软工
第一章 软件的本质
软件
软件是:
- 指令的集合(计算机程序),通过执行这些指令可以满足预期的特性、功能和性能需求;
- 数据结构,使得程序可以合理利用信息;
- 软件描述信息,它以硬拷贝和虚拟形式存在,用来描述程序的操作和使用。
软件的特点:
- 功能性:一组功能及其指定的性质有关的一组属性。适合性、准确性、互用性/互操作性、依从性、安全性。
- 可靠性:在规定的一段时间和条件下,软件维持其性能水平有关的一组软件属性。成熟性、容错性、易恢复性。
- 可用性:与使用的难易程度及规定或隐含用户对使用方式所做的评价有关的软件属性。易理解性、易学性、易操作性。
- 效率:在规定条件下,软件的性能水平和所有资源之间的关系有关的一组软件属性。时间特性、资源特性。
- 可维护性:与进行指定的修改所需的努力有关的一组软件熟悉。易分析性、可修改性、稳定性、可测试性。
- 可一致性:与软件可从某一环境转移到另一环境的能力有关的一组软件属性。适应性、易安装性、一致性(遵循性)、可替换性。
软硬件的区别:
- 软件是开发设计的,不是生产制造的。
- 软件不会磨损,但会退化。不断的变更是软件退化的根本原因。硬件会磨损,磨损的部分可以用备用的构建替换,而软件却不存在备用构件。
- 虽然整个工业向着基于构件的构造模型发展,然而大多数的软件还是主要采用用户定制的方式。在硬件设计中,构件复用是工程进程中通用的方法。而在软件设计中,大规模的复用还刚刚开始尝试。
软件的变更本质
四大类软件不断演化,在行业中占有主导地位。
- WebApp
- 移动App
- 云计算
- 产品线软件
第二章 软件工程
软件工程 - 一种层次化的技术
软件工程的定义:
(1)将系统化的、规范化的、可量化的方法应用于软件的开发、运行和维护,即将工程化方法应用于软件;
(2)对(1)中所述方法的研究。
软件工程的目的
在给定成本、进度的前提下,开发出具有适用性、有效性、可修改性、可靠性、可理解性、可维护性、可重用性、可移植性、可追踪性、可互操作性和满足用户需求的软件产品。
Layer
- 质量关注点:支持软件工程的根基
- 过程:软件工程的基础
- 方法:为构建软件提供技术上的解决方法(如何做)。
- 工具:为过程和方法提供自动化或半自动化的支持。
过程框架
过程框架定义了若干个框架活动,为实现完整的软件工程过程定义了基础。
一个通用的软件工程过程框架通常包含以下5个活动:
- 沟通 / communication
- 策划 / planning
- 建模 / modeling
- 构建 / construction
- 部署 / deployment
普适性活动(umbrella activities)
软件工程过程框架活动由很多普适性活动来补充实现。通常,这些普适性活动贯穿软件项目始终,以帮组软件团队管理和控制项目进度、质量、变更和风险。
典型的普适性活动:
- 软件项目跟踪和控制 — 项目组根据计划来评估项目进度,并且采取必要的措施保证项目按进度计划进行。
- 风险管理 — 对可能影响项目成果或者产品质量的风险进行评估。
- 软件质量保证 — 确定和执行保证软件质量的活动。
- 技术评审 — 确定和执行保证软件质量的活动。
- 测量 — 定义和收集过程、项目以及产品的度量,以帮组团队在发布软件时满足利益相关者的要求。
- 软件配置管理 — 在整个软件过程中管理变更所带来的影响。
- 可复用管理 — 定义工作产品复用的标准(包括软件架构),并且建立构件复用机制。
- 工作产品的准备和生产 — 包括生成产品(如建模、文档、日志、表格和列表等)所必需的活动。
软件开发神话
软件开发神话,即关于软件及其开发过程中的一些被人盲目相信的说法。
- 管理神话
- 客户神话
- 从业者神话
第三章 软件过程结构
Prescriptive models
瀑布模型
瀑布模型又称为经典生命周期(classic life cycle),它提出了一个系统的、顺序的软件开发方法,从用户需求规格说明开始,通过策划、建模、构建和部署的过程,最终提供完整的软件支持。
· 按照过程框架线性开发
适用于需求清楚、熟悉的系统。
不足之处:
- 实际的项目很少遵守瀑布模型提出的顺序。
- 用户常难以清除地描述所有的需求。
- 客户必须要有耐心,只有在项目接近尾声的时候,他们才能得到可执行的程序。
增量过程模型
· 按照过程框架线性迭代开发
适用于周期比较短的项目。
为什么使用增量模型:如果在既定的商业要求之前不可能找到足够的开发人员,增量模型显得特别有用。
RAD模型
- 是一种侧重于短暂的开发周期的增量过程模型,为大型且必须在严格的时间内提交的项目 而设计的。
- 是瀑布模型的高速变体,通过基于构件的构建方法实现快速开发。
- 是一种 linear sequential model
不足之处:
- 对于大型的可伸缩项目,RAD 需要大量的人力资源来创建多个相对独立的 RAD 团队。
- 如果没有为短时间内急速完成整个系统做好准备,RAD 项目将会失败。
- 如果一个系统不能合理地模块化,RAD 构建会有很多问题。
- 如果系统需求是高性能,不能采用 RAD 模型。
- 技术风险很高的时候,不宜采用 RAD。
演化过程模型
演化模型是迭代的过程模型。
原型开发
瀑布模型的改进,一般用于需求很模糊的时候。
原型模型的思想:先建立一个能够反映用户主要需求的原型,让用户实际看一下未来系统的面貌,以便判断哪些功能是符合需要的,哪些方面还需要改进,然后将原型反复改进,直至建立完全符合用户要求的新系统。
螺旋模型
- 结合了原型的迭代特性、瀑布模型的系统性和可控性特点特点。采用循环的方式逐步加深系统定义和实现的深度。
- 其他过程模型在软件交付之后就结束了,螺旋模型则不同,它应用在计算机软件的整个生命周期,从概念开发到维护。
- 把原型开发作为降低风险的机制,它依赖大量的风险评估专家来保证成功。
专用过程模型
应用较窄,只适用于某些特点的软件工程方法。
基于构件的开发
本质上是演化模型,需要以迭代方式构建软件。(需要面向对象技术支持)
面向方面的软件开发(AOSD)
以用户跨越多个系统功能、特性和信息为关注点。
统一过程(UP)
是一种增量模型,定义了五个阶段:
- 起始(inception):包括客户沟通和策划活动,强调定义和细化用例,并将其作为主要模型
- 细化(elaboration):包括用户沟通和建模活动,重点是创建分析和设计模型,强调类的 定义和体系结构的表示
- 构建(construction):细化设计模型,并将设计模型转化为软件构件实现
- 转换(translation):将软件从开发人员传递给最终用户,并由用户完成 Beta 测试和验收测试
- 生产(production):持续地监控软件的运行,并提供技术支持
第四章 敏捷开发
什么是敏捷
- 能够有效响应变更
- 在参与人之间有效地沟通
- 将客户作为开发团队的一部分
- 项目计划必须是可以灵活调整的
这种哲学理念推崇:
- 让客户满意和软件的早期增量发布;
- 小而高度自主的项目团队;
- 非正式的方法;
- 最小化软件工程工作产品以及整体精简开发。
极限编程XP
XP使用面向对象方法作为推荐的开发范型。
XP的四个框架活动:
- 策划:始于建立一系列描述待开发软件必要特征与功能的故事(用户故事)。
- 设计:遵循KIS(keep it simple,保持简洁)原则;鼓励使用CRC(类-指责-协作者)卡作为有效机制;如果在某个故事设计中碰到困难,实现并评估原型;XP鼓励既是构建技术又是设计中的重构。
- 编码:关键概念之一是结对编程。
- 测试:在编码之前建立单元测试是XP方法的关键因素,XP验收测试(也称为用户测试),由客户确定,根据用户故事得到的。
动态系统开发方法(DSDM)
- DSDM建议使用修改版Pareto原则。在这种情况下,如果交付整个应用系统需用100%时间,那么80%的应用系统可以用20%的时间交付。
- DSDM建议使用迭代软件过程。
Scrum(橄榄球)
- 每一个框架活动中,发生一个过程模式中的工作任务称为一个冲刺。
- 每一个过程模式定义的一系列问题:待定项
(backlog)、冲刺(sprint) - 十五分钟例会回答的基本问题:
- 上次例会之后做了什么
- 遇到什么困难
- 下次例会之前做些什么
第八章 理解需求
需求工程 - design和construction的桥梁
需求工程(Requirement Engineering,RE)是指致力于不断理解需求的大量任务和技术。包含起始、获取、细化、协商、规格、确认、需求管理。
需求工程通过执行7个不同的活动来完成:
- Inception(起始)
- Elicitation(导出)
- Elaboration(细化)
- Negotiation(谈判)
- Specification(规格说明)
- Validation(确认)
- Management(管理)
开发用例
User-case:产生了一个参与者与系统的交互。从参与者的角度定义用例,用例从最后用户的角度描述了软件或系统。
分析模型中用到的UML图:
- 活动图:描述某个受限环境中处理过程的活动序列。
- 类图:列出传感器的属性和可以修改这些属性的操纵。
- 状态图:一种表现系统行为的方法,该方法描绘系统状态以及导致系统改变状态的事件。
- 用例图:从用户的视角描述系统。
第九、十、十一章 需求模型
需求分析
分析模型的三个主要目标:
需求建模方法
- 结构化分析:是一种考虑数据和处理的分析建模方法,数据作为独立的实体转换。数据对象建模定义了对象的属性和关系,操作数据对象的处理建模应表明当数据对象在系统内流动时处理如何转换数据。
- 面向对象分析:就是检查定义为一组用例的问题域,尽量提取定义问题的类。关注于定义类和影响客户需求的类之间的协作方式。UML 和统一过程主要是面对对象的。
数据建模
- 数据对象:
- 数据对象是任何必须被软件理解的复合信息的表示
- 数据对象只(only)封装数据,在数据对象内没有任何对数据操作的引用。
- 数据属性定义了数据对象的性质,可以用来:
- 为数据对象的实例命名
- 描述这个实例
- 建立对另一个表中的另一个实例的引用
- 关系(relationship)指明数据对象相互连接的方式
- 基数(cardinality)描述了一个对象的出现次数与另一个对象出现次数的关联,有三种:
- 1:1
- 1:n
- m:n
- ER图的三个元素:attributes、object、relationship。ER图的主要目的是:展示数据对象和他们的关系。
基于场景建模
UML
使用UML的分析建模从开发用例图、活动图和泳道图形式的场景开始。
Use-Cases
use-case的概念:从定义的参与者的角度,用简单的语言描述一个特点的使用场景。
面对对象分析
- attributes:描述一个类的一系列数据值
- class:封装描述某个实词实体行为所需的数据和程序抽象
- object:特定类的实例。对象继承类的属性和操作。
- operation:当对象接收到数据时调用的对象过程
生成行为模型
- 评估所有的用例,以保证完全理解系统的交互顺序。
- 识别驱动交互顺序的事件,并理解这些事件如何与特定的对象相互关联
- 为每个用例生成序列
- 创建系统状态图
- 评审行为模型以验证准确性和一致性
第十二章 设计概念
软件工程中的设计
将分析模型映射到设计模型中
设计概念
- 抽象(abstraction)
- 体系结构(architecture):软件的整体结构和这种结构为系统提供概念完整性的方式。
- 模式(patterns):每个设计模式的目的都是提供一个描述,使得设计人员能够确定:模式是否适用于现在的工作,模式能否复用,模式是否能够指导类似模式。
- 模块化(modularity):软件划分为独立命名的、可处理的构件。
- 信息隐藏(information hiding):每个模块对其他所有模块都隐蔽自己的设计决策。
- 功能独立(functional independence):开发具有专一功能和避免与其他模块过多交互的模块。
- 求精(refinement):通过连续精化过程细节层次来实现程序开发,通过逐步分解功能的宏观陈述直至形成程序设计语言的语句来实现层次开发。
- 重构(refactoring):一种重新组织的技术,可以简化构件的设计(或代码)而无需改变其功能或行为。
- 设计类(design class):当设计模型发生演化时,必须定义一组设计类,它们可以:(1)通过提供设计细节对分析类进行求精,而这些设计细节将促成类的实现;(2)实现支持业务解决方案的软件基础设施。
设计模型
过程
- 数据设计元素
- 体系结构设计元素
- 接口设计元素
- 构件级设计元素
- 部署级设计元素
组织良好的设计类的四个特征
- 完整性与充分性
- 原始性
- 高内聚性
- 低耦合性
实现所有功能,提供软件完整的视图。
第十三章 体系结构设计
软件体系结构
程序或计算系统的软件体系结构是指系统的一个或者多个结构,它包括软件构件、构件的外部可见属性以及它们之间的相互关系。
数据设计的目标
把在分析模型中定义的数据对象转化成软件构件级的数据结构,并且在必要时转化为应用程序级的数据库体系结构。
体系结构风格和模式
体系结构风格的简单分类
- 以数据为中心的体系结构
- 数据流体系结构
- 调用和返回体系结构
- 面向对象体系结构
- 层次体系结构
体系架构设计的复杂性(三种依赖):
- sharing dependency(共享依赖):消费者间或生产者间的依赖关系
- flow dependency(流依赖):资源的生产者和消费者间的依赖关系
- constrained dependency(约束依赖):在一组活动间相关控制流上的约束。
第十四章 构件级设计
什么是构件
面对对象的观点
在面向对象软件工程观点中,构件包括一个协作类集合。
传统的观点
在传统观点中,一个构件就是程序的一个功能要素,三种角色为:
- control component(控制构件)
- problem domain component(问题域构件)
- infrastructure component(基础设施构件)
设计基于类的构件
基本设计原则
- 开闭原则(The Open-Closed Principle,OCP):模块(构件)应该对外延具有开放性,对修改具有封闭性。
- Liskov替换原则(Liskov Substitution Principle,LSP):子类可以替换它们的基类。
- 依赖倒置原则(Dependency Inversion Principle,DIP):依赖于抽象,而非具体实现。
- 接口分离原则(Interface Segregation Principle,ISP):多个客户专用接口比一个通用接口要好。
- 发布复用等价性原则(Release Reuse Equivalency Principle,REP):复用的粒度就是发布的粒度。
- 共同封装原则(Common Closure Principle,CCP):一同变更的类应该合在一起。
- 共同复用原则(Common Reuse Principle,CRP):不能一起复用的类不能被分到一组。
内聚 & 耦合
内聚
- 功能内聚:主要通过操作来体现,当一个模块完成一组且只有一组操作并返回结果时,就成此模块是功能内聚的。
- 分层内聚:由包、构件和类来体现。高层能够访问低层的服务,但低层不能访问高层的服务。
- 通信内聚:访问相同数据的所有操作被定义在一个类中。
耦合
耦合是类之间彼此联系程度的一种定性度量。
面向对象构件级设计的步骤
- 标识出所有于问题域相对应的设计类。
- 确定所有基础设施域相对应的设计类。
- 细化所有不需要作为复用构件的设计类。
3.1. 在类或构件协作时说明消息的细节。
3.2. 为每个构件确定适当的接口。
3.3. 细化属性,并且定义实现属性所需要的数据类型和数据结构。
3.4. 详细描述每个操作中的处理流。 - 说明持久数据源(数据库和文件)并确定管理数据源所需要的类。
- 开发并细化类或构件的行为表示。
- 细化部署图以提供额外的实现细节。
- 考虑每个构件级设计表示,并且时刻考虑其他可选方案。
传统构件级设计
传统构件的三种设计表示:
- 图形 —— 流程图
- 表格 —— 决策表
- 文本 —— PDL
在构件级设计中,面向对象的观点和传统的观点的区别?
- 面向对象的观点注重细化来自于问题域和基础设施域的设计类
- 面向对象的观点注重细化来自于问题域和基础设施域的设计类
第十五章 用户界面设计
黄金规则
- 把控制权交给用户
- 减轻用户的记忆负担
- 保持界面一致
用户界面分析和设计
界面分析步骤
- 用户分析
- 任务分析和建模
- 显示内容分析
- 工作环境分析
界面设计步骤
- 定义界面对象和动作
- 确定事件(用户动作),即会导致用户界面状态发生变化的事件
- 描述每个状态的表示形式
- 说明用户如何利用界面提供的信息来解释每个状态
第二十二、二十三、二十四章 测试策略和技术
软件测试的策略性方法
验证与确认
验证:是指确保软件正确地实现某一特定功能的一系列活动;
确认:指的是确保开发的软件可追溯到客户需求的另外一系列活动
传统软件的测试策略(过程与文档)
单元测试
单元测试侧重于软件设计的最小单元(软件构件或模块)的验证工作。
集成测试&回归测试
集成测试:是构建软件体系结构的系统化技术,同时也是进行一些旨在发现与接口相关的错误的测试。
回归测试:重新执行已测试过的某些子集,以确保变更没有传播不期望的副作用。
为什么说回归测试是集成测试流程中的关键部分?
因为在集成测试策略的环境下,每加入一个新的模块作为测试的一部分时,软件会发生变更,这些变更可能会是使本来可以正常工作的功能产生问题,而回归测试只是重新执行已进行测试的某个子集,以确保变更没有传播不期望的副作用。
确认测试
确认测试始于集成测试的结束,那时已测试完单个构件,软件已组装成完整的软件包,且接口错误已被发现和改正。
系统测试
What is the normal order of activities in which traditional software testing is organized?
unit testing, integration testing, validation testing, system testing
调试技巧
测试和调试的关系
- 测试发现错误,调试诊断错误出现的原因和位置,以便消除错误。
- 调试出现在成功的测试之后。
软件测试基础
软件可测试的定义和特点
软件可测试就是(计算机程序)能够被测试的容易程度。
特点:
- 可操作性
- 可观察性
- 可控制性
- 可分解性
- 简单性
- 稳定性
- 易理解性
白盒测试
白盒测试是在了解模块内部结构的情况下进行的测试。
白盒测试集中在程序控制结构上。
流图表示
流图是一种简单的控制流表示方法。
- 边和结点限定的范围称为域
- 在计算域的数量时,将图的外部区域作为一个域。
环复杂度
V(G) = E − N + 2 (E 是流图边数,N 是流图节点数)
基本路径测试
控制结构测试
黑盒测试
黑盒测试旨在验证功能需求,而不考虑程序的内部工作。
等价类划分
它将程序的输入划分为若干个数据类,从中生成测试用例。
边界值分析
边界值分析通常在边界值附近设计测试用例。
面向对象的测试方法
基于错误的测试
基于场景的测试
是一种面向对象的测试方法,意味着捕获用户必须完成的任务,然后在测试时使用它们及其变体。
第二十一、二十九、三十一、三十二、三十三、三十四、三十五章 项目管理
4P’s
- people:人员是软件项目的基本要素和关键因素。
- product:在制定项目计划之前,应该首先确定产品的目标和范围,考虑可选的解决方案,识别技术和管理上的限制。
- process:项目团队要选择一个适合于待开发软件的过程模型
- Project:采用科学的方法和工具对项目基本内容进行管理。
软件配置管理
概念
是一组管理变更的活动,
是应用于整个软件过程的一种普适性活动。
SCM过程
- 标识
- 变更控制
- 版本控制
- 配置审核
- 报告
风险管理
- 项目风险:威胁到项目计划。项目风险是指预算、进度、人员、资源、利益相关者、需求等方面的潜在问题以及它们对软件项目的影响。
- 技术风险:威胁到要开发软件的质量及交付时间。技术风险是指设计、实现、接口、验证和维护等方面的潜在问题。
- 商业风险:商业风险威胁到要开发软件的生存能力。
开发了一个无人真正需要的优良产品或系统(市场风险)
开发的产品不符合公司的整体商业策略(策略风险)
建造了一个销售部门不知如何销售的产品(销售风险)
由于重点转移失去了高级管理层支持(管理风险)
没有得到预算或人员的保证(预算风险)