文章目录
ch.1 软件工程概述
- 软件=程序+数据+文档
- 软件危机:在计算机软件的开发和维护过程中所遇到的一系列严重问题。
- 软件工程是 ① 将系统性的、规范化的、可定量的方法应用于软件的开发、运行和维护,即工程化应用到软件上;② 对①中所述方法的研究。------IEEE【IEE93】
- 软件工程的目标:
- 软件工程的基本要素:方法、过程、工具 (前三个成为软工的三个方面)、范型(构造软件的特定方法或风格,比如面向服务、面向对象、面向过程等等)
- 软件工程的过程:问题定义——需求开发——软件设计——软件实现——软件测试
ch.2 软件过程
是什么?
为了获得高质量软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。描述了 who、when、what、how,用以实现某一个特定的具体目标。
2.1 软件生命周期
2.1.1 是什么?从考虑概念开始,到交付使用,到最终退役为止的整个过程。
2.1.2 各时期的任务:
(1)软件定义时期的任务:确定必须完成的总目标;确定工程的可行性;确定完成目标的总策略和必须完成的功能; 估计资源、成本;制定工程进度表。 (分为 3 个阶段:问题定义,可行性研究,需求分析);
(2)软件开发时期的任务:把用户的要求转变为软件产品。包括:把需求转换成设计,把设计用代码实现,测试该 代码,有时还要进行代码安装和交付运行。这些活动可以重叠,执行时也可迭代 (分为 4 个阶段:系统设计{总体设计(概要设计),详细设计},系统实现{编码和单元测试,综合测试)};
(3)运行维护时期的任务:使软件持久地满足用户的需要;
2.2 软件过程
2.2.1 软件过程模型
传统
-
瀑布模型:理想的线性开发模式,缺乏灵活性
在软件开发初期就确定完整的需求很难。 -
原型模型:做一个“样机”(也叫原型,软件早期可运行的版本)给客户看,征求意见
用户参与,风险降低;大型项目的原型难构建。 -
增量模型:每开发一部分,向用户展示一部分
开发周期小,降低风险; -
螺旋模型:使用原型及其他方法来尽量降低风险 可看作是在每个阶段之前都增加了风险分析过程的快 速原型模型。 强调版本和版本升级。
适用范围:主要适用于内部开发的大规模软件项目。支持 需求不明确的大型软件系统的开发,并支持面 向规格说明、面向过程、面向对象等多种软件 开发方法,是一种具有广阔前景的模型。 -
喷泉模型:各个开发阶段没有特定的次序要求,并且可以交互进 行,可以在某个开发阶段中随时补充其他任何开发阶 段中的遗漏。该模型认为软件开发过程自下而上周期的各阶段是相 互重叠和多次反复的,就像水喷上去又可以落下来, 类似一个喷泉。
效率高,节约时间;不易于管理。
现代
- 基于构件:考虑的重点的集成,而非实现构件
- 统一过程(统一过程 Rational Unified Process,RUP)模型:使用同一建模语言UML( Unified Modeling Language)
- 敏捷开发
ch.3 可行性分析
- 可行性研究的目的:用最小的代价在尽可能短的时间内研究并确定客户提出的问题是否有行得通的解决办法。
- 可行性分析是系统分析师的工作。
- 可行性研究从以下四个方面进行:
技术可行性:做得了吗?做得好吗?做得快吗?
经济可行性:这个系统的经济效益能超过它的开发成本吗?
操作可行性:系统的操作方式在这个用户组织内行得通吗?
社会可行性:法律、道德、社会影响力
ch.4 需求工程
-
软件工程的子领域
-
需求工程的定义:应用已证实有效的技术、方法进行需求分析,确定客户需求,帮助分析人员理解问题并定义目标系统的所有外部特征的一门学科。
-
任务:最终形成一份经开发方和用户认可或达成共识的软件需求规格说明书
-
内容
需求分析的模型概述
分层数据流图:
step1 顶层图:系统的输入和输出
step2 0层图:系统内部
step3 加工内部
例子:考试管理系统
顶层图
0层图:
加工1(考试报名):
加工2(统计成绩):
数据字典
由不同的数据条目组成,而数据条目是对数据流图中的不同组成元素(源和宿、数据流、加工、文件)的说明
- 行为模型:状态转换图(STD)
ch5.面向过程(结构化)的软件设计
- 软件设计的基本目的是解决 系统应该如何实现 这个问题
- 结构化开发方法:系统按功能要求分为若干子功能模块,子模块又进一步分解为若干个子子模块,循此进行,从上往下进行功能分解。分解的结果将逐层地产生一系列的功能模块,随着分解的层次由高到低的发展,模块功能是逐层地由抽象变得具休,由综合变得单一。
- 过程:结构化分析的结果——>概要设计——>详细设计——>设计复审——>软件设计文档,需求分析模型——>设计模型
- 软件分析的目标: 系统分析——做什么?——逻辑模型, 系统设计——怎么做?——物理模型
- 结构化软件设计的任务: 体系结构设计(定义软件模块间的关系),接口设计,数据设计,过程设计,前两个称为概要设计,后两个称为详细设计
- 概要设计:主要任务是将数据流图映射为软件系统结构图
- 详细设计:对概要设计的每一个模块进行数据设计和过程设计
软件设计的基本原则:
- 模块化
(1)概念:解决一个复杂问题时,自顶向下逐层把软件划分成若干模块的过程
(2)目标:模块独立性
(3)衡量模块独立性的两个准则:
内聚: 模块内部各成分之间的联系,也称块内联系或模块强度
耦合: 一个模块与其它模块之间的联系,也称为块间联系
🔥内聚性最高的是功能内聚。非直接耦合的模块独立性最强!
(4)模块的独立性高:块内联系强,块间联系弱,追求高内聚,低耦合
(5)好处:每一模块的设计、测试和维护相对独立。模块间的联系少,错误的传播也少。耦合增加了系统的可理解性、可测试性、可靠性和可维护性。 - 抽象
忽略细节,分层理解问题,自顶向下层层细化,包括对过程、数据和控制的抽象。 - 逐步求精
求精实际是一个详细描述的过程。 - 信息隐蔽
在设计和确定模块时,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不可访问的。
数据流图映射到软件结构图
- 结构化设计方法把数据流图映射为软件结构图,数据流的类型决定了映射的方法.数据流有两种类型:变换型,事务型.
- 变换性:由输入、变换中心、输出组成。
- 事务型:数据沿输入通路到达一个处理 T,这个处理根据输入数据的类型在若干个动作序列中选出一个来执行。处 理 T 称为事务中心,它完成以下任务:
(1) 接收输入数据(输入数据又称为事务)。
(2) 分析每个事务以确定它的类型。
(3) 根据事务类型选取一条动作路径。
模块分解的启发式规则
4. 模块大小适当:经验表明,一个模块的规模不应过大,通常规定其语句行数为50~100 行,最多不超过500 行。
5. 深度、宽度、扇入、扇出适当
6. 尽可能减少高扇出结构,随着深度增大扇入。如果一个模块的扇出数过大,就意味着该模块过分复杂,需要协调和控制过多的下属模块。应当适当增加中间层次的控制模块。
7. 模块的作用域应在控制域之内
(1)模块的作用域:受该模块内一个判定影响的所有模块的集合。
(2)模块的控制域:这个模块本身以及所有直接或间接从属于它的模块的集合。
详细设计
- 详细设计就要对软件结构中的每一个模块确定使用的算法或块内数据结构,并用某种选定的表达工具给出清晰的描述。
- 详细设计的表达工具
程序流程图
盒图
PAD 图
PDL
IPO 图
ch.6 面向对象方法基础:介绍和UML
-
面向对象=对象 + 类 + 消息 + 继承 + 多态
-
比较面向对象对象开发方法与结构化开发方法(面向过程)的异同:
面向过程:“怎样做”,着重功能分解,面向对象:“是什么”,着重建立对象模型。面向过程侧重线,面向对象侧重点。面向过程优点是简单、实用,适合于数据处理领域,缺点是不适应大型规模、复杂的项目,难以解决软件重用,难以适应需求变化,难以解决维护问题。面向对象方法更容易获得符合用户需求、可靠的、适应性强的系统。 -
三大特性是:封装,继承,多态
-
五大基本原则
- 单一职责原则SRP(Single Responsibility Principle)
是指一个类的功能要单一,不能包罗万象。如同一个人一样,分配的工作不能太多,否则一天到晚虽然忙忙碌碌的,但效率却高不起来。- 开放封闭原则OCP(Open-Close Principle)
一个模块在扩展性方面应该是开放的而在更改性方面应该是封闭的。比如:一个网络模块,原来只服务端功能,而现在要加入客户端功能,
那么应当在不用修改服务端功能代码的前提下,就能够增加客户端功能的实现代码,这要求在设计之初,就应当将服务端和客户端分开,公共部分抽象出来。- 替换原则(the Liskov Substitution Principle LSP)
子类应当可以替换父类并出现在父类能够出现的任何地方。比如:公司搞年度晚会,所有员工可以参加抽奖,那么不管是老员工还是新员工,
也不管是总部员工还是外派员工,都应当可以参加抽奖,否则这公司就不和谐了。- 依赖原则(the Dependency Inversion Principle DIP) 具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,
这个时候,B不应当直接使用A中的具体类: 而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口:这样就达到
了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。一个常见的问题就是编译A模块时需要直接包含到B模块的cpp文件,而编译B时同样要直接包含到A的cpp文件。- 接口分离原则(the Interface Segregation Principle ISP)
模块间要通过抽象接口隔离开,而不是通过具体的类强耦合起来
UML建模工具
Unified Modeling Language(统一建模语言)是对象管理组织(OMG)制定的一个通用的、可视化的建模语言标准,可以用来可视化(visualize) 、描述(specify)、构造(construct)和文档化(document)软件密集型系统的各种工件(artifacts,又译制品)。
事务:
- 结构事物:类,接口,协作,用例,活动类,组件,节点
- 行为事物:交互,状态机
- 分组事务:包
- 注释事务:注释
关系:
- 关联:关联两端的类可以某种角色参与关联,关联有二元关联(binary)、三元关联
(ternary)、多元关联(higher order)。
关联类(不重要):OO建模的一个普遍问题是,当类之间具有多对多关系时,一些属性不能容易地放人任何一个类中。例如,下图所示的公司与员工的类关系。
- 依赖
在UML2.0中的依赖种类如下:Access(访问), bind(绑定 ) , call( 调 用 ) , create( 创 建 ) , derive( 派 生 ) ,instantiate( 实例化 ) , permit( 允 许 ) , realize( 实 现 ) ,refine(精化),send(发送),substitute(替换),trace(追踪依赖),use(使用)。- 聚合和组合
聚合(Aggregation)是一种特殊形式的关联,它表示类之间的整体与部分的关系,组合(Composition)是一种特殊形式的聚集,组合关系中的整体与部分具有同样的生存期。
- 泛化:泛化指出类间的“一般——特殊关系”
5. 实现
图
(1)是什么?说明和定义软件系统的功能需求,从系统外部观看系统功能,并不描述系统内部对功能的具体实现,展现一组用例、参与者及其它们之间的关系。
(2)用例之间的关系:
泛化:一个用例描述的执行场景是另一个用例描述的执行场景的特例;
包含:一个用例描述的执行场景是另一个用例所描述的场景中的一步;
扩展:一个用例描述的执行是对另一用例所描述的执行场景的扩展;
用例之间的包含关系:一个用例是对另一个用例描述的活动序列的某个活动
的细化
-
类图
展示系统中的类、类的属性和操作、以及类与类之间的关系(关联、依赖、聚合等)
类图怎么画?名称、属性、操作
类图的可视性标记:“+”:公共,可以被外部对象访问。“#”:保护,可以被本类或子类的对象访问。“-”:私用:不可以被外部对象访问,只能为本类的对象使用
派生:另一种可以为属性提供的信息是派生值,它可以使用数学函数、字符串函数或者将要在应用程序中实现的其他商务逻辑。 要想指出一个属性是派生的,需要在属性名之前添加一个前斜线(/), 并且要附加一个注释,其中包含了派生属性值的指令。 -
序列图:
ch.7 面向对象分析
-
是什么?找出并规定该问题域中根据系统各项要求而行动并相互作用的对象,并依据这些对象及其关系建立问题域模型。
-
步骤:
第一步:用例建模
建立软件系统的用例模型,用例图+用例描述
用例图:(用例图详细内容看ch.6)
用例描述:
第二步:对象建模
-
理解用例描述
-
识别类和类的属性(怎么识别?分析类)
三种分析类
👌边界类:描述与参与者直接打交道的对象,一般是一些UI界面
👌控制类:描述系统的行为,即系统做什么
👌实体类:描述系统的中的数据信息(有些数据是实体类,而有些是实体类的属性)
-
识别类的操作(怎么识别?为用例建立顺序图)
-
确定类与类之间的关系
-
评审
建立软件系统的静态结构模型,类图
第三步:动态建模
描述系统的行为
第四步:评审
面向对象建模考试不会考,暂时停滞在这里,以后有机会的话再来补充。
ch.8 软件体系结构与设计模式
不考,不总结了
上课pdf
🔥
设计模式是一套被人反复使用、多数人知晓、经过分类编目的、代码设计经验的总结,描述了软件系统设计过程中常见问题的一些解决方案,通常是从大量的成功实践中总结出来的且被广泛公认的实践和知识,描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案
使用设计模式,我们就能一次一次地利用已有方案而不必做重复劳动
更重要的是可以使我们更加深刻地理解面向对象的设计思想,非常有利于我们更好地使用面向对象语言解决设计中的问题。
ch.9 用户界面设计与软件实现
本节所处的地位:
不考,不总结了
上课pdf
ch.10 软件测试与维护
- 测试技术:关注于如何测试,即采用什么方法测试软件;测试策略:关注于如何组织测试,即采用了某一个技术之后,应该采取了什么样的过程来测试
- 测试技术:
从是否关心软件内部结构和具体实现的角度:
黑盒测试、白盒测试
从是否执行程序的角度:
静态测试、动态测试 - 黑盒测试: 完全不考虑程序的内部结构和处理过程,只知道软件产品应该具有的功能,通过测试检验每个功能是否都能正常使用。又称为功能性测试或行为测试。
- 白盒测试: 有时称为透明盒测试,已知产品内部工作过程,通过测试检验产品内部动作是否按照产品规格说明的规定正常进行。
- 静态测试:是指不运行被测程序本身,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性。
- 动态测试:是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能。
- 什么是维护
在软件交付使用后对其进行的修改,以纠正故障,改善性能,使产品适应改变了的环境。
目的:就是保证软件系统能持续地与用户环境、数据处理操作相协调,最终使系统稳定运行。 - 软件维护的分类:纠错性维护、适应性维护、完善性维护、预防性维护
- 面向对象的集成测试重点在于发现不同类之间的协作错误。
- 确认测试目的:验证软件的有效性,即验证软件的功能和性能及其他特性是否符合用户要求。
- 系统测试:测试软件系统是否能与硬件协调工作,测试与其他软件协调运行的情况。
- 单元测试:单元测试也称模块测试,是针对软件设计的最小单元程序模块进行测试的工作。其目的是发现模块内部的软件缺陷,修改这些缺陷使其代码能够正确运行。
- 代码覆盖技术
(1)是什么?属于动态白盒的测试内容。测试程序的状态以及程序流程,设法进入和退出每一个模块,执行每一行的代码,进入软件的每一条逻辑和决策分支。
(2)包括:语句覆盖,分支覆盖,条件覆盖
(3)满足分支覆盖一定满足语句覆盖。
ch.11 敏捷开发
不考,不总结了
上课pdf