先说两句

毫不夸张的说,这个章节真的是重中之重,你把这个章节学明白了,基本上其它章节都明白了。我必须要给你解释一下,这个章节的核心东西。一定要理解这里面的逻辑关系,后面所有的内容都要以这个为基础的。

开始学习整体架构

打开网易新闻 查看精彩图片

软件过程模型

软件过程模型(Software Process Model)是软件开发过程中为有效管理项目、控制质量、满足需求而设计的结构化框架,它描述了软件开发从需求分析到交付维护的各个阶段、活动、任务及它们之间的逻辑关系。

瀑布模型

打开网易新闻 查看精彩图片

学习重点

前面一个阶段的产出物作为下一个阶段的输入

需求分析完成之后会产生软件需求分析说明书(SRS),SRS作为软件设计的依据

用瀑布模型做项目的失败率会非常高,因为瀑布模型只适合需求明确的模型,但是大多数项目的需求不是很明确的,需求不明确带来的问题就是,随着瀑布模型的不断往下发展,问题会逐渐放大,最后导致很多工作无用功了。

原型模型

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

快速构建系统原型,通过用户反馈迭代优化,最终开发正式系统。在开发原型系统之前不需要进行实际的编码,可以反复迭代原型系统,最终达到需求明确的目的。

它有两个阶段:

原型开发阶段:用于开发原型系统

目标软件开发阶段:当原型系统确定之后,就可以往下走了,最终走到运行维护阶段

原型分为:抛弃型原型和演化型原型

抛弃型原型:快速验证需求或设计的可行性,验证后即被丢弃,不作为最终产品的一部分。其核心价值在于“低成本试错”,通过快速构建原型降低需求误解或技术方案错误的风险。

演化型原型:原型逐步完善,最终演化为最终系统。其核心价值在于“持续交付价值”,通过迭代满足用户需求变化,同时保持代码可维护性。(当采用演化型原型(Evolutionary Prototype)时,原型本身是可运行的代码

原型系统可以和其它系统有关联

快速原型模型其实就是抛弃型模型

增量模型:将一个大系统先做核心的模块,然后不断做与核心模块相关的,不断增加,最终完成整个系统

V模型

打开网易新闻 查看精彩图片

学习重点

与瀑布模型相比,V模型的测试会提前,比如瀑布模型会等编码完成之后才会测试

但是V模型会在需求分析阶段就产生验收测试,也就是根据需求来输出验收测试方法

系统测试强调软件、硬件环境联合测试,也是在需求分析阶段产生

概要设计阶段就会产生集成测试,概要设计就是将系统拆分为子模块,设计接口,集成测试就是验证这些模块之间的接口能不能有效的协同

详细设计就对应了单元测试,详细设计就是设计单个模型走什么算法,什么逻辑,完成什么样的工作,单元测试就是为了测试每个小模块的功能和边界值性能等东西

W模型

打开网易新闻 查看精彩图片

学习重点

W模型是V模型的调整和改进,W模型由两个V构成,一个V是开发过程,另外一个V是测试过程,它的特点是开发和测试并行,可以让开发和测试独立走每个生命周期

打开网易新闻 查看精彩图片

可以看到最下面被打勾的合并起来就是V模型了。

迭代与增量

打开网易新闻 查看精彩图片

学习重点

增量:一点一点的在增加,比如一开始有一条鱼,后面有鱼和手

迭代:一点一点的在变好,比如一开始就画好了鱼和手的大概位置,后面有轮廓,最后成型

螺旋模型

打开网易新闻 查看精彩图片

学习重点

螺旋模型可以用于开发一些大型的软件,它的核心是快速原型+瀑布模型,它是从快速原型模型开始,经过瀑布模型的,产生下一轮的原型系统2,不断的迭代

构建组件模型

打开网易新闻 查看精彩图片

基于构件的软件工程(CBSE)

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

组件模型(Component Model)是一种软件设计方法,其核心思想是将复杂系统拆解为独立、可复用的组件,通过标准化接口进行组合,实现系统的模块化、可扩展性和高效开发。

设计构建组装:类似于一个整体的概念

构建构建库:是一个局部的概念,是一个费力的过程,需要标准化,但是一旦构建完成之后,后面就轻松了

构建应用软件:通过局部组成成整体

构建标准了解一下

基于构建组件模型就会产生想应的方法论,由此产生了基于构建的软件工程方法,在这个方法中要想成为构建的特征(独立,可独立部署、标准号、文档化、可组装)

构建模型要素:当使用构建的额方式来完成软件开发的时候,形成的构建模型,需要约束几个维度的东西,只有这几个维度存在的时候,才可以,我理解就是使用说明书,需要把这几个内容说清楚,才可以知道构建模型的内容是什么。

构建的组装:构建和构建之间是可以组装起来,形成更加强大的功能,组件和组件的组装方式有三种,上图中红色的地方,可以理解为调用方,顺序组装,就是调用方先调用构建1、在调用构建2。层次组装,是调用方调用构建1,构建1调用构建2。迭代是多个构建组装起来了,然后组成一个新的构建,提供一个新的接口给外面使用

组装会存在不兼容的问题

参数不兼容:参数类型和数量不兼容

操作不兼容:功能可能兼容,但是名字不兼容

操作不完备:一个构建无法给另外一个构建提供全部的功能

快速应用开发模型

打开网易新闻 查看精彩图片

学习重点

快速应用开发模型的是瀑布+基于构建的组合,所以主流程用瀑布,然后引入构建不需要重复开发的方式,对整个开发过程进行提速

统一过程

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

用例驱动就是用例来驱动整个过程,用例是在需求阶段对需求里面功能块描述的一种机制

以架构为中心:因为统一过程适合大项目

迭代和增量:初始(偏需求)>细化(核心,确定架构)->构造(开发未实现功能,并测试)->移交(交付,用户参与的β测试)

统一过程还可以通过核心工作流进行切分。也就是从要做的事情进行切分,有些工作流在不同的阶段可能都要执行,比如业务建模在初始化、细化、构造、移交等四个阶段都要做,只不过大头在初始和细化中。9个工作流分为两部分,一部分是过程,一部分是支持。过程类似于开发做的事情,支持类似于管理做的事情。

原型不强调阶段,强调的是原型

瀑布模型是区分阶段,但是强调的是需求分析、软件设计等等

螺旋模型是区分阶段,区分目标、风险、开发验证、评审

V模型测试贯穿始终,强调测试的模型

敏捷方法

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

敏捷方法(SCRUM)

打开网易新闻 查看精彩图片

所有敏捷方法:

打开网易新闻 查看精彩图片

学习重点

适应性:整个过程都在不断的调整变化

以人为本:考虑每个人的差异

小步快跑:小范围迭代

小型项目:大项目会失控

有点上上来就干的感觉,别整太多文档啊,这种东西

敏捷方法有多种实践,这里介绍了XP,沟通就是面对面的沟通,尽量不搞文档

12条过程实践:就是XP方法的最佳实践

敏捷方法(SCRUM)也就是敏捷开发方法的一种,从所有要开发的任务中抽取一部分来完成,作为一个迭代的任务。比如一开始有10个任务,没必要一开始做10个任务,可以先做两个任务,然后通过1个月的实践来迭代完成这两个任务,完成之后在完成后面的任务,这样的好处在于假设10个任务要一年完成,那么我可以在一年结束的时候发现可能2个任务没有完成,8个任务已经完成了。如果10个任务一起搞,可能最后会发现10个任务都没有完成。

除了以上两个敏捷方法之外,还要了解一下如图所示的其它的敏捷方法

敏捷开发以原型开发思想为基础,采用迭代式增量开发方法

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

逆向工程

打开网易新闻 查看精彩图片

一些概念

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

逆向工程中的再工程分为逆向工程->考虑新需求->正向工程

逆向工程就是把设计还原的过程,再还原过程中可以分为多个等级,包含实现级(代码层面,通过代码反推功能)、结构级、功能级(完整功能)、领域级(ER图),每个等级需要了解

要知道这些概念,这样才可以通过概念来确定是再描述哪一个

净室软件工程

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

把软件开发放置再一个尽量单纯,不被影响的环境下开发。‘对于一些百分百成熟的地方,让机器生成,可以保证准确性

需求工程需求工程阶段划分

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

软件需求是用户对系统的期望

需求工程的主要活动阶段要了解

需求开发包含:需求获取->需求分析->形成需求规则->需求确认与验证 不能转化为应用系统成果,要想转变为成果,需要编码实现

需求获取

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

需求分析

需求分析分为两条线,一个是结构化需求分析,一个是面向对象的需求分析。

结构化需求分析

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

结构化需求分析阶段主要是建立三种模型:

一种是功能模型

一种是行为模型

一种是数据模型

打开网易新闻 查看精彩图片

功能模型主要产生数据流图。数据流图主要可以看到哪些角色再用它,哪些角色传递了数据给系统,哪些角色从系统获取到了数据。数据流图也是分层的,比如上面的培训部、辅导老师是数据流图的顶层。下面是数据流图的底层。从上层可以看到很全局的东西,角色和系统的交互。至于系统内部的交互我们是看不到的

四大构成要素:

数据流+加工+数据存储+外部实体

注册请求这就是数据流

加工就是函数

数据存储就是数据表数据库之类的东西

外部实体,比如学员并不在系统之内,但是还要和系统进行交互,这就是外部实体

行为模型是:一种状态经过某个行为后变为另外一种状态

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

数据模型就是E-R图,E是实体,R是联系

学员注册到系统,那么学员究竟发送了什么数据给到了系统呢?比如姓名、年龄等等,这个可以在中间的数据字典中进行定义

面向对象的需求分析(OOA)

打开网易新闻 查看精彩图片

UML图

打开网易新闻 查看精彩图片

用例图

打开网易新闻 查看精彩图片

新增书籍,查询书籍都是用例

打开网易新闻 查看精彩图片

如何创建用例模型呢?通过以上四步

时间比如定时执行。还可以是温度或者湿度等等

获取达到参与者之后就可以从参与者的角度来确定需求

第三步细化用例描述

打开网易新闻 查看精彩图片

要把用例的详细情况描述出来

第四步核心是优化用例模型

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

包含关系其实就是复用,比如学习课程需要验证学员有没有权限,课程测试需要验证学员有没有权限,那么就可以把检查权限功能抽取出来,让学习课程和课程测试都调用检查权限。必须调用才可以

比如课程测试过程中可能会产生额度不够的情况,此时就需要充入学习币这个用例。可选调用

泛化就是继承,向上抽取的过程

打开网易新闻 查看精彩图片

generalize就是泛化关系,当一个用例可以出现在另一个用例的任何一个位置的时候,就说明UC1可以被子类所替代,这是标准的字符类之间的关系。

类图与对象图

分析模型

打开网易新闻 查看精彩图片

书籍中只有属性

书籍列表中只有方法

要知道方法和属性的区别

以上是类图,对象图基本和它类似

多重度就是两个实体之间的联系,这个联系可以是1:1,可以是1:n,也可以是n:n,比如书籍这里是1,借阅记录为0..1,表示一本书有0或者1条借阅记录

打开网易新闻 查看精彩图片

关系是核心

打开网易新闻 查看精彩图片

这些图的箭头怎么画的不用关心,实际考试过程中也会存在画图不标准的情况

依赖关系:A调用了B方法,那么A依赖B

关联关系:了两个对象之间有关联,但是不是整体和部分的关系,那么就是关联关系

关联关系分为聚合关系和组合关系两种。聚合关系比如电脑整体和键盘,电脑坏了,键盘可能没有坏。组合关系类似于公司和部门,公司倒闭了,部门也就不存在了

实现:就是接口和类之间的关系

泛化:其实就是继承,特殊和一般关系,一般是指公共方法,特殊是子类中特殊的方法

类间关系的语义强度:从依赖关系逐渐增加到泛化

打开网易新闻 查看精彩图片

交互图

打开网易新闻 查看精彩图片

类名前面写:就是对象

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

通信图(协作图)

打开网易新闻 查看精彩图片

状态图

打开网易新闻 查看精彩图片

On是开关的开状态,Off是开关的关状态,当开关是关状态的时候,如果这个时候点击开关 TurnOn就是事件,【没水】就是条件,没有水,还是会回归到开关的off状态

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

活动图

打开网易新闻 查看精彩图片

这个有点像流程图,流程图是用在结构化里面的,二活动图是用在面向对象里面的

黑色的横线是并行的意思

打开网易新闻 查看精彩图片

泳道式活动图,分为客户泳道、系统泳道、供应商泳道

定时图

打开网易新闻 查看精彩图片

比如浸泡是0到10分钟

洗涤是10到30分钟

脱水是30到35分钟

构件图与包图

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

部署图

打开网易新闻 查看精彩图片

学习重点

UML与语言无关,UML主要由构造块、规则(UML运行的基本原则)、公共机制(所有的元素达成的共识)

打开网易新闻 查看精彩图片

主要把这几种图搞定,知道每个图的侧重点是什么,然后再填图的时候能够填上

系统工程建模

打开网易新闻 查看精彩图片

系统建模语言是再统一建模语言的基础上发展来的

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

需求图中的各种关系

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

学习重点

系统工程比软件工程的敢为要更大的,它的三大支柱就是建模语言、建模思路、建模工具。如果不好理解是再什么,可以和软件工程中的UML、面向对象开发、Visio来对标

可以看到系统建模语言是在通一建模语言基础上产生的,所以系统建模语言的很多图都和统一建模语言的图类似,其中需求图是新增加的

需求是有关系的,其中包含是比较特殊的,是需求可以且只能包含其它需求。

跟踪类似于依赖

继承就是父子关系

改善就是对需求进行了细化

满足,比如一个排序功能,可以排序前10个数字,那么一个模块可以满足这个要求,那么就是满足

验证:用一个测试用例来验证需求,测试用例的也是需求

需求开发需求定义(形成需求规格)

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

需求确认与验证

打开网易新闻 查看精彩图片

需求已经分析了,已经输出需求文档了。此时就需要需求评审

需求测试就是根据需求设计一些假设性场景,验证需求是否可以跑通

需求跟踪

打开网易新闻 查看精彩图片

比如说了5条需求,最后验收发现只有四条,或者说有的需求说的是A,但是实际上做的确实B,这也让人头疼,此时就需要跟踪需求,保证需求不丢失,不跑偏

需求变更管理过程

打开网易新闻 查看精彩图片

需求总是不断发生变化的,需求不能随便随便拒绝,也不能随便答应,应该要有一种评估方法

打开网易新闻 查看精彩图片

软件系统建模

打开网易新闻 查看精彩图片

物理系统到物理模型其实就是一个逆向的过程

例题

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

系统设计人机界面设计(黄金三法则)

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

结构化设计

打开网易新闻 查看精彩图片

在结构化设计的时代是没有架构设计的,而概要设计就有一部分是架构设计的思想的

结构化设计分为概要设计和详细设计

结构化设计是有原则的,要遵守这些原则,就不容易出问题

多扇入少扇出,扇入多说明服用高,好。

扇出多说明模块依赖的模块多,不好

深度和宽度过高不是一件好事,宽度高,说明依赖多,深度高,说明层级深

打开网易新闻 查看精彩图片

结构化设计(内聚)

打开网易新闻 查看精彩图片

结构化设计(耦合)

打开网易新闻 查看精彩图片

结构化设计(模块四要素)

打开网易新闻 查看精彩图片

结构化设计中模块是一个基本的元素,那么如何定义一个模块呢?就是通过四要素来完成的

面向对象设计基本过程

打开网易新闻 查看精彩图片

面向对象设计(类的分类)

打开网易新闻 查看精彩图片

实体类往往和数据库表一一对应

边界类是对外的,可以被用户感知到的

控制类:获取实体类信息,进行一系列的演算,然后将结果返回给边界类,类似于service层

面向对象设计原则

打开网易新闻 查看精彩图片

软件测试软件测试类型

打开网易新闻 查看精彩图片

根据代码是否运行,可以确认是动态测试还是静态测试

白盒测试与黑盒测试

打开网易新闻 查看精彩图片

一段程序,如果语句覆盖,可能只能覆盖所有情况的50%,如果是路径覆盖就可以覆盖所有情况的100%

有效等价类就是在规定内的,比如范围1~10.则5

无效等价类就是不在规定内的,比如范围1~10,则16

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

软件测试阶段

打开网易新闻 查看精彩图片
打开网易新闻 查看精彩图片

单元测试也有打桩的概念

集成测试也仅仅是软件方面的测试

系统测试:是软硬结合,包含正式环境的测试

打开网易新闻 查看精彩图片

链接测试中的孤立的页面的意思就是没有一个链接可以链接到这个页面

集成测试策略

打开网易新闻 查看精彩图片

一次性组装:一次性将所有模块组装起来,效率高,但是可能遗漏,会出问题

增量组装:假设有10个模块,那么先1模块和2模块组装起来,先测试,然后再加上3再测试,这样会比较全面,但是会比较慢。

驱动模块:调用被测模块

桩模块:被测模块依赖的模块

系统测试策略

实际运行起来的程序,分为:功能测试、性能测试、健壮性测试、用户界面测试、安全性测试、安装与反安装测试负载

打开网易新闻 查看精彩图片

负载测试:各种工作负载下(不同并发情况下的测试),各种极限

压力:最大极限

强度:在很低资源配置(CPU低,内存低)的情况下,系统受限的,还能不能支撑正常的业务

打开网易新闻 查看精彩图片

系统运行与软件维护遗留系统演化策略

打开网易新闻 查看精彩图片

继承是指继承功能模型和数据模型

打开网易新闻 查看精彩图片

从功能、业务流程、数据角度来说都是有价值的,但是技术实现上过时了。

改造:在现有技术上做增强

打开网易新闻 查看精彩图片

编辑

新旧系统的转换策略

打开网易新闻 查看精彩图片

编辑

直接转换:现有系统下线,新系统上线,中间没有过渡期,同一时间只会运行同一个系统

并行转换:两个系统同时存在,成本增加,相当于灰度步数

分段转换:现有系统的某一个子系统先切到新系统,不断的变更

数据转换与迁移

打开网易新闻 查看精彩图片

编辑

影响软件可维护性的因素

打开网易新闻 查看精彩图片

编辑

软件维护类型

打开网易新闻 查看精彩图片

编辑

打开网易新闻 查看精彩图片

思维导图

软件工程知识体系 │ ├── 软件工程定义 │ └── 软件工程是将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件 │ ├── 软件生命周期划分 │ ├── 三个主要阶段 │ │ ├── 软件定义 │ │ │ ├── 包括可行性研究和详细需求分析过程 │ │ │ └── 任务是确定软件开发工程必须完成的总目标 │ │ ├── 软件开发 │ │ │ ├── 软件的设计与实现 │ │ │ └── 可分为:概要(总体)设计、详细设计、编码、测试等 │ │ └── 软件运行与维护 │ │ ├── 软件运行:把软件产品移交给用户使用 │ │ ├── 软件维护:对软件产品进行修改或对软件需求变化做出响应的过程,尽可能地延长软件的寿命 │ │ └── 软件退役:当软件已没有维护的价值时,宣告退役,软件生命随之宣告结束,不会进入到下一个生命周期了 │ └── 核心任务:软件投入运行后的主要任务是使软件持久满足用户的要求 │ ├── 软件开发方法分类 │ ├── 定义:软件开发方法是指软件开发过程所遵循的办法和步骤,从不同的角度可以对软件开发方法进行不同的分类 │ ├── 从开发风范上看 │ │ ├── 自顶向下的开发方法 │ │ │ └── 描述:先对最高层次中的问题进行定义、设计、编程和测试,而将其中未解决的问题作为一个子任务放到下一层次中去解决 │ │ ├── 自底向上的开发方法 │ │ │ └── 描述:根据系统功能要求,从具体的器件、逻辑部件或者相似系统开始,通过对其进行相互连接、修改和扩大,构成所要求的系统 │ │ └── 说明:在实际软件开发中,大都是两种方法结合,只不过是应用于开发的不同阶段以何者为主而已 │ ├── 从性质上看 │ │ ├── 形式化方法 │ │ │ ├── 是一种具有坚实数学基础的方法,从而允许对系统和开发过程做严格处理和论证 │ │ │ └── 适用于那些系统安全级别要求极高的软件的开发 │ │ └── 非形式化方法 │ │ └── 不把严格性作为其主要着眼点,通常以各种开发模型的形式得以体现 │ └── 从适应范围来看 │ ├── 整体性方法:适用于软件开发全过程的方法 │ └── 局部性方法:适用于开发过程某个具体阶段的软件方法 │ ├── 1️ 软件过程模型 (★★★★) │ ├── 软件生存周期模型定义 │ │ ├── 软件生存周期模型又称软件开发模型(software develop model)或软件过程模型(software process model) │ │ └── 它是从某个特定角度提出的软件过程的简化描述 │ ├── 主要模型 │ │ └── 瀑布模型、演化模型、原型模型、螺旋模型、喷泉模型和基于可重用构件的模型等 │ ├── 软件过程模型的基本概念 │ │ ├── 定义:软件过程是制作软件产品的一组活动以及结果,这些活动主要由软件人员来完成 │ │ └── 软件活动主要有 │ │ ├── (1) 软件描述:必须定义软件功能以及使用的限制 │ │ ├── (2) 软件开发:软件的设计和实现,软件工程人员制作出能满足描述的软件 │ │ ├── (3) 软件有效性验证:软件必须经过严格的验证,以保证能够满足客户的需求 │ │ └── (4) 软件进化:软件随着客户需求的变化不断地改进 │ ├── 软件开发模型分类 │ │ ├── 第一种:以软件需求完全确定为前提的瀑布模型 │ │ ├── 第二种:在软件开发初始阶段只能提供基本需求时采用的迭代式或渐进式模型 │ │ │ └── 例如:喷泉模型、螺旋模型、统一开发过程和敏捷方法等 │ │ └── 第三种:以形式化为基础的变换模型 │ │ ├── 核心思想:把软件开发当作数学公式推导来对待 │ │ └── 面向规格说明的开发方法:严格的数学证明 │ ├── 瀑布模型 │ │ ├── 生命周期划分 │ │ │ ├── 软件计划 │ │ │ ├── 需求分析 │ │ │ ├── 软件设计 │ │ │ ├── 程序编写 │ │ │ ├── 软件测试 │ │ │ └── 运行维护 │ │ ├── 特点 │ │ │ ├── 严格区分阶段,每个阶段因果关系紧密相连 │ │ │ ├── 只适合需求明确的项目 │ │ │ ├── 前一个阶段的错漏会隐蔽地带到后一个阶段 │ │ │ ├── 前一个阶段的错漏会隐蔽地带到后一个阶段,因此每一个阶段工作完成后,都要进行审查和确认 │ │ │ ├── 瀑布模型的一个主要特点是因果关系紧密相连,前一个阶段工作的输出结果是后一个阶段工作的输入 │ │ │ └── 不支持并行:瀑布模型各个阶段不支持并行,是严格串行化的 │ │ └── 缺点 │ │ ├── 软件需求完整性、正确性难确定 │ │ ├── 严格串行化,很长时间才能看到结果 │ │ ├── 要求每个阶段一次性完全解决该阶段工作,不现实 │ │ ├── 瀑布模型要求在每个阶段一次性地完全解决该阶段的工作,不允许随意修改需求 │ │ └── 不适合紧急的项目 │ ├── 智能模型 │ │ └── 基于规则的专家系统 │ ├── 变换模型 │ │ └── 形式化开发方法 │ ├── 喷泉模型 │ │ ├── 面向对象方法,复用性好 │ │ └── 开发过程无间隙,节省时间 │ ├── V模型(瀑布变种) │ │ ├── 测试贯穿于始终 │ │ ├── 测试分阶段,测试计划提前 │ │ └── 是一种测试的开发模型 │ ├── W模型 │ │ ├── 定义:测试和开发【并行进行】的软件过程模型 │ │ ├── 核心特点 │ │ │ ├── 开发与测试并行 │ │ │ ├── 测试活动与开发活动同步开展 │ │ │ └── 强调测试全程介入 │ │ └── 与V模型的关系 │ │ ├── 都是强调测试重要性的模型 │ │ ├── V模型:测试贯穿始终 │ │ └── W模型:测试与开发并行进行 │ ├── 原型模型 │ │ ├── 适合需求不明确的项目 │ │ ├── 两个阶段 │ │ │ ├── 原型开发阶段 │ │ │ └── 目标软件开发阶段 │ │ ├── 分类方式 │ │ │ ├── 从原型是否实现功能来分 │ │ │ │ ├── 水平原型:界面 │ │ │ │ └── 垂直原型:算法 │ │ │ └── 从原型最终结果来分 │ │ │ ├── 抛弃式原型 │ │ │ │ ├── 主要用于界面设计 │ │ │ │ ├── 用于快速验证需求,确认后即被丢弃,后续采用瀑布模型开发 │ │ │ │ └── 基本思路:开始就做一个简单的界面设计,用来让用户有直观感受,从而可以提出需求,等需求获取到之后,可以把这个界面原型抛弃不用 │ │ │ └── 演化式原型 │ │ │ ├── 主要用在必须易于升级和优化的场合,适合于Web项目 │ │ │ └── 通过迭代逐步完善为最终系统 │ │ └── 主要目的:通过迭代获取用户满意的系统 │ ├── 增量模型 │ │ ├── 将软件产品分解为多个增量构件,每个增量交付部分功能 │ │ ├── 优点 │ │ │ ├── 逐步交付,用户可早期获得部分功能 │ │ │ ├── 降低风险,便于管理 │ │ │ └── 适应需求变化,与瀑布模型相比,降低了实现需求变更的成本,更容易得到客户对于已完成开发工作的反馈意见,并且客户可以更早地使用软件并从中获得价值。 │ │ └── 缺点 │ │ ├── 要求系统具有可分解性 │ │ └── 可能增加管理复杂性 │ ├── 螺旋模型 │ │ ├── 以快速原型为基础 + 瀑布模型 │ │ ├── 考虑了风险问题 │ │ ├── 支持并行:螺旋模型各个阶段是支持并行的 │ │ ├── 两个显著特点 │ │ │ ├── ① 采用循环的方式逐步加深系统定义和实现的深度,同时降低风险 │ │ │ └── ② 确定一系列里程碑,确保项目开发过程中的相关利益者都支持可行的和令人满意的系统解决方案 │ │ ├── 螺旋模型的若干次迭代 │ │ │ ├── ① 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件 │ │ │ ├── ② 风险分析:分析评估所选方案,考虑如何识别和消除风险 │ │ │ │ └── 详细说明:分析评估所选方案,考虑如何识别和消除风险,有时候需要用到原型系统来完成,如果某些风险不能排除,该方案立即终止,否则启动下一个开发步骤 │ │ │ ├── ③ 实施工程:实施软件开发和验证 │ │ │ └── ④ 客户评估:评价开发工作,提出修正建议,制定下一步计划 │ │ ├── 适合场景 │ │ │ ├── 内部的大规模软件开发 │ │ │ ├── 如果发现风险,但是风险不能解决,则立即停止 │ │ │ ├── 让客户相信项目风险是不容易的,所以螺旋模型适合内部的大规模软件开发 │ │ │ └── 如果执行风险分析将大大影响项目的利润,那么进行风险分析毫无意义,因此,螺旋模型只适合于大规模软件项目 │ │ ├── 螺旋模型适用于面向规格说明、面向过程和面向对象的软件开发方法 │ │ └── 核心解释:这说明螺旋模型具有极广的适用范围,不局限于某一种特定的设计方法或者技术 │ ├── 快速应用开发RAD │ │ ├── 概念 │ │ │ ├── 瀑布模型的高速变种 │ │ │ ├── 适用比传统生命周期快得多的开发方法 │ │ │ ├── 强调极短的开发周期 │ │ │ └── 通常适用于构件的开发方法获得快速开发 │ │ ├── 过程 │ │ │ ├── 业务建模 │ │ │ ├── 数据建模 │ │ │ ├── 过程建模 │ │ │ ├── 应用生成 │ │ │ └── 测试与交付 │ │ ├── 适用性(局限性) │ │ │ ├── 对模块化要求比较高,如果某项功能不能被模块化,则其构件就会出问题 │ │ │ ├── 如果高性能是一个指标,且必须通过调整结构使其适应系统构件才能获得,则RAD也有可能不能奏效 │ │ │ ├── 要求开发者和客户必须在很短的时间完成一系列的需求分析,任何一方配合不当都会导致失败 │ │ │ └── 只能用于管理信息系统的开发,不适合技术风险很高的情况 │ │ └── 用户参与:RAD需要用户参与 │ ├── 构件组装模型 / 基于构件的开发方法(CBSD) │ │ ├── 构件是可以独立部署的单元 │ │ ├── 通过复用构件可以提高软件的可靠性和易维护性 │ │ ├── 核心特征:融合了螺旋模型的特征,本质上是演化型的,强调模块化和构件复用,也适合大型项目 │ │ ├── 五个主要阶段 │ │ │ ├── ① 需求分析和定义 │ │ │ ├── ② 结构设计 │ │ │ ├── ③ 构件库的建立 │ │ │ ├── ④ 应用软件构建 │ │ │ └── ⑤ 测试和发布 │ │ └── 说明:CBSD更强调构件的重用和组装,而不是从头编写代码,代码编写的工作主要体现在"构件库的建立"和"应用软件构建"这两个阶段中 │ ├── 统一过程 / 统一开发方法(RUP) │ │ ├── 适合场景:适合复杂项目,且支持根据新需求启动新开发周期,是一种重量级的软件开发方法 │ │ ├── 典型特点 │ │ │ ├── 用例驱动 │ │ │ ├── 以架构为中心 │ │ │ ├── 迭代和增量 │ │ │ │ ├── 补充说明:迭代指重复开发过程,而增量指逐步添加功能 │ │ │ │ └── 好处:采用迭代和增量的开发方式,这样可以在软件开发的早期就对关键的、影响大的风险进行处理 │ │ ├── 四个阶段 │ │ │ ├── 说明:每一个阶段都由一个或多个连续的迭代(iteration)组成。迭代并不是重复地做相同的事,而是针对不同用例的细化和实现。每一个迭代都是一个完整的开发过程,它需要项目经理根据当前迭代所处的阶段以及上次迭代的结果,适当地对核心工作流中的行为进行裁剪 │ │ │ ├── 构思阶段(初始/初启阶段) │ │ │ │ ├── 定义最终产品视图和业务模型,确定系统范围 │ │ │ │ └── 里程碑:生命周期目标 │ │ │ ├── 细化阶段(精化阶段) │ │ │ │ ├── 设计及确定系统架构,制定工作计划及资源要求 │ │ │ │ ├── 淘汰风险元素 │ │ │ │ └── 里程碑:生命周期架构 │ │ │ ├── 构造阶段 │ │ │ │ ├── 开发剩余构件和应用程序功能,把这些构件集成为产品,并进行详细测试 │ │ │ │ └── 里程碑:初始运作功能 │ │ │ └── 移交阶段 │ │ │ ├── 确保软件对最终用户是可用的,进行β测试,制作产品发布版本 │ │ │ └── 里程碑:产品发布 │ │ ├── 9个核心工作流 │ │ │ ├── 业务建模 │ │ │ ├── 需求 │ │ │ ├── 分析与设计 │ │ │ ├── 实现 │ │ │ ├── 测试 │ │ │ ├── 部署 │ │ │ ├── 配置与变更管理 │ │ │ ├── 项目管理 │ │ │ └── 环境 │ │ └── RUP模型的“4+1”视图模型 │ │ ├── 逻辑视图:功能需求,对应用户 │ │ ├── 开发视图:软件管理,编程人员 │ │ ├── 物理视图:拓扑,安装,工程,系统工程人员 │ │ ├── 进程视图:性能,可扩展性,吞吐量,系统集成人员 │ │ └── 场景视图 │ └── 敏捷开发方法 │ ├── 敏捷开发概述 │ │ ├── 定义:一种以人为核心、迭代、循序渐进的开发生态 │ │ ├── 适用场景:适用于小团队和小项目 │ │ └── 核心思想:小步快跑 │ ├── 敏捷开发核心思想 │ │ ├── ① 敏捷方法是适应型,而非可预测型 │ │ ├── ② 敏捷方法是迭代增量式的开发过程 │ │ └── ③ 敏捷方法是以人为本,而非以过程为本 │ ├── 敏捷宣言 │ │ ├── 个体和交互胜过过程和工具 │ │ ├── 可工作的软件胜过大量的文档 │ │ ├── 客户合作胜过合同谈判 │ │ └── 响应变化胜过遵循计划 │ ├── 敏捷软件过程核心理念 │ │ ├── 强调内容 │ │ │ ├── 让客户满意和软件尽早增量发布 │ │ │ ├── 小而高度自主的项目团队 │ │ │ ├── 非正式的方法 │ │ │ ├── 最小化软件工程工作产品 │ │ │ └── 整体精简开发 │ │ └── 产生原因 │ │ ├── 在绝大多数软件开发过程中,提前预测哪些需求是稳定的和哪些需求会变化非常困难 │ │ ├── 对于软件项目构建来说,设计和构建是交错的 │ │ ├── 从指定计划的角度来看,分析、设计、构建和测试并不容易预测 │ │ └── 可执行原型和部分实现的可运行系统是了解用户需求和反馈的有效媒介 │ ├── 敏捷方法速记表 │ │ ├── 极限编程 (XP) │ │ │ ├── 核心标签:工程纪律狂魔 │ │ │ ├── 一句话类比:像特种兵训练:测试驱动、结对编程、持续集成,要求极高。 │ │ │ └── 纪律性:XP强调高度的纪律性 │ │ ├── 水晶 (Crystal) │ │ │ ├── 核心标签:看人下菜碟 │ │ │ ├── 一句话类比:像定制西装:项目大就重一点,项目小就轻一点,不强求一律。 │ │ │ └── 纪律性:水晶系列提倡最少纪律 │ │ ├── 开放式源码 │ │ │ ├── 核心标签:全球打补丁 │ │ │ └── 一句话类比:像维基百科:谁都能改,但最终由主编(维护者)合并。 │ │ ├── SCRUM │ │ │ ├── 核心标签:固定冲刺+三个角色 │ │ │ └── 一句话类比:像足球队的赛前集训:固定周期(冲刺)、每天站会、有教练(Scrum Master)。 │ │ ├── 功用驱动 (FDD) │ │ │ ├── 核心标签:功能列表+首席程序员 │ │ │ ├── 一句话类比:像建筑工地:总工(首席程序员)设计,工人(类程序员)按图纸砌墙。 │ │ │ └── 迭代周期:致力于短时的迭代阶段和可见可用的功能,在FDD中一个迭代周期一般是两周 │ │ └── 自适应 (ASD) │ │ ├── 核心标签:猜测-合作-学习 │ │ └── 一句话类比:像探险队:没有地图,边走边猜、边合作、边学,不断调整路线。 │ ├── 极限编程(XP) │ │ ├── 概述:在一些对费用控制严格的公司中的使用非常有效,近螺旋式的开发方法 │ │ ├── 核心实践 │ │ │ ├── 测试先行(测试驱动开发) │ │ │ ├── 轻量文档以减少初期负担 │ │ │ └── 结对编程等协作方式 │ │ ├── 四大价值观 │ │ │ ├── 沟通:加强面对面沟通 │ │ │ ├── 简单:不过度设计 │ │ │ ├── 反馈:及时反馈 │ │ │ └── 勇气:接受变更的勇气 │ │ └── 十二大最佳实践 │ │ ├── 简单设计 │ │ ├── 测试驱动 │ │ ├── 代码重构 │ │ ├── 结对编程 │ │ ├── 持续集成 │ │ ├── 现场客户 │ │ ├── 发行版本小型化 │ │ ├── 系统隐喻 │ │ ├── 代码集体所有制 │ │ ├── 规划策略 │ │ ├── 规范代码 │ │ └── 40小时工作机制 │ ├── 水晶方法(Crystal) │ │ └── 提倡“机动性”的方法,拥有对不同类型项目非常有效的敏捷过程 │ ├── 并列争球法(SCRUM) │ │ ├── 概述:明确定义了可重复的方法过程来解决可重复问题 │ │ ├── 侧重于项目管理 │ │ ├── 角色 │ │ │ ├── 产品负责人(PO) │ │ │ ├── 开发团队 │ │ │ └── Scrum Master │ │ ├── 工件 │ │ │ ├── 产品待办列表 │ │ │ ├── 迭代待办事项 │ │ │ └── 潜在可发布的产品增量 │ │ └── 会议 │ │ ├── 迭代计划会议 │ │ ├── 每日站会 │ │ ├── 迭代评审会议 │ │ └── 迭代回顾会议 │ ├── 自适应软件开发方法(ASD) │ │ └── 核心是三个非线性的、重叠的开发阶段:猜测、合作与学习 │ ├── 特征驱动开发方法(FDD) │ │ ├── 认为有效的软件开发需要3要素:人、过程、技术 │ │ └── 定义了6种关键的项目角色 │ │ ├── 项目经理 │ │ ├── 首席架构设计师 │ │ ├── 开发经理 │ │ ├── 主程序员 │ │ ├── 程序员 │ │ └── 领域专家 │ ├── 开放式源码 │ │ └── 程序开发人员在地域上分布很广(其他方法强调集中办公) │ ├── 动态系统开发方法(DSDM) │ │ ├── 倡导以业务为核心 │ │ └── 核心主张:先交付满足核心业务需求的“够好用”的版本,而不是追求“完美无缺”才发布 │ └── 敏捷开发特点补充 │ └── 敏捷开发过程要求开发人员必须有权做技术方面的所有决定,这体现了敏捷方法“面向人的”特点 │ ├── 2️ 基于构件的软件工程(CBSE)(★★) │ ├── 构件的定义 │ │ └── 基于构件开发中的构件(Component)是一个自包容、可复用的程序集,外界通过接口访问其提供的服务 │ ├── 哲学:购买而不是重新构造 │ ├── CBSE的主要过程步骤 │ │ ├── (1) 系统需求概览 │ │ ├── (2) 识别候选构件 │ │ ├── (3) 根据发现的构件修改需求 │ │ ├── (4) 体系结构设计 │ │ ├── (5) 构件定制与适配 │ │ └── (6) 组装构件创建系统 │ ├── 软件重用 │ │ ├── 定义:软件重用是指在两次或多次不同的软件开发过程中重复使用相同或相似软件元素的过程。软件元素包括需求分析文档、设计过程、设计文档、程序代码、测试用例、领域知识等 │ │ ├── 软件重用可以区别为横向重用和纵向重用 │ │ ├── 横向重用 │ │ │ ├── 是指重用不同应用领域中的软件元素,例如数据结构、分类算法和人机界面构建等 │ │ │ └── 标准函数是一种典型的、原始的横向重用机制 │ │ └── 纵向重用 │ │ ├── 是指在一类具有较多公共性的应用领域之间进行软部件重用 │ │ └── 纵向重用活动的主要关键点是域分析:根据应用领域的特征及相似性预测软部件的可重用性 │ ├── 对象重用 │ │ ├── 说明:COM不支持任何形式的实现继承 │ │ ├── COM支持两种形式的对象组装 │ │ │ ├── 包含(Containment) │ │ │ │ ├── 是一个对象拥有指向另一个对象的唯一引用 │ │ │ │ ├── 外部对象只是把请求转发给内部对象,所谓转发就是调用内部对象的方法 │ │ │ │ ├── 包含能重用内含于其他构件的实现,是完全透明的 │ │ │ │ └── 如果包含层次较深,或者被转发的方法本身相对简单,包含会存在性能上的问题 │ │ │ └── 聚集(Aggregation) │ │ │ ├── COM定义的第二类重用形式 │ │ │ ├── 聚集直接把内部对象接口引用传给外部对象的客户,而不是再转发请求 │ │ │ └── 保持透明性是很重要的,因为外部对象的客户无法辨别哪个特定接口是从内部对象聚集而来的 │ ├── 构件与原子构件 │ │ ├── 构件 │ │ │ └── 是一组通常需要同时部署的原子构件 │ │ ├── 原子构件 │ │ │ ├── 是一个模块和一组资源 │ │ │ ├── 是部署、版本控制和替换的基本单位 │ │ │ ├── 通常成组地部署,但是它也能够被单独部署 │ │ │ └── 模块:是一组类和可能的非面向对象的结构体,比如过程或者函数 │ │ └── 构件与原子构件的区别 │ │ └── 大多数原子构件永远都不会被单独部署,尽管它们可以被单独部署。相反,大多数原子构件都属于一个构件家族,一次部署往往涉及整个家族 │ ├── 构件与类的对比 │ │ ├── 构件的特性 │ │ │ ├── (1) 独立部署单元:构件的部署必须能跟它所在的环境及其他构件完全分离,构件作为一个部署单元是不可拆分的 │ │ │ ├── (2) 作为第三方的组装单元 │ │ │ ├── (3) 没有(外部的)可见状态,可以利用容器管理自身对外的可见状态 │ │ │ ├── 构件可以基于对象实现,也可以不基于对象实现 │ │ │ └── 构件与类的关系:一个构件可以包含多个类元素,但是一个类元素只能属于一个构件。将一个类拆分进行部署通常没什么意义 │ │ └── 对象的特性 │ │ ├── (1) 一个实例单元,具有唯一的标志 │ │ ├── (2) 可能具有状态,此状态外部可见 │ │ └── (3) 封装了自己的状态和行为 │ ├── OMG构件标准 │ │ ├── 说明:对象管理组织(OMG)基于CORBA基础设施定义了四种构件标准 │ │ ├── (1) 实体(Entity)构件 │ │ │ └── 需要长期持久化并主要用于事务性行为,由容器管理其持久化 │ │ ├── (2) 加工(Process)构件 │ │ │ └── 同样需要容器管理其持久化,但没有客户端可访问的主键 │ │ ├── (3) 会话(Session)构件 │ │ │ └── 不需要容器管理其持久化,其状态信息必须由构件自己管理 │ │ ├── (4) 服务(Service)构件 │ │ │ └── 是无状态的 │ │ └── IDL文件元素 │ │ ├── 说明:OMG接口定义语言IDL文件包含了六种不同的元素 │ │ ├── 接口描述:是IDL文件中最核心的内容 │ │ ├── 模块定义:将映射为Java语言中的包(Package)或C++语言中的命名空间(Namespace) │ │ ├── 类型定义 │ │ ├── 常量定义 │ │ ├── 异常 │ │ └── 值类型 │ ├── 构件模型要素 │ │ ├── 接口 │ │ │ ├── 构件通过构件接口来定义 │ │ │ ├── 构件模型规定应如何定义构件接口 │ │ │ └── 接口定义中应包含的要素:操作名、参数以及异常等 │ │ ├── 使用信息 │ │ │ ├── 命名机制:为使构件远程分布和访问,必须给构件一个特定的、全局唯一的名字或句柄 │ │ │ ├── 构件元数据 │ │ │ │ ├── 构件本身相关的数据,比如构件的接口和属性信息 │ │ │ │ └── 用户可以通过元数据找到构件提供的服务 │ │ │ ├── 构件模型的实现通常包括访问构件的元数据的特定方法 │ │ │ └── 构件配置:构件是通用实体,在部署的时候,必须对构件进行配置来适应应用系统 │ │ └── 部署 │ │ ├── 构件模型包括一个规格说明,指出应该如何打包构件 │ │ ├── 打包目的:使其部署成为一个独立的可执行实体 │ │ └── 部署信息中包含有关包中内容的信息和它的二进制构成的信息 │ ├── 构件特征 │ │ ├── 可组装性:所有外部交互必须通过公开定义的接口进行 │ │ ├── 可部署性:构件总是二进制形式的,能作为一个独立实体在平台上运行 │ │ ├── 文档化:用户根据文档来判断构件是否满足需求 │ │ ├── 独立性:可以在无其他特殊构件的情况下进行组装和部署。构件应该是独立的,如确实需要其他构件提供服务,则应显示声明 │ │ └── 标准化:符合某种标准化的构件模型 │ ├── 配置项 │ │ ├── 定义:配置项是构成产品配置的主要元素 │ │ ├── 两大类 │ │ │ ├── (1) 属于产品组成部分的工作成果:如需求文档、设计文档、源代码和测试用例等 │ │ │ └── (2) 属于项目管理和机构支撑过程域产生的文档:如工作计划、项目质量报告和项目跟踪报告等。这些文档虽然不是产品的组成部分,但是值得保存 │ │ └── 不属于配置项:设备清单不属于配置项 │ ├── 面向构件的编程(COP) │ │ ├── 定义:面向构件的编程(COP)关注于如何支持建立面向构件的解决方案 │ │ └── 基本支持 │ │ ├── 多态性(可替代性) │ │ ├── 模块封装性(高层次信息的隐藏) │ │ ├── 后期的绑定和装载(部署独立性) │ │ └── 安全性(类型和模块安全性) │ ├── 逻辑构件模型与物理构件模型 │ │ ├── 逻辑构件模型 │ │ │ └── 用功能包描述系统的抽象设计,用接口描述每个服务集合,以及功能之间如何交互以满足用户需求,它作为系统的设计蓝图以保证系统提供适当的功能 │ │ └── 物理构件模型 │ │ └── 用技术设施产品、硬件分布和拓扑结构、以及用于绑定的网络和通信协议描述系统的物理设计,这种架构用于了解系统的性能、吞吐率等许多非功能性属性 │ ├── 构件的组装(一般都要借助胶水代码) │ │ ├── 构件组装定义 │ │ │ └── 构件组装是指将构件库中的构件经过适当修改后相互连接,或者将它们与当前开发项目中的构件元素相连接,最终构成新的目标软件 │ │ ├── 构件组装技术 │ │ │ ├── 说明:构件组装技术大致可分为基于功能的组装技术、基于数据的组装技术和面向对象的组装技术 │ │ │ ├── (1) 基于功能的构件组装技术 │ │ │ │ └── 这种技术侧重于根据软件系统的功能需求来组装构件 │ │ │ ├── (2) 基于数据的构件组装技术 │ │ │ │ └── 这种技术首先根据当前软件问题的核心数据结构设计一个框架,然后根据框架中各个结点的需求提取构件并进行适应性修改 │ │ │ └── (3) 面向对象的构件组装技术 │ │ │ └── 面向对象技术提供了封装、继承和多态等特性,这些特性使得面向对象比其他的软件开发方法更适合支持软件复用 │ │ ├── 构件组装模型的一般开发过程 │ │ │ └── 顺序:设计构件组装 → 建立构件库 → 构建应用软件 → 测试与发布 │ │ ├── 系统构件组装的三个层次 │ │ │ ├── (1) 定制(Customization) │ │ │ │ └── 是构件组装过程的第一个层次,主要关注于根据特定需求对构件进行个性化的调整或修改 │ │ │ ├── (2) 集成(Integration) │ │ │ │ └── 是构件组装过程的第二个层次,主要关注于将多个定制好的构件组合成一个完整的软件系统 │ │ │ └── (3) 扩展(Extension) │ │ │ └── 是构件组装过程的第三个层次,主要关注于在现有软件系统的基础上增加新的功能或构件 │ │ ├── 顺序组装:按顺序调用已经存在的构件,可以用两个已经存在的构件来创造一个新的构件 │ │ ├── 层次组装:被调用构件的“提供”接口必须和调用构件的“请求”接口兼容 │ │ └── 叠加组装:多个构件合并形成新构件,新构件整合原构件的功能,对外提供新的接口 │ ├── 构件管理 │ │ └── 已有的构件分类方法可以分为三大类 │ │ ├── 关键字分类法 │ │ │ └── 根据领域分析的结果将应用领域的概念按照从抽象到具体的顺序逐次分解为树形或有向无回路图结构 │ │ ├── 刻面分类法 │ │ │ └── 利用Facet描述构件执行的功能、被操作的数据、构件应用的语境或任意其他特征 │ │ └── 超文本组织方法 │ │ └── 使得检索者在阅读文档过程中可以按照人类的联想思维方式任意跳转到包含相关概念或构件的文档 │ └── 组装可能出现3种不兼容 │ ├── 参数不兼容:接口每一侧的操作有相同的名字,但参数类型或参数个数不相同 │ │ └── 解决方案:构件接口参数顺序不一致需要通过适配器解决 │ ├── 操作不兼容:提供接口和请求接口的操作名不同 │ └── 操作不完备:一个构件的提供接口是另一个构件请求接口的一个子集,或者相反 │ ├── 3️ 逆向工程 (★) │ ├── 定义:分析程序,力图在比源代码更高抽象层次上建立程序的表示过程,是设计的恢复过程 │ ├── 逆向工程导出信息的四个抽象层次(在逆向工程中用于恢复信息的方法有四类。其中,用户指导下的搜索与变换方法用于导出实现级和结构) │ │ ├── 实现级:包括程序的抽象语法树、符号表、过程的设计表示 │ │ ├── 结构级:包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图、程序和数据结构 │ │ ├── 功能级:包括反映程序段功能及程序段之间关系的信息,例如数据和控制流模型 │ │ └── 领域级:包括反映程序分量或程序诸实体与应用领域概念之间对应关系的信息,例如实体关系模型 │ └── 相关概念 │ ├── 重构/重组(Restructuring):在同一抽象级别上转换系统描述形式 │ ├── 设计恢复(Design recovery):借助工具从已有程序中抽象出有关数据设计、总体结构设计和过程设计等方面的信息(不一定是原始设计) │ ├── 正向工程(Forward engineering):不仅从现有系统中恢复设计信息,而且使用该信息去改变或重构现有系统,以改善其整体质量 │ └── 再工程/重构工程(Re-engineering) │ ├── 定义:对现有系统的重新开发过程 │ ├── 过程步骤 │ │ ├── 逆向工程:分析现有系统,恢复设计信息 │ │ ├── 新需求的考虑过程:考虑需要新增或修改的功能 │ │ └── 正向工程:应用逆向工程获得的信息和新需求,重新开发系统 │ └── 最终产物:产生一个新的系统 │ ├── 4️ 净室软件工程 (★) │ ├── 名称释义:净室即无尘室、洁净室,是一个受控污染级别的环境 │ ├── 定义:软件开发的一种形式化方法,可以开发较高质量的软件 │ ├── 主要目标:在开发过程中实现零缺陷或接近零缺陷 │ ├── 核心思想 │ │ ├── 使用盒结构规约(或形式化方法)进行分析和设计建模 │ │ ├── 强调将正确性验证,而不是测试,作为发现和消除错误的主要机制 │ │ └── 使用统计测试来获取认证软件可靠性所需要的信息 │ ├── 适用性分析 │ │ ├── 适用场景:安全关键系统 │ │ │ ├── 适用于那些系统安全级别要求极高的软件的开发 │ │ │ ├── 能够数学地表述和研究应用问题及软件实现 │ │ │ ├── 通过正确性验证确保系统的安全性和可靠性 │ │ │ └── 形式化方法系统安全级别要求极高的场景 │ │ └── 不适用场景:复杂应用问题 │ │ ├── 用形式化语言书写的大型应用问题的软件规格说明往往过于细节化 │ │ ├── 难为用户和软件设计人员所理解 │ │ ├── 要求开发人员具备良好的数学基础 │ │ └── 在目前的软件开发实践中并未得到普遍应用 │ ├── 技术手段 │ │ ├── 统计过程控制下的增量式开发:控制迭代 │ │ ├── 基于函数的规范和设计:盒子结构 │ │ │ └── 定义3种抽象层次 │ │ │ ├── 行为视图(黑盒) │ │ │ ├── 有限状态机视图(状态盒) │ │ │ └── 过程视图(明盒) │ │ ├── 正确性验证:净室工程的核心 │ │ └── 统计测试和软件认证 │ │ ├── 使用统计学原理,总体太大时必须采用抽样方法 │ │ └── 基于客户对软件的预期使用测试 │ ├── 强调内容 │ │ ├── 强调在规划和设计上的严格性 │ │ └── 强调统计质量控制技术,包括基于客户对软件的预期使用测试 │ ├── 理论基础 │ │ ├── 函数理论 │ │ │ └── 函数理论将程序视为从输入到输出的映射,在CSE中的主要应用是将程序规范视为函数规范,强调完备性、一致性和正确性。这种方法有助于通过基于函数理论的推理来验证设计的正确性,是CSE追求零缺陷或接近零缺陷的重要理论基础 │ │ └── 抽样理论 │ ├── 开发成本说明 │ │ └── CSE确实要求采用增量式开发等特定方法,普通工程师需要额外培训才能掌握,这增加了开发成本 │ └── 缺点 │ ├── 太理论化,正确性验证的步骤比较困难且耗时 │ ├── 正确性验证步骤被认为是困难且耗时的,这是其缺点之一 │ ├── 开发小组不进行传统的模块测试,这是不现实的 │ ├── 净室软件工程开发的模块需要进行传统的模块测试 │ ├── 脱胎于传统软件工程,不可避免带有传统软件工程的一些弊端 │ ├── 不适合复杂应用问题 │ └── 净室软件工程的成本会比较高 │ ├── 5️ 需求工程 (★★) │ ├── 需求专题讨论会 │ │ └── 一个重要优点是能够有效地解决不同涉众之间的需求冲突 │ ├── 软件产品改进动力 │ │ └── 软件开发商对软件产品进行持续不断改进的动力主要来自用户的反馈意见 │ ├── 需求的多层次 │ │ ├── 说明:需求是多层次的,包括业务需求、用户需求和系统需求,这三个不同层次从目标到具体,从整体到局部,从概念到细节 │ │ ├── (1) 业务需求 │ │ │ ├── 是指反映企业或客户对系统高层次的目标要求 │ │ │ ├── 来源:通常来自项目投资人、购买产品的客户、客户单位的管理人员、市场营销部门或产品策划部门等 │ │ │ └── 作用:通过业务需求可以确定项目视图和范围,项目视图和范围文档把业务需求集中在一个简单、紧凑的文档中,该文档为以后的开发工作奠定了基础 │ │ ├── (2) 用户需求 │ │ │ ├── 描述的是用户的具体目标,或用户要求系统必须能完成的任务 │ │ │ ├── 即用户需求描述了用户能使用系统来做些什么 │ │ │ └── 获取方式:通常采取用户访谈和问卷调查等方式,对用户使用的场景(scenarios)进行整理,从而建立用户需求 │ │ └── (3) 系统需求 │ │ ├── 是从系统的角度来说明软件的需求,包括功能需求、非功能需求和设计约束等 │ │ ├── 功能需求:也称为行为需求,它规定了开发人员必须在系统中实现的软件功能,用户利用这些功能来完成任务,满足业务需要。功能需求通常是通过系统特性的描述表现出来的,所谓特性,是指一组逻辑上相关的功能需求,表示系统为用户提供某项功能(服务),使用户的业务目标得以满足 │ │ ├── 非功能需求:是指系统必须具备的属性或品质,又可细分为软件质量属性(例如,可维护性、效率等)和其他非功能需求,比如安全性 │ │ └── 设计约束:指限制条件和补充规定 │ ├── 质量功能部署(QFD) │ │ ├── 定义:Quality Function Deployment,是一种将用户要求转化成软件需求的技术 │ │ ├── 目的:最大限度地提升软件工程过程中用户的满意度 │ │ └── 软件需求的三类划分(从客户角度) │ │ ├── (1) 常规需求(基本需求) │ │ │ └── 用户认为系统应该做到的功能或性能,实现越多用户会越满意,核心功能 │ │ ├── (2) 期望需求 │ │ │ └── 用户想当然认为系统应具备的功能或性能,但并不能正确描述自己想要得到的这些功能或性能需求。如果期望需求没有得到实现,会让用户感到不满意 │ │ └── (3) 意外需求 │ │ └── 也称为兴奋需求,是用户要求范围外的功能或性能(但通常是软件开发人员很乐意赋予系统的技术特性),实现这些需求用户会更高兴,但不实现也不影响其购买的决策。意外需求是控制在开发人员手中的,开发人员可以选择实现更多的意外需求,以便得到高满意、高忠诚度的用户,也可以(出于成本或项目周期的考虑)选择不实现任何意外需求 │ ├── 关于需求的陈述 │ │ ├── ① 每一项需求都必须完整、准确地描述即将要开发的功能 │ │ ├── ② 需求必须能够在系统及其运行环境的能力和约束条件内实现 │ │ └── ③ 每一项需求记录的功能都必须是用户的真正的需要 │ ├── 需求开发(从无到有,建立需求基线) │ │ ├── (1) 需求获取 │ │ │ └── 与用户沟通,收集原始需求 │ │ ├── (2) 需求分析 │ │ │ └── 分析、建模、排歧、细化 │ │ ├── (3) 需求规格说明编写 │ │ │ ├── 形成 SRS(软件需求规格说明书),包括:功能需求、非功能需求和约束 │ │ │ └── 约束分为 │ │ │ ├── ① 设计约束:限制系统设计(如“必须使用Java开发”) │ │ │ └── ② 过程约束:限制开发过程(如“需遵循ISO 9001流程”) │ │ └── (4) 需求确认与验证 │ │ ├── 验证:需求是否正确、一致、完整 │ │ ├── 确认:用户确认需求符合预期 │ │ └── 输出:需求基线(通过评审的 SRS) │ │ └── 需求基线是产品功能需求和非功能需求的需求约定,是需求开发和需求管理之间的桥梁 │ ├── 需求获取方法 │ │ ├── 需求获取步骤 │ │ │ ├── 第一步:开发高层的业务模型 │ │ │ ├── 第二步:定义项目范围和高层需求 │ │ │ │ └── 使用系统上下文图和系统顶层用例图等建模手段 │ │ │ ├── 第三步:识别用户角色和用户代表 │ │ │ ├── 第四步:获取具体的需求 │ │ │ └── 第五步:确定目标系统的业务工作流 │ │ ├── 用户面谈:1对1-3,有代表性的用户,了解主观想法,交互好;成本高,要有领域知识支撑 │ │ ├── 联合需求计划(JRP):高度组织的群体会议,各方参与,了解想法,消除分歧,交互好,成本高 │ │ ├── 问卷调查:用户多,无法一一访谈,成本低 │ │ ├── 现场观察:针对较为复杂的流程和操作 │ │ ├── 原型化方法:通过简易系统方式解决早期需求不确定问题 │ │ └── 头脑风暴法:一群人围绕新业务,发散思维,不断产生新的观点 │ ├── 需求分析工具 │ │ ├── 结构化分析 │ │ │ ├── 基本思想:自顶向下,逐层分解。把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题。经过逐层分解,每个最低层的问题都是足够简单、容易解决的 │ │ │ ├── 分析模型的核心:数据字典 │ │ │ ├── 三个层次的模型 │ │ │ │ ├── 数据模型:用E-R图表示 │ │ │ │ ├── 功能模型:用DFD(数据流图)表示 │ │ │ │ └── 行为模型(状态模型):用状态转换图(STD)表示 │ │ │ ├── 功能模型:DFD(数据流图) │ │ │ ├── 行为模型:STD(状态转换图) │ │ │ └── 数据模型:ER图(实体关系图) │ │ │ ├── 1:1的联系 │ │ │ ├── 1:n的联系 │ │ │ ├── m:n的联系 │ │ │ └── 同一实体集内一对多的联系 │ │ └── UML(统一建模语言) │ │ ├── 基于UML的需求分析过程 │ │ │ └── 说明:在初步的业务需求描述已经形成的前提下,基于UML的需求分析过程大致可分为以下步骤 │ │ │ ├── 步骤一:利用用例及用例图表示需求 │ │ │ │ └── 从业务需求描述出发获取执行者和场景;对场景进行汇总、分类、抽象,形成用例;确定执行者与用例、用例与用例图之间的关系,生成用例图 │ │ │ └── 步骤二:利用包图和类图表示目标软件系统的总体框架结构 │ │ │ └── 根据领域知识、业务需求描述和既往经验设计目标软件系统的顶层架构;从业务需求描述中提取"关键概念",形成领域概念模型;从概念模型和用例出发,研究系统中主要的类之间的关系,生成类图 │ │ ├── UML图分类 │ │ │ ├── 静态图(结构图) │ │ │ │ ├── 类图:描述类、接口及其关系,是面向对象设计的基础 │ │ │ │ ├── 对象图:类图的实例,展示特定时刻对象及其关系的静态快照 │ │ │ │ ├── 构件图:描述封装组件及其接口、端口,用于模块化系统设计 │ │ │ │ ├── 部署图:描述节点上的构件部署,展示软硬件之间的映射关系 │ │ │ │ ├── 包图:通过带标签的文件夹组织元素,管理大型项目结构 │ │ │ │ └── 组合结构图 │ │ │ └── 动态图(行为图) │ │ │ ├── 用例图 │ │ │ ├── 顺序图(序列图) │ │ │ ├── 通信图 │ │ │ ├── 状态图 │ │ │ ├── 活动图 │ │ │ ├── 定时图 │ │ │ └── 交互概览图 │ │ ├── 用例图 │ │ │ ├── 由参与者(Actor)、用例(Use Case)、边界以及它们之间的关系构成 │ │ │ ├── 用于描述系统功能 │ │ │ ├── 最适合用来描述系统的功能需求和用户与系统的交互 │ │ │ ├── 用例模型建立流程 │ │ │ │ ├── 1. 识别参与者(用户、组织、外部系统,时间) │ │ │ │ ├── 2. 合并需求获得用例 │ │ │ │ ├── 3. 细化用例描述 │ │ │ │ └── 4. 调整用例模型(可选步骤) │ │ │ └── 关系 │ │ │ ├── 包含关系(Include) │ │ │ │ ├── 判断:当两个用例都必须需要执行某一个用例的时候就是包含关系 │ │ │ │ ├── 说明:当可以从两个或两个以上的原始用例中提取公共行为,或者发现能够使用一个构件来实现某一个用例的部分功能是很重要的事时,应该使用包含关系来表示它们 │ │ │ │ └── 举例:“创建新订单”、“更新订单”与用例“核查客户帐号”之间是包含关系 │ │ │ ├── 扩展关系(Extend) │ │ │ │ ├── 判断:当某一个用例可选或条件触发另一个用例时就是扩展关系 │ │ │ │ └── 说明:如果一个用例明显地混合了两种或两种以上的不同场景,即根据情况可能发生多种事情,可以断定将这个用例分为一个主用例和一个或多个辅用例描述可能更加清晰 │ │ │ └── 泛化关系(Generalization) │ │ │ └── 举例:“电话注册”与“邮件注册”都属于“会员注册”,它们是“会员注册”的具体形式,所以存在父子关系,可判定为泛化关系 │ │ ├── 类图与对象图 │ │ │ ├── 类图:描述一组类、接口、协作和它们之间的关系,是面向对象设计的基础,不直接表示功能需求 │ │ │ ├── 对象图:描述一组对象及它们之间的关系,是类图所建立的事物实例的静态快照 │ │ │ └── 类的关系(按强度) │ │ │ ├── 依赖关系:一个事物发生变化影响另一个事物 │ │ │ ├── 关联关系:描述了一组链,链是对象之间的连接 │ │ │ │ ├── 聚合关系:整体与部分生命周期不同 │ │ │ │ └── 组合关系:整体与部分生命周期相同 │ │ │ ├── 实现关系:接口与类之间的关系 │ │ │ └── 泛化(继承)关系:特殊/一般关系 │ │ ├── 状态图 │ │ │ ├── 用于描述一个特定对象的所有可能状态及状态转换 │ │ │ └── 定义:定义对象的内部行为 │ │ ├── 活动图 │ │ │ ├── 用于描述系统的动态行为和控制流 │ │ │ ├── 适用于描述复杂算法的执行流程 │ │ │ └── 泳道式活动图:划分责任主体 │ │ ├── 序列图(顺序图) │ │ │ ├── 主要用于描述对象之间的交互顺序和时间流程 │ │ │ ├── 直观地表现各个对象发送、接收和处理消息的时间顺序 │ │ │ └── 组合片段 │ │ │ ├── Loop【循环】:如果满足"循环条件",则重复执行本框中的内容 │ │ │ ├── Alt【条件分支】:满足条件1则执行对应内容,满足条件2则执行对应内容 │ │ │ └── Opt【可选分支】:如果条件满足,则执行框中内容,否则跳过不执行 │ │ ├── 通信图(协作图) │ │ │ └── 强调对象之间存在的消息收发关系,而不专门突出这些消息发送的时间顺序 │ │ ├── 定时图 │ │ │ └── 展示交互过程中的真实时间信息,描述对象状态变化的时间点以及维持特定状态的时间段 │ │ ├── 构件图与包图 │ │ │ ├── 构件图:描述一个封装的类和它的接口、端口,以及由内嵌的构件和连接件构成的内部结构 │ │ │ └── 包图:把共同工作的元素放到一个文件夹中(如多个类或构件组成子系统) │ │ └── 部署图 │ │ └── 描述对运行时的处理节点及在其中生存的构件的配置 │ ├── 需求管理(基线建立后,进行全过程控制) │ │ ├── 需求管理是对需求基线进行管理 │ │ ├── (1) 变更控制 │ │ │ └── 需求变更申请、评估、批准、实施 │ │ ├── (2) 版本控制 │ │ │ └── 记录需求文档的版本历史 │ │ ├── (3) 需求跟踪 │ │ │ ├── 需求管理需要维持对用户原始需求和所有产品构建需求的双向跟踪 │ │ │ ├── ① 正向跟踪:检查《产品需求规格说明书》中的每个需求是否都能在后继工作成果中找到对应点 │ │ │ ├── ② 逆向跟踪:检查设计文档、代码、测试用例等工作成果是否都能在《产品需求规格说明书》中找到出处 │ │ │ ├── ③ 正向跟踪和逆向跟踪合称为“双向跟踪” │ │ │ ├── ④ 维持双向可追溯性 │ │ │ └── ⑤ 确保所有需求都被实现和验证 │ │ └── (4) 需求状态跟踪 │ │ └── 跟踪每个需求的状态(如:提议、已批准、已实现、已验证等) │ ├── 需求跟踪 │ │ └── 主要目的:建立与维护需求到产品实现过程的一致性 │ ├── 需求定义方法 │ │ ├── 严格定义方法 │ │ ├── 原型方法 │ │ └── 不适合使用严格定义方法的情况:需求不能在系统开发前被完全准确的说明 │ ├── 需求确认与验证 │ ├── 需求变更管理 │ │ ├── 变更控制委员会(CCB) │ │ │ ├── 性质:决策机构,不是作业机构 │ │ │ ├── 工作方式:通过评审手段来决定项目是否能变更,但不提出变更方案 │ │ │ ├── 组成:由项目所涉及的多方成员共同组成,通常包括用户和实施方的决策人员 │ │ │ ├── 职责:项目所有者权益代表,负责裁定接受哪些变更 │ │ │ ├── 说明:变更控制委员会对项目中任何基线工作产品的变更都可以做出决定 │ │ │ └── 决策过程 │ │ │ ├── 1. 制订决策 │ │ │ ├── 2. 交流情况 │ │ │ └── 3. 重新协商约定 │ │ │ └── 重新协商约定是决策过程的一部分 │ │ ├── 变更策略 │ │ │ ├── ① 所有需求变更必须遵循变更控制过程 │ │ │ ├── ② 对于未获得批准的变更,不应该做设计和实现工作 │ │ │ ├── ③ 变更应该由项目变更控制委员会决定实现哪些变更 │ │ │ ├── ④ 项目风险承担者应该能够了解变更数据库的内容 │ │ │ ├── ⑤ 决不能从数据库中删除或者修改变更请求的原始文档 │ │ │ └── ⑥ 每一个集成的需求变更必须能跟踪到一个经核准的变更请求 │ │ ├── 变更控制工具选择要点 │ │ │ ├── ① 可以定义变更请求的数据项 │ │ │ ├── ② 可以定义变更请求生存期的状态转换图 │ │ │ ├── ③ 可以加强状态转换图使经授权的用户仅能作出所允许的状态变更 │ │ │ ├── ④ 记录每一种状态变更的数据,确认作出变更的人员 │ │ │ ├── ⑤ 可以定义在提交新请求或请求状态被更新后应该自动通知的设计人员 │ │ │ └── ⑥ 可以根据需要生成标准的或定制的报告和图表 │ │ ├── 变更流程 │ │ │ ├── (1) 问题分析和变更描述 │ │ │ │ └── 识别和分析需求问题或者一份明确的变更提议,以检查它的有效性,从而产生一个更明确的需求变更提议 │ │ │ ├── (2) 变更分析和成本计算 │ │ │ │ └── 使用可追溯性信息和系统需求的一般知识,对需求变更提议进行影响分析和评估。变更成本计算应该包括对需求文档的修改、系统修改的设计和实现的成本。一旦分析完成并且被确认,应该进行是否执行这一变更的决策 │ │ │ └── (3) 变更实现 │ │ │ └── 这要求需求文档和系统设计以及实现都要同时修改。如果先对系统的程序做变更,然后再修改需求文档,这几乎不可避免地会出现需求文档和程序的不一致 │ │ └── 不正确描述:需求变更对软件项目开发有利无弊(×) │ └── 系统建模 │ ├── 结构化建模 │ │ ├── 关注点:过程/流程 │ │ ├── 核心理念:以“过程为中心”,把系统看作一系列“输入→处理→输出”的流程 │ │ ├── 强调内容:强调“做什么”、“怎么做” │ │ └── 典型工具:DFD(数据流图)、结构图、流程图 │ ├── 信息工程建模(数据库建模) │ │ ├── 关注点:数据/实体 │ │ ├── 核心理念:以“数据为中心”,先分析“系统需要存什么数据”,再围绕数据设计结构和关系 │ │ ├── 强调内容:强调“数据是什么”、“数据之间怎么关联” │ │ └── 典型工具:ER图(实体关系图)、数据字典、关系模型 │ ├── 面向对象建模 │ │ ├── 关注点:对象/行为+数据封装 │ │ ├── 核心理念:以“对象为中心”,把数据和操作打包成“对象”,模拟现实世界中的“事物及其行为” │ │ ├── 强调内容:强调“谁来做”、“怎么做”、“状态如何变化” │ │ └── 典型工具:UML(类图、用例图、顺序图、状态图等) │ └── MBSE(基于模型的系统工程) │ └── SysML(系统建模语言) │ └── 需求图 │ ├── 包含关系(Include):一个需求可以且只能包含其他需求 │ ├── 跟踪关系(Trace):对提供方元素的修改可能导致对客户方元素修改的需要(箭头从“因”指向“果”) │ ├── 继承关系(deriveReq):一个需求可以继承另一个需求的属性 │ ├── 改善关系(refine):表示一个需求改进了另一个需求的满足程度 │ ├── 满足关系(satisfy):一般是模块满足某种需求 │ ├── 验证关系(verify):表示一个需求验证了另一个需求的正确性 │ └── 复制关系(Copy):表示一个需求复制了另一个需求的特性 │ ├── 6️ 系统分析与设计 (★★) │ ├── 界面设计 │ │ ├── 黄金三法则 │ │ │ ├── 置于用户控制之下 │ │ │ ├── 减少用户的记忆负担 │ │ │ └── 保持界面的一致性 │ │ └── 原则 │ │ ├── 界面的视觉布局应该尽量与真实世界保持一致 │ │ ├── 所有可视信息的组织需要按照统一的设计标准 │ │ ├── 确保用户界面操作和使用的一致性 │ │ └── 错误描述:界面交互模型应经常进行修改(×) │ ├── 结构化设计 │ │ ├── 概要设计(外部设计):功能需求分配给软件模块,确定每个模块的功能和调用关系,形成模块结构图 │ │ ├── 详细设计(内部设计):为每个具体任务选择适当的技术手段和处理方法 │ │ ├── 结构化设计原则 │ │ │ ├── 模块独立性原则(高内聚、低耦合) │ │ │ ├── 保持模块的大小适中 │ │ │ ├── 深度和宽度均不宜过高 │ │ │ └── 多扇入、少扇出 │ │ ├── 内聚类型(从高到低) │ │ │ ├── 高内聚 │ │ │ │ ├── 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可 │ │ │ │ ├── 顺序内聚:处理元素相关,而且必须顺序执行 │ │ │ │ ├── 通信内聚:所有处理元素集中在一个数据结构的区域上 │ │ │ │ ├── 过程内聚:处理元素相关,而且必须按特定的次序执行 │ │ │ │ └── 时间内聚(瞬时内聚):所包含的任务必须在同一时间间隔内执行 │ │ │ └── 低内聚 │ │ │ ├── 逻辑内聚:完成逻辑上相关的一组任务 │ │ │ └── 偶然内聚(巧合内聚):完成一组没有关系或松散关系的任务 │ │ └── 耦合类型(从低到高) │ │ ├── 非直接耦合:两个模块之间没有直接关系,完全通过主模块的控制和调用来实现 │ │ ├── 数据耦合:一组模块借助参数表传递简单数据 │ │ ├── 标记耦合:一组模块通过参数表传递记录信息(数据结构) │ │ ├── 控制耦合:模块之间传递的信息中包含用于控制模块内部逻辑的信息 │ │ ├── 外部耦合:一组模块都访问同一全局简单变量,且不是通过参数表传递 │ │ ├── 公共耦合:多个模块都访问同一个公共数据环境 │ │ └── 内容耦合:一个模块直接访问另一个模块的内部数据;不通过正常入口转到另一个模块内部;程序代码重叠;一个模块有多个入口 │ └── 面向对象设计 │ ├── 基本过程 │ │ ├── 分析模型 │ │ │ ├── 用例模型 │ │ │ └── 领域模型 │ │ ├── 设计阶段 │ │ │ ├── 设计用例实现方案 │ │ │ ├── 设计技术支撑实施 │ │ │ ├── 设计用户界面 │ │ │ └── 细化设计模型 │ │ └── 设计模型 │ │ ├── 架构图(用包图表示) │ │ ├── 用例实现图(交互图) │ │ ├── 类图 │ │ └── 其他 │ │ ├── 状态图:用于描述复杂对象的状态变化,展现对象在不同事件下的状态转移过程 │ │ └── 活动图:用于描述流程化活动,展示工作流、业务流程或算法的执行步骤 │ ├── 类的分类 │ │ ├── 边界类:显示屏、窗体、打印机接口、通信协议、对话框、菜单、购物车、报表、二维码 │ │ ├── 控制类:身份验证器等 │ │ └── 实体类:学员类、课程类等 │ └── 面向对象设计原则 │ ├── 单一职责原则:设计目的单一的类 │ ├── 开放-封闭原则:对扩展开放,对修改封闭 │ ├── 李氏(Liskov)替换原则:子类可以替换父类。在运用里氏替换原则时,尽量将一些需要扩展的类或者存在变化的类设计为抽象类或者接口,并将其作为基类,在程序中尽量使用基类对象进行编程 │ ├── 依赖倒置原则:要依赖于抽象,而不是具体实现;针对接口编程,不要针对实现编程 │ ├── 接口隔离原则:使用多个专门的接口比使用单一的总接口要好 │ ├── 组合重用原则:要尽量使用组合,而不是继承关系达到重用目的 │ └── 迪米特(Demeter)原则(最少知识原则):一个对象应当对其他对象有尽可能少的了解 │ ├── 7️ 软件测试 (★★) │ ├── 软件测试的主要目的 │ │ ├── 确保软件质量:为软件质量模型的建立提供依据 │ │ ├── 发现错误:发现软件的错误 │ │ ├── 验证需求满足情况:验证软件是否满足技术要求 │ │ └── 局限性:软件测试不能保证发现所有的漏洞 │ ├── 软件调试与测试的区别 │ │ ├── ① 目的不同:测试的目的是找出存在的错误,而调试的目的是定位错误并修改程序以修正错误 │ │ ├── ② 活动顺序:调试是测试之后的活动,测试和调试在目标方法和思路上都有所不同 │ │ ├── ③ 起止条件:测试从一个已知的条件开始,使用预先定义的过程,有预知的结果;调试从一个未知的条件开始,结束的过程不可预计 │ │ └── ④ 过程可预测性:测试过程可以事先设计,进度可以事先确定;调试不能描述过程或持续时间 │ ├── 测试工具 │ │ ├── 说明:测试工具根据工作原理不同可分为静态测试工具和动态测试工具 │ │ ├── 静态测试工具 │ │ │ ├── 是对代码进行语法扫描,找到不符合编码规范的地方,根据某种质量模型评价代码的质量,生成系统的调用关系图等 │ │ │ ├── 直接对代码进行分析,不需要运行代码,也不需要对代码编译链接和生成可执行文件 │ │ │ └── 可用于对软件需求、结构设计、详细设计和代码进行评审、走审和审查,也可用于对软件的复杂度分析、数据流分析、控制流分析和接口分析提供支持 │ │ └── 动态测试工具 │ │ ├── 与静态测试工具不同,它需要运行被测试系统,并设置探针,向代码生成的可执行文件中插入检测代码 │ │ └── 可用于软件的覆盖分析和性能分析,也可用于软件的模拟、建模、仿真测试和变异测试等 │ ├── 测试类型 │ │ ├── 静态测试(人工监测和计算机辅助分析) │ │ │ ├── 说明:包括对文档的静态测试和对代码的静态测试 │ │ │ ├── 对文档的静态测试:主要以检查单的形式进行 │ │ │ ├── 对代码的静态测试:一般采用桌前检查(Desk Checking)、代码审查和代码走查 │ │ │ ├── 桌前检查 │ │ │ ├── 代码审查 │ │ │ ├── 代码走查 │ │ │ └── 静态分析内容 │ │ │ ├── 控制流分析:是否存在没有使用的语句/无法达到的语句/调用并不存在的子程序 │ │ │ ├── 数据流分析:引用未定义的变量、对以前未使用的变量再次赋值 │ │ │ ├── 信息流分析:找出输入变量和输出变量之间的依赖关系 │ │ │ ├── 接口分析:模块之间接口的一致性、子程序和函数之间的接口一致性、函数形参与实参的数量、顺序、类型的一致性 │ │ │ └── 表达式分析:括号不配对、数组引用越界、除数为零 │ │ ├── 动态测试(计算机运行) │ │ │ ├── 白盒测试法 │ │ │ │ ├── 核心特点:关注内部结构与逻辑,主要用于单元测试阶段 │ │ │ │ ├── 主要方法 │ │ │ │ │ ├── 控制流分析 │ │ │ │ │ ├── 数据流分析 │ │ │ │ │ ├── 路径分析 │ │ │ │ │ ├── 程序变异 │ │ │ │ │ └── 错误驱动测试 │ │ │ │ └── 覆盖强度(按递增排列) │ │ │ │ ├── 说明:按递增排列不代表覆盖能力的强弱,只代表用例设计的精细程度 │ │ │ │ ├── 覆盖标准对比表 │ │ │ │ │ ├── 判定覆盖 │ │ │ │ │ │ ├── 核心关注点:整个(A且B)的最终结果(真/假) │ │ │ │ │ │ ├── 含义:要求测试用例中,至少有一次整个表达式结果为真,至少有一次结果为假 │ │ │ │ │ │ └── 最低要求:2个用例 │ │ │ │ │ ├── 条件覆盖 │ │ │ │ │ │ ├── 核心关注点:每个原子条件(A和B)的可能取值(真/假) │ │ │ │ │ │ ├── 含义:要求测试用例中,A至少要有一次为真、一次为假;B也至少要有一次为真、一次为假 │ │ │ │ │ │ └── 最低要求:2个用例 │ │ │ │ │ ├── 判定/条件覆盖 │ │ │ │ │ │ ├── 核心关注点:同时满足上述两者 │ │ │ │ │ │ ├── 含义:既要有结果为真和假的用例,又要让A和B的真假都出现过 │ │ │ │ │ │ ├── 最低要求:通常2个用例(需精心设计) │ │ │ │ │ │ └── 缺点:未考虑条件的组合情况 │ │ │ │ │ └── 条件组合覆盖 │ │ │ │ │ ├── 核心关注点:所有原子条件取值的所有可能组合 │ │ │ │ │ ├── 含义:要求覆盖A和B取值的全部4种组合:(真,真)、(真,假)、(假,真)、(假,假) │ │ │ │ │ └── 最低要求:4个用例 │ │ │ │ ├── 判定覆盖与条件覆盖的对比 │ │ │ │ │ └── 与判定覆盖相比,条件覆盖增加对符合判定情况的测试,增加了测试路径 │ │ │ │ ├── 语句覆盖:确保每条语句至少执行一次 │ │ │ │ ├── 判定覆盖:确保每个判断条件的两种结果(真和假)都至少出现一次 │ │ │ │ ├── 条件覆盖:确保每个条件的两种结果(真和假)都至少出现一次 │ │ │ │ ├── 判定覆盖与条件覆盖的区别 │ │ │ │ │ └── 判断覆盖是整体看,条件覆盖是从局部看 │ │ │ │ ├── 条件/判定覆盖 │ │ │ │ │ └── 同时满足判定覆盖和条件覆盖的逻辑覆盖称为判定/条件覆盖 │ │ │ │ ├── 条件组合覆盖 │ │ │ │ │ ├── 选取足够的测试用例,使得每个判定表达式中条件结果的所有可能组合至少出现一次 │ │ │ │ │ └── 满足条件组合覆盖必然满足判定/条件覆盖 │ │ │ │ ├── 路径覆盖:确保程序中所有可能的执行路径至少执行一次 │ │ │ │ └── 路径覆盖与语句覆盖的关系 │ │ │ │ └── 路径覆盖包含所有语句的执行,因此路径覆盖可以代替语句覆盖 │ │ │ ├── 黑盒测试法 │ │ │ │ ├── 核心特点:关注输入输出及功能,不关注内部逻辑,仅依据需求规格设计用例 │ │ │ │ ├── 主要根据程序外部功能来设计测试用例 │ │ │ │ ├── 测试软件的外部特性 │ │ │ │ ├── 功能测试属于黑盒测试 │ │ │ │ └── 主要方法 │ │ │ │ ├── 等价类划分:将输入域划分为有效/无效等价类,每类选代表值设计用例,覆盖典型与异常场景 │ │ │ │ ├── 边界值分析:聚焦输入/输出的边界点(含刚好超出边界的值),是发现错误的高发区 │ │ │ │ ├── 因果图法:从自然语言需求中提取输入条件(因)与输出结果(果),转化为判定表,再设计用例 │ │ │ │ ├── 正交试验法:利用正交表组合多因素多水平,用最少数目用例实现最大覆盖,适合参数组合复杂场景 │ │ │ │ ├── 判定表(决策表):系统分析输入条件的各种组合及对应输出 │ │ │ │ └── 错误推测法(补充):基于经验或直觉猜测可能出错点,补充其他方法未覆盖的角落情况 │ │ │ └── 灰盒测试法:介于两者之间,结合了黑盒和白盒测试的特点,既关注输入输出的正确性,又考虑内部逻辑,但不像白盒测试那样详细 │ │ └── 自动化测试 │ │ ├── 先写脚本→自动化执行 │ │ ├── 不适合场景:项目周期短,需求变动频繁 │ │ ├── 常见类型 │ │ │ ├── 单元自动化测试 │ │ │ ├── 接口自动化测试 │ │ │ └── UI自动化测试 │ │ ├── 脚本技术说明 │ │ │ └── 当前流行的自动化测试工具主要使用脚本技术来生成测试用例 │ │ └── 脚本的基本结构 │ │ ├── 线性脚本 │ │ │ └── 是录制手工测试的测试用例时得到的脚本,这些脚本是未做修改的 │ │ ├── 结构化脚本 │ │ │ └── 具有各种逻辑结构,包括选择型结构、分支结构、循环迭代结构,而且具有函数调用功能。结构化脚本具有很好的可用性和灵活性,易于维护 │ │ ├── 共享脚本 │ │ │ └── 是指一个脚本可以被多个测试用例使用,即脚本语言允许一个脚本调用另一个脚本 │ │ ├── 数据驱动脚本 │ │ │ └── 是指将测试输入存储在独立的数据文件中,而不是脚本中。这样,脚本可以针对不同的数据输入实现多个测试用例 │ │ └── 关键字驱动脚本 │ │ └── 是数据驱动脚本的逻辑扩展,它用测试文件描述测试用例,它说明测试用例做什么,而不是如何做。关键字驱动脚本允许使用描述性的方法,只需要提供测试用例的描述,即可生成测试用例 │ ├── 测试阶段 │ │ ├── 单元测试 │ │ │ ├── 依据:【详细设计】 │ │ │ ├── 内容:模块测试,模块功能、性能、接口等 │ │ │ ├── 执行者:程序员 │ │ │ ├── 测试方法:采用白盒测试法 │ │ │ └── 面向对象系统的单元测试 │ │ │ ├── 说明:包括方法层次的测试、类层次的测试和类树层次的测试 │ │ │ ├── (1) 方法层次的测试 │ │ │ │ ├── 类似于传统软件测试中对单个函数的测试 │ │ │ │ └── 常用测试技术:等价类划分测试、组合功能测试、递归函数测试和多态消息测试等 │ │ │ ├── (2) 类层次的测试 │ │ │ │ └── 主要包括:不变式边界测试、模态类测试和非模态类测试 │ │ │ └── (3) 类树层次的测试 │ │ │ └── 主要包括:多态服务测试和展平测试 │ │ ├── 集成测试 │ │ │ ├── 依据:【概要设计】 │ │ │ ├── 内容:模块间的接口 │ │ │ ├── 重点关注:模块间接口问题 │ │ │ ├── 测试方法:采用白盒和黑盒结合的方法 │ │ │ └── 集成测试策略 │ │ │ ├── 一次性组装【风险高】 │ │ │ └── 增量式组装【测试全面】 │ │ │ ├── 自顶向下【需要桩模块】 │ │ │ ├── 自底向上【需要驱动模块】 │ │ │ └── 混合式【桩模块和驱动模块都需要】 │ │ ├── 系统测试 │ │ │ ├── 依据:【需求文档】 │ │ │ ├── 内容:包括功能测试、性能测试、验收测试、压力测试、恢复测试、安全测试、可用性测试、可维护性测试、安装测试等 │ │ │ ├── 目的:检查系统是否符合软件需求 │ │ │ └── 测试方法:采用黑盒测试法 │ │ ├── Alpha测试 │ │ │ └── 是在开发环境下进行的测试,由用户/内部用户模拟实际操作环境下进行的受控测试 │ │ ├── Beta测试 │ │ │ ├── 是用户在实际使用环境下进行的测试 │ │ │ └── Beta测试不能由程序员或测试员完成,因而是在开发者无法控制的环境下进行的软件现场应用 │ │ ├── 验收测试 │ │ │ ├── 目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务 │ │ │ └── 是向未来的用户表明系统能够像预定要求那样工作 │ │ ├── 回归测试 │ │ │ ├── 目的是测试软件变更之后,变更部分的正确性和对变更需求的符合性,以及软件原有的、正确的功能、性能和其它规定的要求的不损害性 │ │ │ └── 确保修正过程中没有引入新的缺陷 │ │ └── 确认测试:依据【需求文档】,验证软件与需求的一致性 │ │ ├── 内部确认测试 │ │ ├── Alpha测试 │ │ ├── Beta测试 │ │ └── 验收测试 │ ├── 其他测试描述 │ │ ├── AB测试:多版本同时使用,利于收集各版本的用户反馈,评估出最好版本,也是一种网页优化方法 │ │ ├── 金丝雀测试(渐进式部署) │ │ ├── Web测试 │ │ │ ├── Web代码测试:源代码规则分析、链接测试、框架测试、表格测试、图形测试等方面 │ │ │ └── 链接测试 │ │ │ ├── 测试所有链接是否按指示链接到该链接的页面 │ │ │ ├── 测试所链接的页面是否存在 │ │ │ └── 保证没有孤立的页面 │ │ ├── 表单测试:验证服务器能否正确保存数据,后台程序能否正确解释和使用这些信息;测试提交操作的完整性 │ │ └── 回归测试:测试软件变更之后,变更部分的正确性和对变更需求的符合性 │ └── 性能测试 │ ├── 负载测试:各种工作负载下系统的性能 │ ├── 压力测试【测上限】:系统的瓶颈或不能接受的性能点 │ ├── 负载测试和压力测试的关系 │ │ └── 负载测试和压力测试可以结合进行,统称为负载压力测试 │ ├── 强度测试【测下限】:系统资源特别低的情况下运行 │ ├── 容量测试【并发测试】:同时在线的最大用户数 │ ├── 可靠性测试:MTTF之类的参数 │ ├── 恢复测试:监测系统的容错能力。检测方法是采用各种方法让系统出现故障,检验系统是否按照要求能从故障中恢复过来 │ ├── 安装测试:在安装软件系统时,会有多种选择。安装测试就是为了检测在安装过程中是否有误、是否容易操作等 │ ├── 健壮性测试 │ ├── 用户界面测试 │ ├── 安全性测试 │ └── 安装与反安装测试 │ ├── 8️ 系统运行与软件维护 (★) │ ├── 遗留系统与系统转换计划 │ │ ├── 遗留系统演化策略 │ │ │ ├── 淘汰:左下角(低水平、低价值) │ │ │ ├── 继承:右下角(低水平、高价值),因为业务还在依赖,新系统需要兼容老系统的功能模型和数据模型 │ │ │ ├── 改造:右上角(高水平、高价值),系统功能增加和数据模型改造 │ │ │ └── 集成:左上角(高水平、低价值),信息孤岛导致的低价值 │ │ └── 新旧系统的转换策略 │ │ ├── 直接转换策略:在某一时刻立即停用旧系统、启用新系统,风险高但成本低、周期短,适用于简单系统 │ │ ├── 并行转换策略:新旧系统同时运行一段时间以对比验证,风险小但资源消耗大、管理复杂 │ │ └── 分段转换策略:将系统分模块逐步替换,风险适中、用户易接受,但整体转换周期较长 │ └── 软件维护 │ ├── 软件维护类型 │ │ ├── 正确性维护(改正型维护)【修BUG】:识别和纠正软件错误/缺陷,测试不可能发现所有错误 │ │ ├── 适应性维护【应变】:使应用软件适应环境变化(外部环境、数据环境)而进行的修改 │ │ ├── 完善性维护【新需求】:扩充功能和改善性能而进行的修改,是软件维护工作的主要部分 │ │ └── 预防性维护【针对未来】:为了适应未来的软硬件环境的变化,主动增加预防性的新的功能,以使系统适应各类变化而不被淘汰(经典实例:专用改通用) │ ├── 软件维护内容详细说明 │ │ ├── 改正性维护:指改正在系统开发阶段已发生而系统测试阶段尚未发现的错误 │ │ ├── 适应性维护:指使应用软件适应信息技术变化和管理需求变化而进行的修改 │ │ ├── 完善性维护:是为扩充功能和改善性能而进行的修改,主要是指对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征 │ │ └── 预防性维护:是为了改进应用软件的可靠性和可维护性,为了适应未来的软/硬件环境的变化,应主动增加预防性的新的功能,以使应用系统适应各类变化而不被淘汰 │ └── 软件可维护性影响因素 │ ├── 可理解性:指通过阅读代码和文档,理解软件功能与运行方式的难易程度 │ ├── 可修改性:指对软件进行修改的难易程度 │ ├── 可测试性:指验证软件程序正确性的难易程度 │ ├── 可靠性:软件可靠性越高,需要维护的概率越低 │ └── 可移植性:指软件从一个环境迁移到另一个环境后仍能正常运行的难易程度 │ ├── 9️ 软件生命周期支持活动 (★) │ ├── P(Plan):计划阶段 │ ├── D(Do):执行阶段 │ ├── C(Check):检查阶段 │ │ └── 主要涉及软件确认,即确认开发的软件能够满足用户的需求 │ └── A(Action):行动阶段 │ ├── 10️ 软件开发环境(SDE)(★) │ ├── 定义:软件开发环境是指支持软件的工程化开发和维护而使用的一组软件,由软件工具集和环境集成机制构成 │ ├── 构成:软件工具集 + 环境集成机制 │ ├── 集成机制说明:软件开发环境应支持多种集成机制。根据功能不同,可以将集成机制分为三个部分 │ ├── 环境集成机制包含三个核心部分 │ │ ├── 环境信息库(核心):存储开发过程中产生的信息(如文档)及环境支持信息(如模板、构件) │ │ ├── 过程控制与消息服务器:实现过程集成(按流程组合工具)和控制集成(工具间协同通信) │ │ └── 环境用户界面:提供统一、一致的界面,便于高效使用工具 │ │ └── 说明:统一的、具有一致性的用户界面是软件开发环境的重要特征,是充分发挥环境的优越性、高效地使用工具并减轻用户学习负担的保证 │ └── 软件工具分类 │ ├── 通常可以按软件过程活动将软件工具分为:软件开发工具、软件维护工具、软件管理和软件支持工具 │ ├── 软件开发工具概述:软件开发工具旨在辅助软件开发过程中的各种活动,从需求分析、设计、编码、测试到维护。根据它们支持的开发阶段和功能,这些工具可以被分类为编程工具、设计工具、测试工具、建模工具等 │ ├── 软件开发工具 │ │ ├── 需求分析工具 │ │ ├── 设计工具 │ │ └── 编码与排错工具 │ ├── 建模工具 │ │ ├── 专门用于辅助建立软件系统的抽象模型的工具。这类工具支持软件工程师在设计阶段创建和编辑系统架构、类图、序列图、活动图等各种模型,以可视化的方式表达软件系统的结构和行为 │ │ └── 常见建模工具:Rose、Together、WinA&D、QuickUML │ ├── 软件维护工具 │ │ ├── 版本控制工具 │ │ ├── 文档分析工具 │ │ ├── 开发信息库工具 │ │ ├── 逆向工程工具 │ │ └── 再工程工具 │ └── 软件管理和软件支持工具 │ ├── 项目管理工具 │ ├── 配置管理工具 │ ├── 软件评价工具 │ └── 软件开发工具的评价和选择 │ └── 11️ 补充章节 (★) └── CMM能力成熟度模型 ├── 定义:CMM(Capacity Maturity Model)是用来指导软件过程改进的 ├── 应用:软件能力成熟度模型(CMM)在软件开发机构中被广泛用来指导软件过程改进 ├── 描述:该模型描述了软件处理能力的5个成熟级别 └── 第二级要求:为了达到过程能力成熟度模型的第二级,组织机构必须具有6个关键过程域KPA(Key Process Areas)