第 6 章给了我们“写程序”的语言——本章讨论如何把一个大型软件系统当作工程来建造:研究软件工程的目标,就是找到一些原则来指导软件开发过程,进而生产出高效可靠的软件产品。
每节末尾附“本节小结”;每节配 2 道课堂选择题(A/B/C/D),共 16 题,参考答案见页面底部。
| 小节 | 核心问题 | 关键概念 |
|---|---|---|
| 7.1 软件工程科学 | 大型软件的开发为什么需要“工程化”? | 实践派 · 理论派 · 协作与沟通 |
| 7.2 软件生命周期 | 软件从诞生到退役经历哪些阶段? | 开发-使用-维护循环 · 需求分析 · 设计 · 实现 · 测试 |
| 7.3 软件工程方法学 | 用什么过程模型组织开发? | 瀑布模型 · 增量/迭代 · 原型 · 开源 · 敏捷/XP |
| 7.4 模块化 | 如何把大系统拆成易处理的单元? | 耦合 · 内聚 · 信息隐藏 · 组件与接口 |
| 7.5 行业工具 | 分析与设计阶段用什么建模? | 数据流图 · 数据字典 · UML · 设计模式 |
| 7.6 质量保证 | 如何系统地提升软件质量? | 帕累托法则 · 基本路径测试 |
| 7.7 文档 | 软件包为什么少不了文档? | 用户文档 · 系统文档 · 技术文档 |
| 7.8 人机界面 | 界面好坏如何度量? | GOMS:目标/操作/方法/选择规则 |
| 7.9 软件所有权和责任 | 使用软件的法律边界在哪里? | 软件许可 · 知识产权 |
软件工程 software engineering:计算机科学的分支,致力于寻找指导大型复杂软件系统开发的原则——目标是生产出高效可靠的软件产品。
软件工程 = 寻找指导大型复杂软件系统开发的原则;研究在实践派(直接应用技术)与理论派(基础原理)两个层面进行。
大型软件的问题不是小程序问题的简单放大;协作与有效沟通是团队开发成功的关键。
软件生命周期 software life cycle:软件从需求分析、设计、开发、测试、部署到维护和退役的全过程——软件工程最基础的概念。
软件一旦开发完成,就进入“使用—维护”循环,一直持续到软件生命结束。点击圆环上的节点查看各阶段说明。
软件一旦开发完成就进入“使用—维护”循环直至退役;维护由三类原因触发:发现错误、环境变化、修改引发新问题。
传统开发四阶段:需求分析(要做什么,成果是 SRS)→ 设计(建立内部结构)→ 实现(写程序、建数据文件和数据库)→ 测试(对照 SRS 确认产品)。
方法学 methodology:组织软件开发过程的总体策略——不同时代、不同项目适用不同模型。
| 模型 | English | 核心思想 | 形象比喻 |
|---|---|---|---|
| 瀑布模型 | waterfall model | 以严格的顺序进行需求分析、设计、实现和测试 | 像瀑布一样只能向一个方向“流动” |
| 增量模型 | incremental model | 先交付功能有限的简化版本,再以递增方式不断添加功能并测试 | 扩建:把前期版本扩展成更大的版本 |
| 迭代模型 | iterative model | 逐步构建和改进软件系统来实现最终产品 | 打磨:反复改进每个版本 |
| 敏捷方法 | agile method | 增量基础上早期快速实现,响应需求变更,降低对严格需求分析和设计的强调 | 轻装快跑:每天重复小周期 |
点击“推进一步”,同时观察两种开发方式的节奏差异:瀑布一大步一大步单向流动;XP 每天重复“非正式需求分析、设计、实现和测试”的小周期。
原型开发 prototyping:构建并评估预期系统的非完整版本(称为原型)的过程。
瀑布 = 严格顺序;增量 = 扩展前期版本;迭代 = 改进每个版本;敏捷 = 早期快速实现 + 响应变更;原型开发有演化式(原型长成系统)与抛弃式(用完即弃)两种归宿。
开源开发以公开源代码促进社区协作;没有放之四海皆准的模型——选择取决于项目规模、需求稳定性和团队文化。
模块化 modularity:把软件分割成多个易于处理的单元(模块),每个单元仅承担整个软件的一部分职责。命令式范型中模块表现为函数;面向对象范型中以对象作为基本模块要素。
| 概念 | English | 含义 | 设计目标 |
|---|---|---|---|
| 耦合 | coupling | 模块或组件之间的依赖程度。控制耦合:两个模块之间移交执行控制;数据耦合:模块之间的数据共享(如全局数据 global data——可被整个系统所有模块使用的数据项) | 最小化 |
| 内聚 | cohesion | 模块内部各部分的关联程度。逻辑内聚:部分元素实现逻辑上相似的活动;功能内聚:所有部分都聚焦于某一活动的性能 | 最大化 |
点击“切换设计”,观察两种模块布局:左边模块互相纠缠,右边各管各的。数数连线——连线越多,改一处要担心的地方就越多。
好设计的口诀:模块间低耦合(控制耦合/数据耦合),模块内高内聚(功能内聚优于逻辑内聚);全局数据是数据耦合失控的典型。
信息隐藏有两个化身:设计目标(高内聚低耦合)与实现目标(局部变量、封装、明确的控制结构);组件通过接口松散协作。
行业工具是软件开发的分析与设计阶段使用的建模技术和符号系统——先把系统“画”清楚,再动手建造。
老工具:数据流图(箭头/椭圆/矩形)+ 数据字典(数据项的中央信息库);新主流:UML——用例图抓用户需求,类图画类与关联。
设计模式 = 反复出现的设计问题 + 预先开发的解决方案;适配器解决接口不兼容,装饰者支持功能按需组合,好模式服从低耦合高内聚。
软件故障、成本超支、错过截止时间等现象的激增,对软件质量控制的方法提出了要求。
帕累托法则(Pareto Principle,又称二八法则/80-20 法则):很多情况下,约 80% 的结果由 20% 的原因造成。在软件工程中:对一个集中区域施加作用,往往就能明显改变结果。
质量保证的范围早已超出调试:还包括软件工程过程的改进、培训课程的开设以及标准的制定。
帕累托法则指导我们把测试火力集中在错误高发的少数区域;基本路径测试保证每条指令至少执行一次。
文档是最终软件包的一个重要部分——软件文档有 3 种用途,因而可以划分为 3 类。
| 文档类型 | English | 用途 | 读者 / 术语风格 |
|---|---|---|---|
| 用户文档 | user documentation | 解释软件的特性,并描述如何使用软件 | 给软件用户阅读,采用应用方面的术语 |
| 系统文档 | system documentation | 描述软件的内部构成,便于在生命周期内维护软件 | 维护人员;主要部分是系统中所有程序的源代码版本 |
| 技术文档 | technical documentation | 描述软件系统应该如何安装和维护 | 安装/维护人员;台式机领域它与用户文档的界限比较模糊(用户常常也是安装维护者) |
三类文档:用户文档(怎么用)、系统文档(内部怎么构成,源代码是其主体)、技术文档(怎么安装和维护)。
文档不是附属品而是软件包的重要组成部分——没有文档的系统几乎无法维护;写文档的对象是“人”,不同读者需要不同的术语和详略。
系统界面的设计可能会成为判定一个软件工程项目是否成功的最终决定因素。
GOMS 把使用界面的动作分析成基本步骤序列,给每个步骤分配精确的时间段后求和——比较两个界面完成相似任务所需的时间。点击“计算并比较”试试:
GOMS(Goal/Operator/Method/Selection rule)把界面操作拆成基本步骤并计时求和,从而在纸面上比较不同界面设计。
软件许可是法律协议:授予使用权而不转移知识产权;安装使用软件前应仔细阅读许可条款。
先独立完成上面的练习,再来这里核对——错题对应的小节值得回看一遍。
| 小节 | 题号 | 答案 | 一句话解析 |
|---|---|---|---|
| 7.1 | Q1 | B | 软件工程 = 找到指导开发的原则,生产高效可靠的软件。 |
| 7.1 | Q2 | C | 实践派做直接技术、理论派探基础原理,两方面需求都巨大。 |
| 7.2 | Q3 | B | 开发完成后进入“使用—维护”循环直至退役。 |
| 7.2 | Q4 | B | 需求分析 → 设计 → 实现 → 测试,顺序不能乱。 |
| 7.3 | Q5 | C | 瀑布模型严格顺序、单向流动,像瀑布一样。 |
| 7.3 | Q6 | B | 原型长成最终系统 = 演化式;用完丢弃 = 抛弃式。 |
| 7.4 | Q7 | B | 模块间依赖程度叫耦合;内部关联程度叫内聚。 |
| 7.4 | Q8 | B | 好设计追求低耦合、高内聚,少用全局数据。 |
| 7.5 | Q9 | C | 参与者 actor 用火柴人,用例用椭圆,系统用大矩形。 |
| 7.5 | Q10 | B | 适配器模式解决预制模块的接口不兼容问题。 |
| 7.6 | Q11 | B | 帕累托法则:作用于集中区域即可明显改变结果。 |
| 7.6 | Q12 | C | 基本路径测试保证每条指令至少被执行一次。 |
| 7.7 | Q13 | B | 系统文档描述内部构成,源代码是其主要部分。 |
| 7.7 | Q14 | B | 用户文档给用户看,采用应用方面的术语。 |
| 7.8 | Q15 | C | GOMS = 目标、操作、方法、选择规则。 |
| 7.9 | Q16 | A | 许可授予使用权,知识产权仍归所有者。 |
软件开发是一个工程化的过程:找到原则来指导开发,进而生产出高效可靠的软件产品。
| 小节 | 一句话总结 | 关键术语 |
|---|---|---|
| 7.1 软件工程科学 | 实践派做技术、理论派探原理;协作与沟通是关键 | practitioner · theorist |
| 7.2 软件生命周期 | 开发 → 使用 ⇄ 维护;需求分析/设计/实现/测试 | life cycle · SRS · stakeholder |
| 7.3 方法学 | 瀑布严格顺序;增量扩展、迭代改进;敏捷响应变化 | waterfall · agile · prototyping |
| 7.4 模块化 | 低耦合 + 高内聚 + 信息隐藏;组件通过接口协作 | coupling · cohesion · interface |
| 7.5 行业工具 | 数据流图/数据字典 → UML;设计模式复用好方案 | UML · design pattern |
| 7.6 质量保证 | 超出调试的范围;帕累托法则聚焦 20% 高发区 | Pareto · basis path testing |
| 7.7 文档 | 用户/系统/技术三类文档,各有读者与术语 | user/system/technical docs |
| 7.8 人机界面 | GOMS 把界面操作拆成步骤并计时比较 | GOMS |
| 7.9 所有权和责任 | 软件许可授予使用权,不转移知识产权 | software license |
重点名词双语对照 + 一句话释义;建议结课时自查一遍。