软件工程---实践者的研究方法
摘要
本篇博客参考《软件工程:实践者的研究方法》,对其第7、8、14、17、19、20章的内容进行简要总结,以便应付考试。其余章节以后有需要了再进行补充。
一些感想
2026.01.26
读软件工程这本书,这次应该是第四次读了。
第一次是在本科大三的时候,那个时候算是刚学软件工程专业,才开始会写一些代码(水平就是会写点基本算法、写个GUI程序,写点前后端接口和网页),就着一些简单的编程经验和软件工程书中的经验法则开始试图搭建心中的工程框架。上学的时候,这本书应该是最不被同学们重视的,因为大多人认为这是一本"形而上学",脱离流行技术,对实际编程和就业没任何用处的书。不过我当时还是挺喜欢看的,只是当时看着密密麻麻的文字,很多地方也读不懂,前面看得认真些,后面就大致扫一下过去了。至于比较具体的用到,在写本科毕业论文的时候,为了突显一些所谓的工程经验,来提高论文的专业性,我试图使用了一些设计模型和评估方法。站在现在的角度来看,可能当时多画几张图,显得高端一些,现在看来很多地方用的都不对。
第二次看是在大四快毕业,准备考研复试的时候。因为复试科目包含了这科,所以快速地复习了一下,以免面试被问到,一句话也说不出来,从学习的深度和实际掌握的情况来说,相比于第一次读没太大区别。
第三次看,是研一上学期,学校又把此书编制到软件工程专业的硕士生培养计划中。作为需要努力完成毕业条件和为进一步发展作规划的研究生,我当然还是不会认真学这本书了。但是相比于本科好的一些地方,就是在各种表达不同又看似相同的图中,关注到了一些细微的区别。
第四次看,就是今天了。要不是单位考试把这本"没用的书"划进去了,我肯定也不会找出来再看它。这次再读,站在一个对整个计算机行业有着更多认识,有了更多思考能力,以及有了一定实际工作经验的我而言,终于可以说,能基本看懂这本书了,也就是说终于知道这本书在讲什么了。但对具体方法的掌握程度,还是有待提高
1.先简单地总结一下,为什么这本书会这么难读?
①这本书原书就是介绍性书籍,缺乏具体的方法流程和严格逻辑。如需求建模/设计建模时,推荐了使用UML建模法。但问题是,在使用UML建模时,具体应如何对需求/系统进行拆解,拆解建模时,应使用哪些UML模型,建模后应如何通过UML图导出编码时的具体解决方案?从需求建模到设计建模细化的过程中,应细化到什么程度,是否有定量的原则,还是都是经验之谈?不过事实是,涉及到管理的问题总是没有定式,关乎到天时地利人和。
②国内外软件工程专业的环境和背景有很大不同,软件工程专业和领域问题是西方国家在60年前就碰到的东西了,我们开始流行研究该学科是近20-30年前。我国在研究该学科时,软件工程已经从最开始的"小作坊"、"技术牛"编写计算机程序,发展为了具有成熟环境、工具的时代。也就是说,我们在该领域少经历30-40年的探索过程 。软件工程专业恰是西方学者在探索的过程中,提出的,我们没有机会从零开始经历,所以不具备一样的历史和土壤,理解自然就会有偏差 。这是从根上讲的。这里就诞生了一个非常有趣的哲学规律:事物之间的差异,本质上是时间的差异 。发达国家玩剩下的东西,到了优秀的发展中国家手里,带来了后者行业、经济业态、人们生活方式的革新。优秀的发展中国家,又在这个行业近乎饱和后,拿到落后的发展中国家去,又带动落后的发展中国家产业、经济等的变革,同时带动自身外汇的增长。落后的国家从内部看似乎一段时间会迎来一场很大的革新,实际他们的视野有限,没发现是别人给了他们追赶的机会。给我们的启示就是:当你在当前环境中手足无措时,不妨看看先行者的发展历程;当你熟知的领地逐渐被大众知晓时,你可以将它带到一片从未出现过的土地,来赚取溢价。
③翻译、总结这类书的人实际也缺乏工程经验,所以他们很多人实际也没有从本质上想清楚这本书想要干嘛。他们往往会让自己组内的研究生完成翻译和汇编工作,用小付出换取大回报。从读者角度,学校的学生本身就还没写过几行代码,对于这种非常依赖于工作经验的实践书籍,缺乏理解的背景,学习的正反馈很少,加上书上引导的太少,自然就不好理解。这里可以得到的经验是:如果你无法理解标准答案的意思,那你照抄就是了。
2.再简单总结一下,软件工程这本书到底想干嘛?
计算机/软件工程专业作为工科的一级学科,和土木、机械、光学、电子、强电等学科,共同都是工科。但是软件工程专业有其非常特殊的情况:设计者、实施者相同 。这是它与其他工科非常大的一个区别。试想之,土木工程设计者的工作是画施工图纸,具体施工的内容由工人照着图纸进行;机械工程设计者的工作是机械制图,具体的零件生产和装配工作由车间工人照着图纸进行;光学设计师通过仿真软件设计光学系统,具体的生产、加工和装调也是由光学厂工人进行。电气设计师设计弱电或高压电系统,具体的生产调试则由电子厂工人和高压电厂工人执行。设计师输入图纸,产品则可按照图纸生产。
但是软件行业,你会惊奇的发现:设计者、和施工者竟然都是同一个人!那就是程序员。无论是明确需求、系统设计直至编码和部署,都是程序员在做。即便我们有系统架构师这种职务,实际他们只是负责抽象粒度更高的程序员。解决方案和项目经理提出的系统方案,大都也是用于项目包装,没有直接用于编码。软件工程这门学科则是想像传统工科一样,从确定需求和系统设计开始,生成需求/设计模型(类似于传统工科中的设计图纸)然后可以参照图纸,完全一致地生成软件产品 。软件工程的研究者们,则是千方百计地想出各种方法,试图将需求模型到设计模型能直接转换为一致的软件产品(事实证明,这还是不行的) 当然,软件工程还借鉴了传统工科的其他方面,如关注过程,从流程和管理的角度来保证项目/产品的成功。
总结来说:软件工程这门学科是站在宏观的视角,将传统工程的管理方法引入软件行业,从项目经理/负责人的角度来说,如何完成一款软件/信息系统全生命周期的工程级工作。
UML需求建模
-
需求建模定义:用文字、图表等形式描述客户需求,以软件需求规格说明书为实际载体,形成需求(分析)模型(系统的第一个技术表示),为软件设计建立基础(转化为结构、接口、构建级的设计),是系统级表示层(描述整个系统和业务功能)和软件设计之间的桥梁(需求模型的所有元素都可正反向追溯到设计模型),也用于软件开发后的验证与评审(正确性、完整性、一致性,软件的质量保证措施)
-
需求建模的类型(面向过程的结构化方法、面向对象的建模方法)
- 场景模型(用例):系统外部,使用/参与者与系统进行交互的实际场景(用例)
- 面向类的模型:通过类(属性、操作)及其类间协作描述系统需求
- 行为模型:通过系统如何对内部/外部事件进行响应来描述系统需求
- 数据模型:描述问题信息域的模型
- 面向流的模型:通过系统的功能元素及其在系统运行的过程中如何进行数据转换的剖面来描述系统需求
-
需求建模的关注点:做什么而非怎么做
-
需求建模的主要目标:描述客户需要什么;为软件设计奠定基础;定义软件完成后可被确认的一组需求
-
分析模型的经验原则:关注问题或业务域,同时保持较高的抽象水平;分析模型应该提供对软件信息域、功能和行为的描述;将对软件体系结构和非功能性细节的考虑推迟到建模活动后期;考虑软件元素与其他元素间的互连方式(系统耦合);分析模型的结构必须为用户和开发者提供价值,且在描述清晰的情况下尽可能保持简单
-
需求建模原则
- 问题的信息域(流入/流出系统、需存储的数据)必须得到表达和理解
- 必须定义软件执行的功能
- 必须表示软件的行为(作为外部事件的结果)
- 描述信息、功能和行为的模型必须以分层(或分级)的方式进行以揭示细节
- 分析任务应从基本信息转向实现细节
-
UML需求建模的步骤与方法
-
需求层(用户视角):场景建模(用例建模)
- 目的:捕获系统与外部参与者的交互,定义系统边界(做什么)
- 输入:需求分析员与系统参与者的交谈;系统参与者的描述;需求分析员的实际调研
- 中间输出:文本描述的、半结构化的用例描述(以下为用例模板)
shell用例:通过互联网访问摄像机监视设备 迭代:最新修改版本 V1.0.1 李一帆 2026年1月9日 主要参与者:房东 情景目标:从任何远程地点通过互联网查看房间的摄像头输出 前提条件:完整配置系统;获得正确的账户、密码 触发器:房东决定查看房屋内部情况 # 用例发生的时机、事件 场景: 1.房东打开XX应用 2.房东登录账号 3.系统显示所有的功能按钮 4.房东选择"监视"按钮然后选择摄像机 5.系统显示屋内情况 异常处理: 1.未联网 2.账号、密码错误 3.屋内设备缺乏电力供应或损坏... 优先级:中 何时有效:第三个增量 使用频率:高 参与者的连接渠道:基于个人手机APP的XX软件 次要参与者:系统管理员、网络摄像机 次要参与者的连接渠道: 1.系统管理员:基于服务器管理应用及前端界面 2.摄像机:无线互联网连接 未解决的问题:...- 输出:UML用例图

-
静态结构层(架构师视角)
-
类图
-
识别类(根据用例图找出系统中的类)
-
按用例场景中的名词分类:外部实体、系统事物、事件、角色、组织单元、场地、结构
-
Budd分类法:数据产生者(源点)、数据使用者(汇点)、数据管理者、查看观察者、帮助类
-
CRC模型(类-职责-协作者):可看作索引卡的集合
- 组成:类、职责、协作

- CRC模型评估方法:每个评审员拿一分部索引卡(每个评审员不能有两张存在协作关系的CRC卡);评审组长阅读用例,看到已命名类时,让拥有该类的评审员描述类职责,看职责是否满足用例需求;若发现错误,则进行修改
-
-
定义属性和操作
-
导出类图(输出)

-
-
包图
-
组件图
-
部署图
-
-
动态行为层(行为建模:描述系统对于内/外部事件应如何响应,第一个事件是外部用例事件)
-
功能建模
-
活动图(过程视图):在分析阶段,只有在功能相对复杂的情况下才会使用活动图。UML活动图实际是对场景用例在系统内部执行的过程进行细化,类似于流程图(如下图示例,为用户使用摄像机的场景用例)

-
泳道图(指出参与者的过程视图):活动图的拓展,在活动图的基础上指出参与者

-
-
交互时序图
- 顺序图:用时间函数表示从一个类流向另一个类的关键类和事件(横向表示类、纵向表示时间)

- 时序图
- 通信图
-
状态图:用于描述系统状态(系统运行时每个类的状态、系统运行时从外部看到的系统状态)及其状态转换时的事件

-
-
软件设计的概念
-
技术债务:一些开发人员倾向于一旦完成用例就开始编码,忽视软件的设计过程。技术债务(在增量开发中是必然存在的)是指选择"快速而粗糙"的解决方案导致的返工成本(重构和设计可以缓解技术债务)
-
软件设计的概念:软件设计是需求分析和需求建模的后一个建模活动(软件建模的最后一个),将需求模型转化为设计模型,创建了软件的建模表示,可以指导高质量的开发软件,是软件工程中的核心环节(与使用的软件过程模型无关)
-
软件设计的重要性:软件设计是将用户需求准确地转换为最终产品的唯一方法,是质量保证和评估的地方,是所有软件工程活动和软件支持活动的基础
-
软件设计的主要内容
-
输入:基于场景、基于类、基于行为等元素表示的需求模型
-
输出(主要内容)
- 数据/类设计:需求分析中类/静态结构设计的细化,转换成如ER图等表示
- 软件体系结构设计(软件体系结构描述语言ADL):体系结构是软件的整体结构和这种结构为系统提供概念完整性的方式。它定义了软件主要的结构化元素间的关系(构件(模块)的【数据】结构或组织以及构件间的交互方式)、可满足系统需求的体系结构风格,以及影响体系结构实现方式的约束(有人主张将体系结构设计从软件设计中剥离出来)
- 输入:应用域信息、需求模型、可选的体系风格与模式
- 特性
- 结构特性:定义了系统构件(模块、对象、过滤器)、构件封装方法、构件间的作用关系
- 外部功能特性:指出体系结构应如何满足需求(功能、性能、可靠性、安全性、可适应性)
- 模型
- 结构模型:将体系结构表示为构件的有序组合
- 框架模型:通过相似应用中的可复用体系结构设计框架(从相关系统族中抽取相似系统设计中的重复性模式)
- 动态模型:强调体系结构的行为方面,指明结构或系统配置如何随外部事件的变化而变化
- 过程模型:强调系统必须提供的业务或技术流程的设计
- 功能模型:表示系统的功能层次结构
- 接口设计:描述了软件和协作系统之间、软件和使用人员之间是如何通信的,包括UI设计、外部接口、内部接口(与构件设计相关,接口的UML表示)

- 构建级设计:将软件体系结构的结构化元素变换为软件构建的过程性描述(注意构件抽象层次,UML构件图)

- 部署级设计:指明软件和子系统如何在物理计算环境中部署(UML部署图)

-
通用过程
shell# 1.检查信息域模型,为数据对象及其属性设计合适的数据结构 # 2.使用需求分析模型选择一种合适的软件体系结构 # 3.将需求分析模型分割为若干设计子系统,并在体系结构中分配这些子系统 # 3.1.确保每个子系统是功能内聚的 # 3.2.设计子系统接口 # 3.3.为每个子系统分配分析类或功能 # 4.创建一系列的设计类或构件 # 4.1.将分析类转化为设计类 # 4.2.根据设计标准检查每个设计类,考虑继承问题 # 4.3.定义与每个设计类相关的方法和消息 # 4.4.评估设计类或子系统,为这些类或子系统选择设计模式 # 4.5.评审设计类,在需要时进行修改 # 5.设计外部系统或设备所需要的所有接口 # 6.设计用户接口 # 7.进行构建级设计,在相对较低的抽象层次上详细描述所有算法 # 7.1.细化每个构件的接口 # 7.2.定义构建级的数据结构 # 7.3.评审每个构件并修正已发现的错误 # 8.开发部署模型
-
-
软件设计的【演化】过程:反复的、逐步细化的(高抽象层次的软件设计可以直接追溯到需求,细化后较低层次的软件设计仍能追溯到需求但联系可能不明显)
- 指导设计演化过程的三个特征
- 制导设计演化过程的质量指导原则
-
软件设计方法的演化:自顶向下的结构化方式、面向对象的设计方式、软件体系结构的设计模式、面向方面的方法、模型驱动开发、测试驱动开发、基于搜索的软件工程SBSE(运筹学、机器学习)
-
软件设计的质量评估:技术评审TR
-
软件设计的一些原则/要求/经验
- 抽象:过程抽象、数据抽象
- 设计模式:适用于当前工作、可复用的、能够指导相似功能开发的模式
- 关注点分离:将复杂问题分解为若干可管理的块进行求解
- 模块化(关注点分离的最常见表现,设计时需考虑适度)、信息隐藏、功能独立、逐步求精(自定向下、层层分解)
- 重构:检查现有设计的冗余性、未使用的元素、低效不必要的算法等,修改代码,而不改变其外部行为
- 设计类:完整性与充分性、原始性、高内聚、低耦合
-
软件设计模型
- 两个维度:过程维度(表示模型的演化)、抽象维度(表示抽象程度的高低)
- 需求分析模型与设计模型的边界:设计模型也大量使用UML图描述,对于相同内容的描述,设计模型是需求分析模式的细化,提供了更多实施细节,更突出了体系结构、构件、接口

- 软件设计建模的原则:设计应追溯到需求模型;设计过程始终考虑系统的体系结构;数据设计与功能设计同样重要;接口设计必须谨慎;用户界面设计应适用用户的最终需求;构建级设计应在功能上独立;构件彼此松耦合与外部环境松耦合;设计模型应易于理解;设计应迭代式开发;设计模型的创建应不排除使用敏捷方法
软件质量保证
软件质量保证SQA是软件过程中每一步都进行的普适性活动,就是将质量保证的管理规则和设计规范(质量保证的能力是成熟的工程学科尺度)映射到软件工程领域
- 软件质量保证的内容:定义过程;质量保证的任务(技术评审、软件测试,见下文);有效的工程实践(方法和工具);变更控制;测量和报告
- 软件质量保证的要素:标准;评审和审核;测试;错误/缺陷的收集和分析;变更管理;职工培训;供应商管理;安全与安全防卫;风险管理
- 软件质量保证的人员:客户、研发人员、质量保障组
- 软件质量保证的计划:计划的目的和范围;工作产品(模型、文档、代码)的描述;标准和习惯做法;任务及其在软件过程中的位置;工具和方法;软件配置管理;收集和维护SQA记录;为质量相关人员定责
- 软件质量保证的任务:编制项目质量保证计划、参与编写项目的软件过程描述、评审软件工程活动(验证其是否符合规定的软件过程)、审核软件产品(验证其是否符合软件过程规定)、根据文档化的规程记录和处理产品和工作中的偏差,记录不合规项并报告

- 软件质量保证的目标、属性和度量(具体实例参考下图):需求质量、设计质量、代码质量、质量控制有效性(判断质量控制过程本身是否有效)

-
统计软件质量保证(质量的量化):收集错误和缺陷信息并进行分类;追溯每个错误/缺陷形成的根本原因(不合规说明、设计错误、需求理解错误);使用Pareto原则(找出错误的核心原因),纠正错误和缺陷
- 示例统计表

- 六西格玛:基于统计的软件质量保证策略,旨在最小化工程过程中的变化和缺陷原因来提高过程输出的质量,是全面质量管理TOM中的一个子集。包括:定义、测量、分析、改进、控制、设计、验证
-
ISO 9000质量标准:以通用的术语描述了质量保证体系要素,能适用于任何行业
软件配置管理
-
软件配置管理概述
- 概念:软件配置管理SCM,也称变更管理,是一系列管理变更的活动,从属于软件过程
- 软件配置管理计划:定义变更管理的项目策略
- 软件配置管理的工作流:标识变更;变更控制(工程变更工单,访问控制:管理哪个研发人员可对哪个版本进行变更、同步控制:变更可被共享);版本控制;实施变更;配置审核(技术评审、软件配置审核,一种SQA活动);报告变更(CSR状态账目,发生了什么事、谁做的、何时发生...)

- 软件配置项SCI:软件过程中产生的所有信息项,包括计算机程序(源码/可执行程序)、文档、数据。其属性包含自己的信息(ID、名称、版本号、类型...)及与其他SCI的关系

- 软件配置管理的人员:项目经理、配置管理员、研发人员、客户
- 软件配置管理系统的要素:构件元素(SCI管理工具,如文件管理系统)、过程元素(动作任务集合)、构建元素(自动构建工具)、人员元素
- 基线:已通过正式评审和批准的规格说明或产品,它可以作为进一步开发的基础,且只有在正式的变更控制规程中才能修改它,是软件开发的里程碑
-
SCM中心存储库:SCM中心存储库是一组机制和数据结构,具有数据管理系统的一般功能(存储的内容见下图)
- 具备的功能:集成或直接支持过程管理;支持SCI数据的存储、访问和维护;提供其他软件集成的接口;能够存储各种数据对象(图文多媒体)
- 特征:版本控制;依赖跟踪和变更管理;需求跟踪;配置管理;审核跟踪

-
持续集成CI
- 最佳实践:保持小数量的代码变体;尽早并经常测试;尽早并经常集成;使用工具进行自动化测试、构建和代码集成
- 优点:加速反馈、提高质量、降低风险、改进报告
-
依赖和变更影响的管理:组织级(识别团队中可能引起变更或受到变更影响的人员、正向影响管理:评估自身变更对其他成员的影响、反向影响管理:检查团队成员的变更对自身的影响)、个人级(减少自身代码变更对他人的影响,减少他人变更对自身代码的影响)
项目管理的概念
- 项目管理的范围/内容4P
- 人员(最重要):人员能力成熟度模型(People-CMM)
- 产品:确定产品目标和范围(项目环境、信息目标、功能和性能) → 问题分解、选择解决方案
- 过程:选择软件过程模型、合并产品和过程、过程分解(单一冲刺、增量策略)
- 项目
- 关键实践(基于度量的项目管理):成本及进度的估算(测量与度量、估算与进度安排),获得价值跟踪、风险分析、根据质量目标跟踪缺陷、以人为本的管理
制定项目计划
-
概念:软件项目计划是软件项目管理的首要活动
-
目的:提供一个能使管理人员对资源、成本及进度做出合理估算的框架
-
W 5 H H W^5HH W5HH原则:Why?(为何开发)、What?(做什么)、Who?(谁负责)、How?(如何做)、How much?(需要多少资源)
-
主要活动:估算(估算具有与生俱来的风险,需要有定量的勇气):需考虑:项目的复杂性、项目规模、结构的不确定性、历史信息及其有效性;进度安排;风险分析;质量管理计划;变更管理计划
-
项目计划任务集(提供一个最好、最坏情况的范围,随着项目的进展不断调整)
-
1.确定项目范围:描述了交付产品的功能和特性,界定了性能、约束、接口和可靠性,范围可以使用一组用例来定义
-
2.确定可行性:可行性分析
-
3.风险分析
-
4.确定所需资源:资源描述、可用性说明、时间窗口(何时需要、需要用多久)
-
4.1.人力资源:PNR(Putnam-Norden-Rayleigh)曲线:表明投入工作量与交付时间的关系

-
4.2.可复用的软件资源(构件)
-
4.3.识别软件工程环境SEE:软硬件及平台
-
-
5.估算成本和工作量
- 5.1.问题分解
- 5.2.使用规模、功能点、过程任务、用例等两种以上的方法进行估算
- 5.3.调和不同的估算
-
6.制定项目进度计划/项目进度安排:宏观进度表 → 详细进度表(宏观进度表中的每条)
-
6.1.基本原则:项目划分、相互依赖性、时间分配、工作量确认、确定责任、明确输出结果、确定里程碑
-
6.2.建立任务集合:包括工作任务、里程碑、工作产品、质量保证措施(如下例)
- 宏观
shell# 1.1确定概念范围 # 1.2初步概念策划 # 1.3技术风险评估 # 1.4概念证明 # 1.5概念实现 # 1.6客户反应- 细化
shell# 任务定义: # 1.1确定概念范围 # 1.1.1 确定需求、效益和潜在客户 # 1.1.2 确定所希望的输出/控制和驱动应用程序的输入事件 # 1.1.2.1 TR:评审需求的书面描述 # 1.1.2.2 导出客户可见的书面描述 # 1.1.2.3 TR:与客户一起评审输入输出,并在需要时修改 # 1.1.3 为每个主要功能定义功能/行为 # 1.1.3.1 TR:评审在任务1.1.2中得到的输入和输出的数据对象 # 1.1.3.2 导出功能/行为模型 # 1.1.3.3 TR:与客户一起评审功能/行为模型,并在需要时进行修改 # 1.1.4 把需要在软件中实现的技术要素分离开 # 1.1.5 研究现有软件的可用性 # 1.1.6 确定技术可行性 # 1.1.7 对系统规模进行快速估算 # 1.1.8 创建范围定义 -
6.3.定义任务网络(活动网络):用于描述任务之间的依赖关系及关键路径(拓扑图)

-
6.4.使用进度计划工具制定时间表
-
时序图(甘特图)

-
项目表

-
-
6.5.定义进度跟踪机制:定期举行项目状态会议、评估评审结果、判断里程碑是否如期完成、比较项目表中内容的完成情况、与相关人员进行非正式会谈、清除用户故事的待定项、时间盒方法(配合敏捷增量过程,每个任务留±10的时间余量,超期则进行下一任务)
-
-
重复上述步骤,为每个原型定义范围,创建详细的进度安排
-