第5章软件工程在20世纪60年代以前软件规模小开发就像个人手工作坊一个人写代码、自己用没什么文档。但到了60年代中期计算机性能大幅提升软件规模急剧膨胀复杂度越来越高问题也随之而来开发进度难以预测、成本失控、功能不能满足用户需求、质量低劣、难以维护、缺少文档……这就是著名的“软件危机”。为了解决软件危机人们提出了“软件工程”的概念希望用工程化的方法来开发软件。5.1 软件工程定义软件工程就是用工程化的原则和方法来开发软件目的是提高软件的生产率、质量和降低成本。IEEE对软件工程的定义是将系统的、规范的、可度量的工程化方法应用于软件开发、运行和维护的全过程及方法的研究。软件工程由三部分组成方法完成软件项目的技术手段支持整个软件生命周期。工具自动或半自动支持软件开发和管理比如各种IDE、项目管理工具。过程贯穿软件开发各个环节的一系列活动管理人员通过过程来控制质量、进度和成本。形象地说软件工程就像建造一座大楼方法就是建筑技术工具就是起重机、搅拌机过程就是施工流程和管理。5.2 软件需求软件需求就是用户对系统在功能、行为、性能等方面的期望。IEEE定义需求是用户解决问题或达到目标所需的条件或能力也是系统必须满足的合同、标准、规范的要求。5.2.1 需求的层次需求分为三个层次从宏观到微观业务需求组织或客户的高层次目标比如“我们要提高客户满意度”、“我们要实现无纸化办公”。通常来自投资人、高层管理人员决定了项目的愿景和范围。用户需求用户的具体目标用户能用系统做什么比如“用户可以在线提交请假申请”。通过访谈、问卷等方式获取。系统需求从系统角度说明的需求包括功能需求系统必须实现的功能比如“系统能计算员工工资”。非功能需求系统的属性或品质如性能、安全性、易用性等。约束设计和实现上的限制比如必须用Java开发、运行在Linux上。形象地说业务需求就像“我要建一栋别墅”用户需求是“要有卧室、厨房、卫生间”系统需求是“卧室要20平米用环保材料电路要暗埋”。5.2.2 质量功能部署QFDQFD是一种将用户要求转化为软件需求的技术把需求分为三类常规需求用户认为系统应该有的功能做得越多用户越满意。比如手机要有打电话功能。期望需求用户想当然认为系统应该有的如果没有就会不满意。比如手机应该能上网用户可能不会明说但如果没有就会觉得差劲。意外需求兴奋需求用户没提但开发者加上的功能有了会让用户惊喜没有也不影响购买。比如手机的人脸识别解锁。QFD帮助开发者在成本和满意度之间做权衡。5.2.3 需求获取需求获取就是与用户沟通确定系统必须满足的需求。常用的方法有用户访谈、问卷调查、采样、情节串联板、联合需求计划等。难点在于用户往往说不清楚自己到底要什么或者需求会变化。所以需求获取不是一次性的需要反复沟通、确认。5.2.4 需求分析需求分析是把获取到的杂乱需求整理成清晰、一致、可验证的用户需求。一个好的需求应该具备无二义性、完整性、一致性、可测试性、确定性、可跟踪性、正确性、必要性。1. 结构化分析SA结构化分析是一种面向数据流的需求分析方法核心是数据字典围绕它有三个模型数据模型用**实体关系图E-R图**描述实体、属性和关系。功能模型用**数据流图DFD**描述数据流动和处理过程。行为模型用**状态转换图STD**描述系统状态和事件。**数据流图DFD**由四种元素组成数据流箭头数据的流向。处理矩形对数据的加工。数据存储开口矩形数据存放的地方。外部项圆角框数据源或终点。DFD的建模步骤确定系统范围 → 画顶层图 → 逐层分解 → 检查确认。数据字典是对DFD中所有元素的详细说明包括数据项、数据结构、数据流、数据存储、处理过程。它就像一本“数据百科全书”供分析员和用户查询。2. 面向对象分析OOAOOA是从对象的角度分析问题域识别类和对象定义它们的属性和方法以及之间的关系。OOA模型由五个层次主题层、对象类层、结构层、属性层、服务层和五个活动标识对象类、标识结构、定义主题、定义属性、定义服务组成。OOA的基本原则抽象抽取共同本质特征忽略非本质细节。封装将属性和方法打包隐藏内部细节。继承子类自动拥有父类的属性和方法。分类把相同属性和方法的对象归为一类。聚合整体与部分的关系。关联对象之间的联系。消息通信对象之间只能通过消息交互。粒度控制在宏观和微观之间切换视野。行为分析分析对象的动态行为。OOA基本步骤确定对象和类。确定结构泛化-特化、整体-部分。确定主题。确定属性。确定方法。5.2.5 需求规格说明书SRSSRS是需求分析的最终成果是项目干系人和开发团队对系统初始规定的共同理解也是后续开发的基础。国家标准GB/T 8567提供了SRS模板主要包括范围系统标识、用途、背景、文档概述等。引用文件相关文档列表。需求详细描述功能、性能、接口、环境、质量等。合格性规定如何验证每个需求演示、测试、分析等。需求可追踪性双向追踪。尚未解决的问题遗留问题说明。注解术语、词汇。附录补充信息。SRS需要经过验证评审和测试确保正确、完整、一致。5.2.6 需求变更需求变更是软件开发中的常态但不能失控。变更控制过程包括问题分析和变更描述分析变更提议的有效性。变更分析和成本计算评估影响和成本决定是否执行。变更实现执行变更并更新相关文档和代码。**变更控制委员会CCB**由多方代表组成负责裁决是否接受变更。CCB不是作业机构只做决策。变更策略所有变更必须遵循过程未批准的不做CCB决定变更内容要可跟踪。5.2.7 需求跟踪需求跟踪是建立需求与后续工作成果设计、代码、测试等之间的联系确保所有需求都被实现且所有成果都有需求依据。分为正向跟踪从需求出发找对应的设计、代码、测试。逆向跟踪从设计、代码、测试出发找对应的需求。常用工具是需求跟踪矩阵记录需求与各阶段产出的对应关系。5.3 软件设计软件设计是把需求转化为软件蓝图的过程解决“怎么做”的问题。分为结构化设计和面向对象设计。5.3.1 结构化设计SDSD是一种面向数据流的设计方法以DFD和数据字典为基础自顶向下、逐步求精。分为两个阶段概要设计确定软件结构划分模块定义模块功能和接口画出模块结构图SC。详细设计为每个模块设计具体算法、数据结构、界面等用流程图、PAD图、伪码等工具。模块化设计的关键概念信息隐藏模块内部细节对外隐藏只暴露接口。模块化模块具有功能、逻辑、状态三个属性。耦合模块之间联系的紧密程度。耦合度从低到高非直接耦合、数据耦合、标记耦合、控制耦合、通信耦合、公共耦合、内容耦合。设计要追求低耦合。内聚模块内部各成分联系的紧密程度。内聚度从高到低功能内聚、顺序内聚、通信内聚、过程内聚、时间内聚、逻辑内聚、偶然内聚。设计要追求高内聚。系统结构图SC反映模块之间的层次结构和调用关系。详细设计的工具图形工具业务流程图、程序流程图、PAD图、NS图。表格工具决策表。语言工具伪码、PDL。5.3.2 面向对象设计OODOOD是OOA的延续主要任务是对类和对象进行设计包括属性、方法以及类之间的关系。OOD的原则单一职责原则一个类只有一个引起它变化的原因。开闭原则对扩展开放对修改封闭。里氏替换原则子类可以替换父类。依赖倒置原则依赖抽象不依赖具体实现。接口隔离原则使用多个专门接口而不是一个总接口。组合重用原则尽量用组合代替继承。迪米特原则一个对象应尽可能少地了解其他对象。在OOD中类分为三种类型实体类对应业务实体需要持久化存储如“学生”、“课程”。通常有属性不一定有操作。控制类负责用例的控制行为如“身份验证器”。通常有方法不一定有属性。边界类位于系统与外界交互的边界如窗口、接口、报表。可以有属性和方法。5.3.3 统一建模语言UMLUML是一种用于软件系统建模的通用语言支持从需求分析到设计实现的全过程。UML的结构包括构造块事物结构事物、行为事物、分组事物、注释事物、关系依赖、关联、泛化、实现、图。规则命名、范围、可见性、完整性、执行等。公共机制规格说明、修饰、公共分类、扩展机制。UML 2.0中的14种图类图、对象图、构件图、组合结构图、用例图、顺序图、通信图、定时图、状态图、活动图、部署图、制品图、包图、交互概览图。UML的五种视图逻辑视图系统的静态结构和动态行为。进程视图并发与同步。实现视图代码文件和构件。部署视图物理节点上的部署。用例视图从用户角度展示功能。5.3.4 设计模式设计模式是前人经验的总结是可复用的解决方案。根据目的分为三类创建型模式如何创建对象如单例、工厂、建造者。结构型模式如何组合类或对象如适配器、代理、装饰。行为型模式如何交互和分配职责如观察者、策略、模板方法。5.4 软件实现5.4.1 软件配置管理SCMSCM是标识、组织和控制修改的技术目标是标识变更、控制变更、确保变更正确实现并向相关人员报告。核心内容版本控制记录文件变更历史支持并行开发分支与合并。变更控制管理变更过程确保有序。SCM活动包括计划、标识、控制、状态记录、审计、发布管理。5.4.2 软件编码编码是把设计翻译成计算机能理解的程序。需要注意程序设计语言选择根据项目需求选择合适语言。程序设计风格源程序文档化、数据说明规范、语句结构清晰、输入/输出友好。程序复杂性度量定量评估复杂度用于估算工作量和缺陷。编码效率包括程序效率、算法效率、存储效率、I/O效率。5.4.3 软件测试测试是为了发现错误而执行程序的过程目的是确保软件质量。测试方法静态测试不运行程序通过检查文档和代码发现错误如桌前检查、代码走查、代码审查。能发现30%~70%的逻辑错误。动态测试运行程序比较实际结果与预期结果。包括白盒测试结构测试透明测试关注内部逻辑设计测试用例覆盖语句、分支、路径等。黑盒测试功能测试不透明测试关注功能是否满足需求常用等价类划分、边界值分析、因果图等。测试类型GB/T 15532单元测试测试单个模块。集成测试测试模块组合后的接口和交互。确认测试验证软件是否满足用户需求。系统测试在真实环境下测试整个系统包括功能、性能、安全等。配置项测试测试软件配置项是否符合SRS。回归测试修改后测试确保原有功能不受影响。面向对象的测试由于封装、继承、多态测试策略不同测试焦点从模块移到类测试范围扩大到分析和设计模型。软件调试发现错误后定位并改正错误常用蛮力法、回溯法、原因排除法。5.5 部署交付5.5.1 软件部署软件部署是将软件安装到用户环境并使其运行的过程包括打包、安装、配置、测试、集成、更新等。部署有风险因为软件越来越复杂、环境不确定、构件来源多样。部署模式有面向单机软件的部署简单安装卸载。集中式服务器应用部署适用于小规模用户。基于微服务的分布式部署适用于高并发、云原生应用常结合容器和DevOps。5.5.2 软件交付传统软件交付流程业务产生想法 → 开发实现 → 测试 → 运维。存在问题沟通效率低、自动化测试不足、手工运维质量难保证。导致进度不可控、环境不稳定、协作不畅。5.5.3 持续交付持续交付是一系列开发实践确保代码能快速、安全地部署到生产环境。它通过自动化流程实现一键部署。优势缩短部署时间降低风险。快速反馈及时发现缺陷。软件始终处于可靠状态。简化部署版本清晰。交付过程可靠、可预期、可视化。5.5.4 持续部署持续部署是持续交付的重要环节常用容器技术如KubernetesDocker实现。部署原则部署包来自统一存储库。所有环境使用相同部署方式和脚本。部署流程阶梯式晋级可回滚。由运维人员执行仅通过流水线改变生产环境。不可变服务器服务器一旦部署就不修改需要更新就替换新版本。部署方式蓝绿部署新旧版本并行通过域名切换和金丝雀部署先让少量用户试用新版本。部署层次Build编译打包→ Ship安装依赖→ Run启动环境。5.5.5 部署和交付的新趋势职责转变开发人员参与交付和部署运维人员自动化脚本。云计算普及环境可自动化创建和回收部署更灵活。研发运维融合DevOps文化打破壁垒。5.6 软件质量管理软件质量是软件与明确和隐含需求的一致程度。从用户角度质量因素分为三组产品运行正确性、健壮性、效率、完整性、可用性、风险。产品修改可理解性、可维修性、灵活性、可测试性。产品转移可移植性、可再用性、互运行性。软件质量保证SQA通过有计划、系统的方法向管理层保证标准和过程被遵循。目标是预防缺陷尽早捕获错误作用于过程贯穿所有活动。SQA的主要任务审计与评审审查工作产品、工具、设备是否符合标准确保过程被遵循。报告记录结果发布给相关人员。处理不合格问题发现问题及时处理和反馈。5.7 软件过程能力成熟度软件过程能力是组织基于过程、技术、资源和人员达成业务目标的综合能力。中国电子工业标准化技术协会发布了CSMM软件过程能力成熟度模型。5.7.1 成熟度模型CSMM模型由4个能力域、20个能力子域、161个能力要求组成治理战略与治理、目标管理。开发与交付需求、设计、开发、测试、部署、服务、开源应用。管理与支持项目策划、监控、结项、质量保证、风险管理、配置管理、供应商管理。组织管理过程管理、人员能力管理、组织资源管理、过程能力管理。5.7.2 成熟度等级CSMM定义了5个等级从低到高1级初始级结果特征软件过程和结果具有不确定性。行为特征能初步交付但依赖个人能力无完整管理规范。2级项目规范级结果特征项目基本可按计划实现预期结果。行为特征项目有选择地遵循管理规范组织提供基础支持。3级组织改进级结果特征在组织范围内稳定实现预期项目目标。行为特征建立并持续改进组织标准过程和资产项目根据自身特征应用并贡献资产。4级量化提升级结果特征量化管理和实现组织和项目目标。行为特征使用统计分析技术建立量化的质量与过程绩效目标分析数据、预测结果。5级创新引领级结果特征通过创新实现业务目标持续提升引领行业发展。行为特征优化革新创新提升竞争力推广自身经验为行业最佳实践。各能力域在不同等级有对应的要求等级越高要求越全面。