软件工程
https://www.cnblogs.com/qyf2199/p/12104922.html
👇这些是按照ppt的章节来划分的(柯逍)
👇无任何重点与汇总:-D
第一章 软件的本质
什么是软件
软件是一组要素的集合,教科书给软件的定义
- 指令的集合(计算机程序),通过执行这些指令可以满足 预期的特征、功能和性能需求,
- 数据结构, 使得程序可以合理利用信息
- 软件描述信息(文档) ,用来描述程序操作和使用
软件和硬件有完全不同的特性:
- 软件是设计开发的,而不是传统意义上生产制造的
- 软件不会磨损,但是会退化
- 基于构件的构造模式
软件开发包括编码
开发与编码的不同之处
-
目的不同
- 编码是让计算机能理解和执行设计者意图
- 软件开发是要满足用户需求,同时也满足自身利益
-
方法不同
-
编码通过规范的程序设计,使程序能正确地理解和执行设计者的意图
-
软件开发要通过实施软件过程,保证按时交付软件、控制质量和降低成本
-
-
参与者不同
- 编码主要靠个人的经验和技巧
- 软件需要有团队的合作,要有适合团队特点的软件过程
软件的应用领域
系统软件
系统软件是一整套服务于其他程序的程序
某些系统软件(例如:编译器、编辑器、文件管理软件)处理复杂但确定的信息结构。
另一些系统应用程序(例如:操作系统构件、驱动程序、网络软件、远程通信处理器)主要处理的是不确定的数据。
特点:
-
和计算机硬件大量交互
-
多用户大量使用;
-
需要调度、资源共享和复杂进程管理的同步操作;
-
复杂的数据结构以及多种外部接口。
应用软件
解决特定业务需要的独立应用程序
除了传统数据处理的应用程序,应用软件也被用于业务功能的实时控制(e.g销售点的交易管理,实时制造过程控制)
工程/科学软件
这类软件通常带着“数值计算“算法的特征
嵌入式软件
嵌入式软件存在于某个产品或者系统中,可以执行有限但难于实现的功能,并提供重要的功能和控制能力
产品线软件
产品为多个不同用户的使用提供特定的功能,关注有限的特定的专业市场或者大众消费品市场
Web/移动APP
以网络为中心的软件,其概念涵盖了宽泛的应用程序产品
人工智能软件
利用非数值算法解决计算和直接分析无法解决的复杂问题
遗留软件
使用了很长时间,由于使用者不愿更换,仍然在使用的系统
特点
- 支持核心业务,并且是业务必不可少的支撑
- 在使用过程中,不断地被改变
- 质量差:设计难以扩展、代码费解、文档混乱
对策:尽可能什么也不做
遗留软件经常会由于下述原因发生演化
- 软件需要进行适应性调整,从而可以满足新的计算机环境或者技术的需求
- 软件必须升级以实现新的商业需求
- 软件必须拓展以使之具有更多新的系统和数据库的互操作能力
- 软件架构必须进行改建以使之能适应不断演化的计算环境
第二章 软件工程
软件工程定义
Fritz Bauer给出了如下定义:
建立和使用一套合理的工程原则,从而经济的获得可靠的,可在实际机器上高效运行的软件
IEEE给出了如下定义:
- 将系统化的、规范的、可量化的方法应用于软件的开发、 运行和维护,即将工程化方法应用于软件
- 对上述方法的研究
软件工程是一种层次化的技术,自下而上分为:质量关注点→过程→方法→工具
-
支持软件工程的根基在于质量关注点
-
基础是过程层,过程定义了一个框架,给出了开发步骤
-
方法为构建软件提供技术上的解决方法,为构建软件提供技术上的解决方法(如何做),包括沟通,需求分析,设计建模、编程、测试和技术支持
-
工具为过程和方法提供自动化或半自动化的支持
软件过程
过程是事情进行或事物发展所经过的顺序。
当开发产品或构建系统时,遵循一系列可预测的步骤(即路线图)是非常重要的,它有助于及时交付高质量的产品。
软件开发中所遵循的路线图就称为**“软件过程”**
**过程:**工作产品构建时所进行的一系列活动、动作和任务的集合
**活动:**主要实现宽泛的目标,与应用领域,项目大小,结果复杂性或者实施软件工程的重要程度没有直接关系
**动作:**包含了主要工作产品生产过程中的一系列任务
**任务:**关注小而明确的目标,能够产生实际产品(e.g构建一个单元测试)
过程框架
过程框架定义了若干个框架活动,为实现完整的软件工程过程建立了基础,每一个活动由一组软件工程动作组成,每一个动作都包括一系列相互关联的可考核的任务
通用过程框架:
- 沟通
- 策划
- 建模
- 构建
- 部署
软件工程过程框架活动由很多普适性活动来补充实现,通常,这些普适性活动贯穿软件项目始终,来帮助软件团队管理和控制项目进度、质量、变更和风险。典型的普适性活动包括
- 软件项目跟踪和控制
- 风险管理
- 软件质量保证
- 技术评审
- 测量
- 软件配置管理
- 可复用管理
- 工作产品的准备和生产
软件工程实践
软件工程实践的精髓
- 理解问题(沟通和分析)
- 计划解决方案(建模和软件设计)
- 实施计划(代码生成)
- 检查结果的正确性(测试和质量保证)
软件工程整体实践的原则
- 存在价值
- 保持简洁
- 保持愿景
- 关注使用者
- 面向未来
- 提前设计复用
- 认真思考
第三章 软件过程结构
过程:在工作产品构建过程中所需完成的工作活动、动作和任务的集合。这些活动、动作、任务中的每一个都隶属于某一框架或者模型,框架或模型定义了他们与过程之间或者相互之间的关系
过程流:描述了在执行顺序和执行时间上如何组织框架中的活动、动作和任务
英文从外到内:软甲过程,过程框架,普适性活动,框架活动,软件工程动作,任务集,
通用过程框架:
分为:
- 线性:字如其名
- 迭代:在执行下一个活动前重复执行之前的一个或多个活动
- 演化:采用循环的方式执行各个活动,每次循环都能产生更为完善的软件版本(增量交付)
- 并行:将一个或者多个活动与其他活动并行执行
软件工程动作由若干个任务集构成,而每一个任务集都由软件工程工作任务、相关工作产品,质量保证点和项目里程碑组成。
任务集定义了为达到一个软件工程动作的目标所需完成的工作
过程模式
描述了软件工程工作中遇到的过程相关问题、明确了问题环境并给出针对该问题的一种或几种可证明的解决方案
模式可以在不同抽象层次上进行定义
- 模式可以描述一个完整的过程模型(例如原型开发)的相关问题和解决方案
- 模式也可以描述一个框架活动(例如策划)
- 或者框架活动中的某一项具体任务(例如项目估算)的相关问题与解决方案
Ambler提出的过程模式的描述模板:
模式名称:应清楚地表达该模式在软件过程中的含义,比如,技术评审。
**驱动力(目的):**模式使用环境及主要问题,以明确主要难点。
**类型:**步骤模式(定义框架活动)、任务模式 (定义软件工程动作或任务)、阶段模式(定义框架活动序列)
**启动条件:**模式应用前需满足的前提条件(输入) 。需要明确:
(1)在此之前,整个开发组织或者开发团队内已有哪些活动?
(2)已有哪些软件工程信息或是项目信息?
(3)过程的进入状态是什么?
**问题:**描述模式将要解决的具体问题
**解决办法:**描述如何成功实现模式。
**结束条件:**描述模式成功执行之后的结果(输出)。模式结束时需要明确:
(1)必须完成哪些开发组织或是开发团队相关的活动?
(2)过程的结束状态是什么?
(3)产生了哪些软件工程信息或是项目信息?
**相关模式:**列举与该模式直接相关的其它过程模式。
**已知应用实例:**说明该模式可应用的具体实例。(什么场合使用)
第四章 过程模型
概念
过程模型为软件工程工作提供了特定的路线,该路线图规定了所有活动的流程、动作、任务、迭代的程度、工作产品以及要完成的工作应如何组织
惯用过程模型
瀑布,增量,演化,并发
目标:使软件开发更加有序
所有的软件过程模型都支持通用框架活动,但是每一个模型都对框架活动有不同的侧重
瀑布模型
又称经典生命周期,它提出了一个传统的、顺序的软件开发方法,即从用户需求规格说明开始,顺序地通过沟通、策划、建模、构建和部署过程,最终提供完整软件和持续技术支持。
变体:V模型
软件团队沿着V模型左侧步骤向下推进,编码结束后,团队沿着V模型右侧的步骤向上推进,其本质是增加了一系列测试(质量保证动作)
对比:两者没有本质区别,V模型提供了一种将验证确认动作应用于早期软件工程工作中的方法
特点
- 阶段间具有顺序性和依赖性
- 顺序性:只有等前一阶段的工作完成以后,后一阶段的工作才能开始;前一阶段的输出文档,就是后一阶段的输入文档。
- 依赖性:只有前一阶段有正确的输出时,后一阶段才可能有正确的结果
- 推迟实现的观点:前面步骤完成后才考虑实现。把逻辑设计和物理设计清楚的划分开来,尽可能推迟程序的物理实现,这是瀑布型软件开发的一条重要的指导思想
- 质量保证的观点:每一阶段都需要有文档以及经过评审。
- 为了保证质量,瀑布型软件开发在各个阶段坚持了两个重要的做法
- 每一阶段都要完成规定的文档。没有完成文档,就认为没有完成该阶段的任务。
- 每一阶段都要对完成的文档进行复审,以便尽早发现问题,消除隐患。
- 为了保证质量,瀑布型软件开发在各个阶段坚持了两个重要的做法
问题
- 不适应需求经常发生变更的环境
- 客户只能到项目开发的晚期才能得到程序的可运行版本,大的错误如果到这时才被发现,会造成灾难性后果
- 工作中会发生阻塞状态
所以,在需求已确定的情况下,且工作采用线性的方式完成的时候,瀑布模型是一个很有有用的过程模型
增量过程模型
提出背景
需求不明确或迫切需要为用户迅速提供一套功能有限的软件产品,然后再后续版本中再进行细化和扩展功能。
随着时间的推移,增量模型在每一个阶段都运用现性序列。每个线性序列生产出软件的可交付增量。(即以迭代方式运用瀑布模式)
运用增量模型的时候,第一个增量往往是核心产品(core product)。也就是,满足了基本的需求,但是许多附加的特性(一些是已知的,一些是未知的)没有提供,客户使用该核心产品或者进行仔细的评价,并根据评价结果制定下一个增量计划。这份计划说明了需要对核心产品进行的修改,以便更好地满足客户的要求,也说明了需要增加的特性和功能
【注】增量模型侧重于每个增量都提交一个可以运行的产品。早期的增量可以看做是最终产品的片段部分。但它们确实具备了用户服务能力,也为用户的评价提供了一个平台
如果在项目既定的商业期限之前不可能找到足够的开发人员,这种情况下增量模型显得特别有用
它还可以规避技术风险
优点
- 能在较短时间内向用户提交可完成部分工作的产品;
- 用户有较充裕的时间学习和适应新产品;
- 易于保证核心功能正确;
- 可以基于早期版本来获取需求;
- 项目完全失败的风险小;
- 可以为那些创新的功能开拓市场;
- 规避了资源缺乏的风险;
问题
- 把用户需求转化为功能递增的不同版本可能比较难 (功能联系紧密,难以完全分开)
- 难以确定所有版本共需的公用模块。(通常进行设计时会先考虑设计公用模块,但是每一个增量只考虑局部的设计,因此,全局的公用模块很难确定)
变体——迭代开发
迭代式开发是增量式开发的一种变体,不同于传统的增量开发(每次提交一个构件),迭代式开发开始提交所有的模块(部分模块有待优化),在其后的阶段逐渐优化。
演化过程模型
提出背景:
- 开发过程中,业务和产品需求经常变化;
- 严格的交付时间使得开发团队不可能圆满完成软件产品,但是必须交付功能有限的版本以及应对竞争或商业压力;
- 往往很好地理解了核心产品需求,但是系统扩展的细节问题却没有定义。
演化模型是迭代的过程模型,每次迭代产生软件的一个更完整的版本
常用的演化过程模型:
原型开发与螺旋模型
原型开发
背景:
- 客户提出了一些基本功能,但未详细定义输入、处理和输出需求;
- 开发人员可能对开发运行环境、算法效率、操作系统的兼容性和人机交互等情况不确定。
当需求很模糊的时候,原型开发模型都能帮助软件开发人员和利益相关者更好的理解究竟需要做啥
使用前提
- 用户必须积极参与原型的建造,建造原型仅仅是为了定义需求,之后就必须被全部抛弃(至少是部分抛弃)
- 必须有快速开发工具可供使用
问题:
- 利益相关者看到了软件的工作版本,却未察觉到整个软件是随意搭成的,也未察觉到为了尽快完成软件,开发者没有考虑整体软件质量和长期的可维护性。当开发者告诉客户整个系统需要重建以提高软件质量的时候,利益相关者会不愿意,并且要求对软件稍加修改使其变为一个可运行的产品。因此,软件开发管理往往陷入失效。
- 作为一名软件工程师,软件开发人员为了使一个原型快速运行起来,往往在实现过程中采用折衷的手段。他们经常会使用不合适的操作系统或程序设计语言,仅仅因为当时可用和熟悉。他们也经常会采用一种低效的算法,仅为了证明系统的能力。时间长了,软件开发人员可能会适应这些选择,而忽略了这些选择其实并不合适的理由,结果造成并不完美的选择变成了系统的组成部分的情况。
【注】原型是为定义需求服务的,然后丢弃原型,实际的软件系统是以质量第一为目标而开发的
螺旋模型
这是一个风险驱动的软件开发模型
【注】它可以运用在应用系统开发的整个生命周期,从概念开发到维护
特点:
- 采用循环的方式,逐步加深系统定义和实现的深度(原型开发的迭代性质);
- 确定一系列里程碑,确保利益相关者都支持系统解决方案(瀑布模型的系统性和可控性);
- 第一圈一般开发出产品的需求规格说明,接下来开发产品的原型系统,并在每次迭代中逐步完善,开发不同的软件版本;
- 项目经理还会调整完成软件开发需要迭代的次数;
- 开发大型系统和软件的理想方法,更好地应对风险
总结
演化模型的问题:
- 迭代周期数目不确定,大多项目管理和估算技术是基于活动的线性布局,所以并不完全适用于演化软件过程
- 演化模型没有确定演化的最快速度
- 演化模型侧重灵活性和可延展性,而不是高质量。(即:演化模型优先追求开发速度,而不是零缺陷)
专用过程模型
专用过程模型往往应用面较窄且较专一,只适用于某些特定的软件工程方法
基于构件的开发
基于构件的开发模型具有许多螺旋模型的特点,本质上是演化模型,需要以迭代的方式构建软件。不同之处在于,基于构建的开发模型采用预先打包的软件构建来开发应用系统
优点:能够使软件复用,减少项目开发费用,缩短开发周期
形式化方法模型
主要活动:生成计算机软件形式化的数学规格说明,使得软件开发人员可以应用严格的数学符号来说明,开发,验证系统
优点:应用数学分析的方法,歧义性问题、不完整问题、不一致问题等都能够更容易地发现和改正。在设计阶段,形式化方法是程序验证的基础,使软件开发人员能够发现和改正一些往往被忽略的问题。
缺点:
- 开发非常耗时,成本也很高;
- 只有极少数程序员具有应用形式化的背景,需要大量的培训;
- 对于技术水平不高的客户,很难用这种模型进行沟通。
应用:高度关注安全性的软件(飞行器,医疗设施,经济领域)
统一过程UP
特点:用例驱动,以架构为核心,迭代并且增量
统一过程认识到与客户沟通以及从用户的角度描述系统并保持该描述的一致性的重要性
五个阶段
- 起始阶段:识别基本的业务需求,并用用例初步描述每一类用户所需要的主要特性和功能
- 细化阶段:沟通和通用过程模型的建模活动
- 构建阶段:采用体系结构模型作为输入,开发或是获取软件构建,使得最终用户能够操作用例
- 转换阶段:通用构建活动的后期阶段以及通用部署活动的第一部分
- 生产阶段:对持续使用的软件进行监控,提供运行环境的支持,提交并评估缺陷报告和变更请求
第五章 敏捷开发
什么是敏捷开发
它是一种软件开发方法论,可以应对客户快速变更的需求,它强调以人为核心,采用迭代的方式,循序渐进的开发软件
普遍存在的变化是敏捷的基本动力
敏捷不仅仅是有效的应对变更,它
- 鼓励能够使沟通更便利的团队结构和协作态度
- 强调可运行软件的快速交付而不那么看重中间产品
- 将客户作为开发团队的一部分开展工作
- 项目计划必须是可以灵活调整的
敏捷宣言
个体与交互 胜过 过程与工具
可用的软件 胜过 完备的文档
客户协作 **胜过 ** 合同谈判
响应变化 胜过 遵循计划
敏捷价值观
- 沟通:促进团队内部的开发人员之间的沟通,以及团队和客户(project stakeholder不知道是不是)的沟通
- 简单:画一两张图表来代替几十甚至上百行代码
- 反馈
- 勇气
- 尊重(谦虚)
敏捷原则
- 我们最优先要做的是通过尽早、持续地交付有价值的软件来使客户满意。
- 即使在开发的后期,也欢迎需求变更。敏捷过程利用变更为客户创造竞争优势。
- 经常交付可运行软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
- 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。
- 围绕有积极性的个人构建项目。给他们提供所需的环境和支持,并且信任他们能够完成工作。
- 在团队内部,最富有效果和效率的信息传递方法是面对面交谈。
- 可运行软件是进度的首要度量标准。
- 敏捷过程提倡可持续的开发速度。责任人(sponsor)、开发者和用户应该能够保持一个长期的、恒定的开发速度 。
- 不断地关注优秀的技能和好的设计会增强敏捷能力。
- 简单是必要的。
- 最好的架构、需求和设计出自于自组织团队。
- 每隔一定时间,团队会反省如何才能更有效地工作,并相应调整自己的行为。
★并不是每一个敏捷模型都同等使用这12项原则,一些模型可以选择忽略(或至少淡化)一个或多个原则的重要性。
敏捷变更的成本费用
传统:
成本费用随着计划的进展成非线性增长,这种方法在软件开发团队收集需求时(在项目的早期)相对容易适应变更,在后期的话,费用会迅速升级
敏捷:
设计良好的敏捷过程“拉平了”变更成本曲线
敏捷过程
基于敏捷原则进行的软件开发过程,视为敏捷过程
【注】基于,是指充分考虑,而不是全部包含
敏捷软件过程必须增量的适应,为了达到这一目的,敏捷团队需要客户的反馈,可执行原型或者部分实现的可运行系统是客户反馈的最有效媒介。因此,应当使用增量式开发策略。
这种迭代方法允许客户:周期性的评价软件增量,向软件项目组提出必要的防窥,影响为适应反馈而对过程进行适应性修改
【注】如何建立能解决不可预测性的过程?
答案就是:在于过程的可适应性
因此,敏捷过程必须具有可适应性
极限编程
敏捷软件开发中使用最广泛的一种方法
特点:
- 是一些相互关联的准则和惯例的集合
- 追求变更曲线的平坦化
- 适合于小团队,高风险的项目
XP使用面向对象方法作为推荐的开发泛型,它包含了策划、设计、编码和测试4个框架活动的规则和实践。
工业极限编程IXP
六个新的实践:
- 准备评估
- 项目社区
- 项目特许
- 测试驱动管理
- 回顾
- 持续学习
关于XP的争论
- 需求易变。因为客户是XP团队的成员,对需求的改变不是正式地提出。结果是,项目的范围会发生变化,早期的工作或许要进行修改来适应当前的要求。
- 矛盾的客户需求。许多项目都有众多客户,每个客户都有自己的一套需求。在XP中,团队自身需要吸纳不同客户的要求,这项工作可能超出了自己的职权范围。
其他敏捷过程模型
Scrum
原则与敏捷宣言是一致的,应用Scrum原则指导过程中的开发活动,过程由“需求,分析,设计,演化,交付“等框架性活动组成
每一个框架活动中,发生于一个过程模式中的工作任务称为一个冲刺(sprint)。冲刺中进行的工作(每一个框架活动中的冲刺的数目根据产品复杂度和规模大小而有所不同)适应于当前的问题,由Scrum团队规定并常常作实时修改。
每一个过程模式定义一系列开发活动:
-
待定项:能为用户提供商业价值的项目需求或特征的优先级列表。待定项中可以随时加入新项(即变更的引入)。产品经理根据需要评估待定项并修改优先级**。
-
冲刺:(待定项的一部分,眼前具体的任务)由一些工作单元组成 ,并且必须能在预定的时间段 (time-box)内(一般情况下为30天)完成。冲刺过程中不允许有变更(例如,积压工作项)。因此,冲刺给开发团队成员的工作提供了短期但稳定的环境。
-
Scrum例会:每天召开的短会(一般为15min)会上所有成员都要回答三个问题:
- 上次例会后做了什么
- 遇到了什么困难
- 下次例会前计划做些什么
👆,站立式会议,任务看板,更新任务看板
团队领导(也称为Scrum主持人)主持会议并评价每个团队成员的表现。Scrum会议帮助团队尽早发现潜在的问题。同时,每日例会进一步促进自我组织团队的建设。
动态系统开发DSDM(注意,这个是一种过程框架)
提供一种框架,使其“通过在可控项目环境中使用增量原型开发模式来满足对时间有约束系统的构建和维护”
e.g:如果交付整个应用系统需要100%的时间,那么80%的应用系统可以用20%的时间交付
特点:每一个迭代都遵循**80%**原则,即每个增量只完成能够保证顺利进入下一增量的工作,剩余的细节则可以在知道更多业务需求或者提出并同意变更之后完成。
生命周期活动
- **功能模型迭代:**为客户开发一系列证明其功能的增量原型 (注意:所有DSDM原型都倾向于逐渐发展成可交付的应用系统 )。迭代的意图是在用户使用原型系统时诱导出反馈信息以获取其他的需求。
- 设计与构建迭代:重新构建原型以确保每一个原型都以工程化方式实现,并能为最终用户提供可操作的业务价值。
- 实现:将最终软件增量(一个可操作的原型)置于操作环境中,应当注意:
- 增量不见得100%完成
- 增量置于操作环境以后可能需要改变
敏捷建模AM
原则:
- 有目的的模型:在构建模型之前,开发者心中应当有明确的目标
- 使用多个模型:
- 轻装上阵:随着软件工程的进展,只保留那些能够提供长期价值的模型,抛弃其余的模型
- 内容重于表达形式:一个有用的内容很少,但语法完美的模型不如一个有缺陷但能向读者提供有用内容的模型更有价值。
- 理解模型及工具:理解每一个模型及其构建工具的优缺点
- 适应本地需要:建模方法应该适应敏捷团队的需要
敏捷统一过程AUP
大型上连续,小型上迭代
采用了经典UP阶跃性活动——开始,加工,构建以及变迁
每个AUP迭代执行以下内容
- 建模:UML建立了对商业和问题域的表述,为了保持敏捷,必须保证这些模型足够好
- 实现:将模型翻译成源代码
- 测试:设计/执行一系列测试来发现错误以保证源代码满足需求
- 部署:重点是对软件增量的交付以及获取最终用户的反馈信息
- 配置及项目管理:配置管理着眼于变更管理/风险管理/开发团队的任一常效产品的控制,项目管理追踪和控制开发团队的活动情况和工作进展
- 环境管理:协调过程的基础设施
【注】UML可以与本章所讲的任一敏捷过程模型相结合
第六章 软件工程的人员方面
"非常专业的"软件工程师的七种特质
- 个人责任感
- 对一些人的需求有敏锐的意识
- 坦诚
- 展现抗压能力
- 有高度的公平感
- 注重细节
- 务实
软件团队
团队毒性:
- 混乱的工作氛围
- 会造成团队成员分裂的挫败
- 支离破碎或协调不当的软件过程
- 对软件团队中角色的模糊定义
- 持续且重复性的失败
四种组织模式
- 封闭模式:按照传统的权力层级模式,创新性较弱
- 随机模式:松散的组织团队,依赖成员的主动性,很难完成”有秩序的操作”
- 开放模式:尝试组成一种团队,有包含上两种团队的特性(可控性,创新型),但是效率没有其他团队高
- 同步模式:依赖于问题的自然区分,不需要很多的交流就可以将成员组织起来共同解决问题
主程序员团队
一个高级工程师(主程序员)+技术人员(2-5人)+一个后备工程师
优点:
- 实现了项目人员分工专业化
- 降低了管理的复杂性,提高了工作效率
缺点:现实社会中,缺乏同时具备高超管理才能和技术才能的“全才”
第七章 理解需求 ※核心
需求工程——提供了解决挑战的可靠途径
需求工程
需求工程致力于不断理解需求的大量任务和技术。
从软件过程的角度看,需求工程是一个软件工程动作,开始于沟通并持续到建模活动。他必须适用于过程,项目,产品和人员的需要
需求工程在设计和构建之间建立起联系的桥梁(?,柯逍在这句话这里打了X,啥意思?)
软件需求
对期望的软件行为的表达
分为 功能需求 和 非功能需求
功能需求:描述系统预期提供的功能或服务
非功能需求:不直接与系统具体功能相关的需求,e.g 产品需求,机构需求,外部需求balabala
需求工程的任务
需求工程包括七项明确的任务
-
起始
多数项目都是当确定了商业要求或是发现了潜在新市场、新服务时才开始
项目起始阶段,要建立基本的理解
-
获取
询问客户、用户和其他人:
- 系统的目标是什么
- 想要实现什么
- 系统和产品如何满足业务的要求
- 最终系统或产品如何用于日常工作
获取过程中最重要的是建立商业目标
【注】
范围问题:一般发生在系统边界不清楚的情况下
理解问题:发生在客户和用户并不完全确定需要什么的情况下
易变问题:发生在需求随时间推移而变更的情况
为了帮助解决👆,需求工程师必须以有组织的方式开展需求收集活动
-
细化
将起始和获取阶段获得的信息在细化阶段进行扩展和提炼
任务核心——开发一个精准的需求模型,用以说明软件的功能,特征和信息的各个方面
-
协商
问题:
- 业务资源有限,客户和用户却提出了过高的要求
- 不同的客户或用户提出了相互冲突的需求,并坚持自己的特殊需求至关重要
需求工程师需要通过协商来调解这些冲突。
用迭代的方法给需求排序,逐个评估成本和风险,表述内部冲突,删除、组合或修改需求,以便于各方均能达到一定的满意度
-
规格说明
两种需求文档:
-
需求定义:客户要求的完整列表(对外)
通常是由客户和需求分析师一起编写,是开发人员对系统功能的一个合同,主要给客户阅读
-
需求规格说明:要构建系统的规格化说明(对内)
由需求分析师编写,并由其他软件开发人员使用
【注】软件需求规格说明 SRS
在项目商业化之前必须建立的详细描述软件各个方面的工作产品
很多项目没有写正规的SRS,很多实例表明花在软件需求规格说明的工作量还不如投入到其他软件工程活动
但是以下几种情况规格说明显得非常必要
(1)软件由第三方开发时
(2)缺少规格说明将导致严重业务问题时
(3)当系统非常复杂或设计十分重要的业务时
-
-
确认
对需求工程的工作产品进行质量评估
正式的技术评审是最主要的需求确认机制,确认需求的评审小组包括软件工程师,客户,用户和其他利益相关者,他们检查系统规格说明,并寻找:
- 内容/解释上的差错
- 可能需要进一步澄清的地方
- 丢失的信息
- 不一致(开发大型系统时的主要问题)
- 冲突或不现实的需求
【注】质量需求越关键,越要采用量化术语来陈述!
某些情况下,常见质量需求可以使用定性技术进行验证,在其他情况下,质量需求可以使用定性和定量相结合的评估方式进行验证
-
管理
对于基于计算机的系统,其需求会变更,而且变更的要求贯穿于系统的整个生命周期
需求管理是用于帮助项目组在项目进展中标识、控制和跟踪需求以及需求变更的一组活动。
【注】这些需求工作中的一些任务会并行发生,并且要全部适应项目的要求
建立根基
确认利益相关者——>识别多重观点——>协同合作——>首次提问(欸奇怪这个是流程吗?)
确认利益相关者
两个大佬对利益相关者的定义:直接或间接地从正在开发的系统中获益的人
每个利益相关者对系统有不同的考虑,开发成功后获得的利益也不同,失败面临的风险也不同
识别多重观点
参与者都将为需求工程贡献信息,从多个角度收集信息时,所形成的需求可能存在不一致性或是相互矛盾。需求工程师把所有利益相关者提供的信息分类,便于决策制定者为系统选择一个内部一致的需求集合
协同合作
需求工程师的工作是标识公共区域 (即所有利益相关者都同意的需求)和矛盾区域或不一致区域 (即某个利益相关者提出的需求和其他利益相关者的需求相矛盾)。
首次提问
项目开始时的提问应该是“与环境无关的”
三组问题,分别用来:
- 识别所有对构建软件感兴趣的利益相关者
- 有助于软件开发组更好的理解问题
- 关注与沟通活动本身效率有关的问题
👆这些问题有助于"打破坚冰",并有助于交流的开始
【注】Q&A会议应该仅仅用于首次解除,然后应该用问题求解、协商和规格说明等需求获取方式来取代
获取需求
需求获取(需求收集)将问题求解、细化、协商和规格说明等方面的元素结合起来在一起
协作收集需求
基本原则
- 会议由软件工程师和其他的利益相关者共同举办和参与。
- 制定筹备和参与会议的规则。
- 建议拟定一个会议议程,这个议程既要足够正式,使其涵盖所有的重点,但也不能太正式,以鼓励思想的自由交流。
- 由一个“调解人”(可以是客户、开发人员或其他人)控制会议。
- 采用“方案论证手段”(可以是工作表、活动挂图、不干胶贴纸或电子公告牌、聊天室或虚拟论坛)。
目的:识别问题
提出解决方案的要素,协商不同的方法以及在有利于完成目标的氛围中确定一套解决需求问题的初步方案。
【注】小规格说明:列表所描述的对象或服务需要更多的解释,为了完成这一任务,利益相关者为列表中的条目编写小规格说明
质量功能部署QFD
质量功能部署是一种将客户要求转化成软件技术需求的技术
目的:最大限度的让客户从软件工程过程中感到满意
一些小概念:
- 常规需求:会议中向客户陈述一个产品或系统时的目标,如果这些需求存在,客户会满意
- 期望需求:客户没有清晰表述的基础功能,缺少了会引起客户的不满
- 兴奋需求:超出客户预期的需求,这些需求存在时会令人非常满意
使用场景
场景,可以识别对将要构建系统的使用线索,一般称为用例
获取工作产品
根据将要构建的系统或产品规模的不同,需求获取后产生的工作产品也不同
开发用例
用例从最终用户的角度描述了软件或系统
撰写用例的第一步:确定故事中所包含的“参与者”
参与者是在功能和行为环境内使用系统或产品的各类人员(或设备)。参与者代表了系统运行时人(或设备)所扮演的角色。
【注】参与者!=最终用户
用户可能在使用系统的时候扮演了许多不同的角色,参与者在用例中仅扮演一种角色
基本用例从较高层次上给出参与者与系统之间交互的故事,但是在很多情况下,需要进一步细化用例以便为交互提供更详细的说明。
模板:
用例:用例名
主要参与者:
目标:
前提条件:
触发器:
场景:
异常:
优先级:
何时可用:
使用频率
使用方式
次要参与者
次要参与者使用方式
为解决的问题
实现方法:用例图!
e.g safehome用例图
构建分析模型
分析模型的元素 ※要会画图!!!
- 基于场景的元素 e.g 用例,用例图,活动图
- 基于类的元素 e.g UML类图
- 行为元素 e.g 状态图
UML活动图:
类图和状态图
分析模式
分析模式在特定应用领域内提供一些解决方案(如类,功能,行为),在为许多应用项目建模时都可以重复使用
优点:
-
提高了抽象分析模型的开发速度
-
有利于把分析模型转变到设计模型
第八章 需求建模:基于场景的方法
需求建模动作产生以下一种或者多种模型类型
- 场景模型:出自各种系统“参与者”观点的需求。
- 数据模型:描述问题信息域的模型。
- 面向类的模型:表示面向对象类(属性和操作)的模型,其方式为通过类的协作获得系统需求。
- 面向流程的模型:表示系统的功能元素并且描述当功能元素在系统中运行时怎样进行数据变换的模型。
- 行为模型:显示了软件如何对外部事件或激励做出相应。
在整个分析建模的过程中,软件工程师的主要关注点集中在做什么而不是怎么做
需求模型的三个主要目标
- 描述用户需要什么
- 为软件设计奠定基础
- 定义在软件完成后可以被确认的一组需求
需求模型在系统级描述和软件设计之间建立了一座桥梁
创建分析模型时应该遵循的规则
- 关注在问题域或业务域内可见的需求,抽象级别应该相对高一点
- 需求模型的每一个元素都应能增加对软件需求的整体理解,并提供对信息域,功能,系统行为的深入理解
- 关于基础结构和其他非功能的模型应推延到设计阶段再考虑
- 最小化整个系统内的关联
- 确认需求模型为所有利益相关者都带来价值
- 尽可能保持模型简洁
域分析
**目标:**查找或创建那些广泛应用的分析类或分析模式,使其能够复用。
域分析师的角色是发现和定义可复用的分析模式、分析类和相关的信息(剽窃?)
需求建模的方法
-
结构化分析
考虑数据和处理的需求建模方法
-
面向对象的分析
【注】柯逍课件里面写得四类需求建模方法
- 基于场景的元素:表述用户如何与系统和使用软件时出现的特定活动序列进行交互。
- **基于类的元素:**描述了系统操作的对象、对象间关系(某层级),以及定义的类间发生的协作。
- 行为元素:描述了外部事件如何改变系统或驻留在系统里的状态。
- **面向流的元素:**表示信息转换的系统,描述了数据对象在流过各种系统功能时是如何转换的。(输入 - 处理 - 输出)
基于场景建模
创建初始用例
用例:帮助定义系统之外存在什么以及系统应该完成什么,即用例从某个特定参与者的角度出发,采用简明的语言描述一个特定的使用场景。但是问题是:
- 编写什么
- 写多少
- 编写说明应该多详细
- 如何组织说明
开始开发用例时,应该列出特定参与者执行的功能或活动。这些可以借助所需系统功能的列表,通过与利益相关者交流,或通过评估活动图(作为需求建模中的一部分而开发)获得
细化初始用例
为了全面理解用例描述功能,对交互操作给出另外的描述是很有必要的。
主场景中的每一个步骤都将通过如下提问得到评估:
- 在这一状态点,参与者能进行一些其他动作吗?
- 在这一状态点,参与者有没有可能遇到一些错误的条件?如果有可能,这些错误会是什么?
- 在这一状态点,参与者有没有可能遇到一些其他的行为(如由一些参与者控制之外的事件调用)?如果有,这些行为是什么?
👆这些问题的答案导致创建一组次场景,次场景属于原始用例的一部分,但是表现了可供选择的行为
👇以下问题也值得关注
- 在这些用例中是否可以支持功能(或参与者)的应答失败?
- 性能差的系统是否会导致无法预期或不正确的用户活动?
编写正式用例
非正规用例对于需求建模常常是够用的。
但是,当一个用例包含关键活动或描述一套具有大量异常处理的复杂步骤时,就会希望采用更为正规的方法。
图形化用户场景
每种需求建模方法都有其局限性,用例方法也无例外:
- 如果描述不清晰,用例可能会误导或有歧义。
- 对于必须特别详细和精准的需求建模情景 (例如安全关键系统),图形化的表示方法更有助于理解。
可以使用:
- 用例图
- 活动图
- 泳道图
👆这些要会画
第九章 需求建模:基于类的方法
基于类的分析模型的元素包括:
- 类
- 对象
- 属性
- 操作
- CRC模型
- 协作图
- 包
建模过程
- 通过检查问题描述来识别类
- 分离潜在类
- 识别类的所有属性
- 定义操作
分析和识别类
进行语法解析,第一次出现的名词加下划线,第一次出现的动词用斜体
抽取名词来获得潜在类
分离出所有名词,我们该寻找什么?分析类表现为
- 外部实体 (其他系统、设备、人员)
- 事物 (报告、显示、字母、信号)
- 偶发事件或事件
- 角色 (经理、工程师、销售人员)
- 组织单元 (部门、组、团队)
- 场地 (制造车间或码头)
- 结构 (传感器、四轮交通工具、计算机)
在分析模型中,分析师考虑每一个潜在类是否应该使用如下这些特征
- 保留信息:必须记录潜在类的信息才能保证系统正常工作
- 所需服务:有一组可确认的,能改变属性值的操作
- 多个属性:只有一个属性的类可能在设计中有用,但在分析阶段,更适合作为另一个类的某个属性
- 公共属性:可定义一组属性,它们适用于该潜在类的所有实例
- 公共操作:可定义一组操作,它们适用于该潜在类的所有实例
- 必要需求:在问题空间中出现的外部实体、或者任何系统解决方案的运行所必需的信息
【注】某些被拒绝的潜在类(不符合上述特征)将成为被接收类的属性
对问题的不同陈述可能导致作出“接收或拒绝”不同的决定
描述属性
属性:属于类的“东西”
课本:属性描述了已经选择包含在需求模型中的类。实质上,属性定义了类,以澄清类在问题空间的环境下意味着什么
【注】如果有超过一个项和某个类相关联,京应该避免把这个项定义为属性
定义操作
操作定义了某个对象的行为
操作的四个类型
(1) 以某种方式操作数据 (例如:添加、删除、重新格式化、选择);
(2) 执行计算的操作;
(3) 获取某个对象状态的操作;
(4) 监视某个对象发生某个控制事件的操作。
CRC建模
CRC模型是表示类的标准索引卡片的集合,分为三部分
顶部写类名,左侧列出类的职责(与类相关的属性与操作),右侧列出类的协作者(提供完成某个职责所需要信息的类)
类
类的分类可以通过如下三种分类方式进行拓展
-
实体类:也称模型或业务类,是从问题说明中直接提取出来的。
-
边界类:用于创建用户可见的和在使用软件时交互的接口(如交互屏幕或打印的报表)。
-
控制类:用于管理“工作单元”,控制类可以管理:
(1) 实体类的创建或更新;(2) 边界类获取信息后的实例化。
(3) 对象集合间的复杂通信。
(4) 对象间或用户和应用系统间交换数据的确认。
通常直到设计开始时才开始考虑控制类
类间的三种通用关系
- is-part-of(是。。。的一部分)
- has-knowledge-of(有。。。的知识):一个类需要从另一个类中获取信息时
- depends-upon(依赖。。。):依赖关系
分析包
将分析模型的各种元素以一种方式分类,分组打包后称为分析包,并取一个有代表性的名字
e.g
+:该类是公共可见的
-:该类对其他包是隐藏的
#:只能由指定包中的类访问该元素
第十章 需求建模:行为和模式
面向流程建模
描述了数据对象在系统中的变换过程
采用数据流图(DFD),状态迁移图等
DFD
符号:
例子:
DFD使用分层的方式来表示
第一个数据流模型(第0层DFD,也成为环境图)表示整个系统,随后的数据流图改进环境图,在为一个后续层提供更多的细节。
指导原则
(1) 第0层DFD(也称环境层DFD或顶层DFD)将系统描述成一个泡泡;
(2) 仔细标记主要的输入和输出;
(3) 通过把选定的处理、数据对象和数据存储分离为下一层表示而开始精化过程,即逐步求精,一次精化一个处理;
(4) 使用有意义的名称,标记所有的箭头和泡泡;
(5) 从一层转至另一层时,注意保持信息流的连续性;
(6) 一次精化一个泡泡。
如何将第0层DFD扩展到第1层数据流模型?
对描述环境层泡泡的用例叙述采用语法解析的方法
根据语法解析:
动词是处理,在后续的DFD中用泡泡表示
名词是外部实体(方框)、数据或控制对象(箭头)、数据存储(双横线)。
在任何DFD层次中对某个泡泡的处理叙述文字进行语法解析,可以产生许多如何精化到下一个层次的有用信息。
持续进行DFD的求精,直到每个泡泡都执行了某个单一的功能,也就是说,直至每个泡泡所代表的处理都执行一个功能,并且该功能可以很容易地成为一个程序构件。
【注】DFD之间的数据流必须要连续
判定表
一个表格,描述条件和条件导致的动作的集合
e.g
数据字典
管理各种关系模型中的信息,具体信息包括:
- 一般信息:名字、别名、描述等;
- 定义信息:数据类型、长度、结构;
- 使用特点:值的范围、使用频率、使用方式;
- 控制信息:来源、使用它的程序;
- 分组信息:父结构、从属结构、物理位置等;
数据元素组成数据对象的方式:
- 顺序:两个或多个分量以确定次序进行连接;
- 选择:从两个或多个可能的元素中选取一个;
- 重复:把指定的分量重复零次或多次。
符号:
- = 等价于
- +和
- []或 (选择一个,用|隔开分量)
例:字母或数字 = [字母字符 | 数字字符] - { } 重复 ,(左右的数字分别为重复次数的上、下界)
例:字母数字串 = 0{字母或数字}7 (可重复0-7次) - ( ) 可选 (即从括号从中任选一项,也可一项都不选)
e.g
生成行为模型
行为模型显示了软件如何对外部事件或激励做出响应
识别用例事件
只要系统和参与者之间交换了信息就发生了事件
【注】事件应该不是被交换的信息,而是已交换信息的事实
对于事件:
- 应确认每个事件的参与者
- 应标记交换的所有信息
- 应列出任何条件或限制
一旦确定了所有的事件,这些事件将被分配到所涉及的对象。
对象负责生成事件或者识别已经在其他地方发生的事件
状态表达
两种不同的状态描述
- 系统执行其功能时每个类的状态
- 系统执行其功能时从外部观察到的系统状态
类的状态
类状态有主动/被动之分
-
被动状态——某个对象所有属性的当前状态
-
主动状态——对象进行连续变换和处理时的当前状态
必然发生事件(触发器)才能迫使对象做出从一个主动状态到另一个主动状态的迁移
具体实现:
UML状态图
UML顺序图
👆要会画
类
类包括:
- 边界类
- 控制类
- 实体类
需求建模的模式
软件模式是获取领域知识的一种机制,从而遇到新问题时可以反复使用。
- 在某些情况下,领域知识在同一应用领域中用于解决新问题。
- 在另外一些情况下,通过模式获取的领域知识可借助模拟用于完全不同的应用领域。
需求模型的组成元素
- 基于场景(用例)、基于数据(数据模型)、基于类、基于流和行为。
其中每个元素都是从不同的视角检查问题,并且每一个都提供一种发现模式的机会,可能发生在整个应用领域,或者发生在类似但横跨不同的应用领域。
在需求模型的描述中最基本的元素是用例。一套连贯用例可以成为服务于发现一个或多个分析模式的基础。
第十一章 设计概念
软件设计在软件工程过程中属于核心技术,它的应用与所使用的软件过程模型无关。
软件设计时建模活动的最后一个软件工程活动,接着便要进入构建阶段(编码与测试)
软件工程中的设计
四种设计模型
- 构建级设计
- 接口设计
- 体系结构设计
- 数据/类设计
-
数据/类设计
将类模型转化为设计类的实现以及软件实现所要求的数据结构
-
体系结构设计
软件的整体结构
定义了软件的主要结构化元素之间的关系、可满足系统需求的体系结构风格和模式以及影响体系结构实现方式的约束,体系结构设计可以从需求模型导出
-
接口设计
描述了软件和协作系统之间、软件和使用人员之间是如何通信的,使用场景和行为模型为接口设计提供了大量的信息
-
构件级设计
完整的描述每个软件构件的内部细节
将软件体系结构的结构化元素变换为对软件构建的过程性描述,从基于类的模型和行为模型中获得的信息是构件设计的基础
设计过程
质量指导
整个设计过程中,我们使用一系列技术评审来评估设计演化的质量,良好设计演化的三个特征:
- 设计应当实现所有包含在需求模型中的明确需求和利益相关者期望的隐含需求
- 设计应当是可读的,可理解的指南
- 提供软件的全貌
质量属性
软件质量属性FURPS体现了所有软件设计的目标
- 功能性
- 易用性
- 可靠性
- 性能
- 可支持性
【注】并不是每个软件质量属性都具有相同的权重
重要的是:设计开始时就应该考虑这些质量属性,而不是设计完成后和构建已经开始时才考虑
设计概念
抽象
分为两种不同的抽象:
- 数据抽象 描述数据对象的具体数据集合e.g 门
- 过程抽象 具有明确和有限功能的指令序列 e.g 打开
体系结构
软件的体系结构指的是:
- 软件的整体结构
- 这种结构为系统提供概念完整性的方式
软件体系结构设计的一组属性
- 结构特性
- 外部功能特性
- 相关系统族
【注】ADL:体系结构描述语言
模式
设计模式描述了解决某个特定设计问题的设计结构,该设计问题处在一个特定环境中,该环境会影响到模式的应用和使用方式
设计模式的目的:
提供一种描述,使得设计人员可以决定:
- 模式是否适用于当前的工作
- 模式是否能够复用
- 模式是否能够用于指导开发一个相似但功能或结构不同的模式
关注点分离
将关注点分割为更小的关注点,以便于用更小的工作量和时间解决一个问题
分而治之
模块化
关注点分离最常见的表现
按照设计原则将系统划分为若干个较小的模块
- 模块间相互独立,又相互关联
- 实质:系统分解和抽象的过程
能否无限制划分软件???答案:否
信息隐蔽原则:
每个模块对其他所有模块都隐蔽自己的设计决策
由于大多数数据和过程对软件的其他部分是隐蔽的,因此,在修改过程中不小心引入的错误就不太可能传播到软件的其他地方
信息隐蔽是实现抽象/模块化机制的基本支撑
优点:
- 对外隐蔽,减少副作用的可能性;
- 强调通过控制接口进行通信;
- 不鼓励使用全局数据;
- 使用封装——高质量的设计的一个属性;
- 使得产生高质量软件。
功能独立
关注点分离,模块化,抽象和信息隐蔽概念的直接产物
通过开发具有“专一”功能和“避免”与其他模块过多交互的模块,可以实现功能独立
两条标准进行评估:
-
内聚性:显示了某个模块相关功能的强度
一个内聚的模块应该只完成一件事情。应该避免“分裂型”构件
内聚的七个层次:
- 巧合
- 逻辑
- 时间
- 过程
- 通信
- 顺序
- 功能
-
耦合性:显示了模块之间的相互依赖性
表明软件结构中多个模块之间的相互连接。
简单的连接性使得软件易于理解并减少“涟漪效果“的倾向
耦合的七个层次
- 内容
- 公共
- 外部
- 控制
- 标记
- 数据
- 非直接
软件设计时,尽量做到高内聚,低耦合
求精
求精:对各种抽象的细化
抽象和细化是互补的概念
- 抽象能够说明内部过程和数据,但对外部使用者隐藏了底层的细节
- 细化有助于在设计过程中揭示底层细节。
↑两个概念均有助于设计人员在设计演化中构建出完整的设计模型
重构
为简化设计而进行的重组
设计类
- 用户接口类
- 业务域类
- 过程类
- 持久类
- 系统类
组织良好的设计类的四个特征:
- 完整性与充分性
- 原始性
- 高内聚性
- 低耦合性
设计模型
两个维度:过程维度、抽象维度
四个主要元素:数据,体系结构,构件,接口
设计元素
-
数据设计元素——
- 数据模型->数据结构/数据库体系结构/数据仓库
-
体系结构设计元素
- 提供软件的整体视图
-
接口设计元素——UML类图中的接口
-
构件级设计元素——UML构建图
-
部署级设计元素——UML部署图
第十二章 体系结构设计
什么是体系结构
指的是系统的一个或者多个架构,包括软件构件、构件的外部可见属性以及他们之间的相互关系
体系结构类型
类型经常会规定特定的体系结构方法
类型隐含了在整个软件领域中的一个特定类别
体系结构风格
软件体系结构风格,每种风格描述一种系统类别,包括四个关键元素
- 一组构件,它们完成系统需要的某种功能
- 一组连接件,它们实现构件间的 “通信、合作和协调”
- 约束,定义构件如何集成为一个系统
- 语义模型,使设计者能通过分析系统的组成成分的已知属性,来理解系统的整体性质
### 体系结构模式
风格的具体体现(体系结构设计的一个框架)
区别:
(1)体系结构模式涉及的范围要小一些,它更多集中在体系结构的某一局部而不是体系结构的整体
(2)模式在体系结构上施加规则,描述了软件是如何在基础设施层次上处理某些功能性方面的问题
(3)体系结构模式倾向于在系统结构的环境中处理特定的行为问题
体系结构风格的简单分类
以数据为中心的体系结构
数据存储位于这种体系结构的中心,其他构建会经常访问该数据存储,并进行增删改查。
特点:
- 一些数据(比如一个文件或者数据库)保存在整个结构的中心,并且被其他部件频繁地使用、添加、删除、或者修改
- 提升可集成性,即现有的构件可以被修改而且新的客户构件可以加入到系统结构中,而无需考虑其他的客户。
- 数据可以在客户间通过“黑板”机制传送,客户构件独立地执行过程。
【注】黑板:当用户感兴趣的数据发生变化时,他讲通知客户软件
优点:
- 开放:数据对所有使用者开放
- 客户构件基本独立
问题:
- 客户软件难以协作
- 中心数据的格式必须为所有客户软件所接受
数据流体系结构
特点:
- 过滤器没有必要了解与之相邻的其他过滤器的工作
- 数据需要服从输入——变换——输出的简单流程
优点:
- 易于理解
- 过滤器易于重用
- 系统易维护
- 易并行运行
问题:
- 适用于批处理,不易于交互
- 流的协作需要考虑
- 过滤器功能重复
调用和返回体系结构
能够设计出一个相对易于修改和扩展的程序结构
存在子风格:
-
主程序/子程序体系结构
将功能分解为一个控制层次结构,其中主程序调用一组程序构件,程序构件又去调用别的程序构件
-
远程调用体系结构
构件分布在网络的多个计算机上
面向对象体系结构
- 系统的构件封装了数据和应用到该数据上的操作。
- 构件间通过消息传递进行通信与合作。
层次体系结构
- 定义了不同的层次,各个层次完成各自的操作
- 每一层为上层提供服务,又接受下层的服务
优点:
- 明确的抽象层次,易于增减或修改层次
问题:
- 系统并不是总能分层
体系结构模式
体系结构模式:体系结构模式在特定坏境和一系列限制与约束下处理特定的应用问题。
模式提出了能够作为体系结构设计基础的体系结构解决方案
体系结构的考虑要素
- 经济型
- 易见性
- 隔离性
- 对称性
- 应激性
体系结构设计
系统环境表示
在体系结构设计层,软件体系结构设计师用体系结构环境图ACD对软件与其外围实体的交互方式进行建模
ACD例子:
定义原型
将体系结构细化为构件
构件的来源:
- 应用领域:需求分析模型中的类
- 基础设施域:内存管理,通信构件,数据库构件等
- 界面领域:环境图中描述的接口隐含多个特定的构件
每一个顶层构件都必须经过反复的迭代精化
要会画UML构件图
体系结构评审
一种特定的技术性评审,提供了一种评估方法,该方法可以评估软件体系结构满足系统质量需求的能力和识别任何潜在风险的能力。
往往只设计软件工程团队成员
评审技术:
- 基于经验的推理
- 原型评估
- 情境评审
- 检查单的使用
经验学习
用决策分析和解决方案(DAR)有助于消除分歧和促成协作
- 原因链法
- 石川鱼骨法
- 思维导图
基于模式的体系结构评审(PBAR)
用于应对短暂的开发周期、紧迫的交付日期、反复变更的需求以及小规模的开发团队
体系结构一致性检查
静态体系结构一致性分析——评估已完成的软件系统是否与它的体系结构模型相符合
第十七章 软件测试策略
软件测试策略包括
- 测试计划
- 测试用例设计
- 测试执行
- 测试结果数据的收集与评估
软件测试的策略性方法
测试策略必须提供
-
低级测试,来验证一小段代码是否正确实现
-
高级测试,确认系统的主要功能是否满足用户需求
测试策略为
- 专业人员提供工作指南
- 管理者提供一系列里程碑
测试进度必须是可度量的,并且使问题尽可能早的暴露
软件开发人员对负责程序各个单元的测试
在软件体系结构完成后,独立测试组ITG开始介入
软件测试策略——宏观
螺旋模型:
软件过程:沿着螺旋向内,分别为系统工程,需求,设计,编码,每走一圈都会降低软件的抽象层次
测试策略:单元测试其实与螺旋的中心,往外是集成测试,确认测试,系统测试
- 单元测试:
- 集成测试:处理并验证与程序构建相关的问题
- 确认测试:为软件满足所有的功能,行为和性能需求提供最终保证
测试完成的标准
测试永远也完不成~~~
傻了吧
策略问题
成功的测试策略
-
早在开始测试之前,就要以量化的方式规定产品需求
-
明确地陈述测试目标
-
了解软件的用户并为每类用户建立用户描述
-
制定强调“快速周期测试”的测试计划
-
建立能够测试自身的“健壮”软件
-
测试之前,利用有效的正式技术评审作为过滤器
-
实施正式技术评审以评估测试策略和测试用例本身
-
为测试过程建立一种持续的改进方法
传统软件的测试策略
单元测试
侧重于软件设计的最小单元的验证工作
对模块的五个基本特性进行评价:
- 模块接口:保证被测程序单元的信息能够正常的流入和流出
- 局部数据结构:确保临时存储的数据在算法的整个执行过程中能维持其完整性
- 边界条件:达到边界值还能正确执行
- 独立路径:确保模块的所有语句至少执行一次
- 错误处理路径
最基本的任务:选择测试的执行路径
最重要的单元测试任务之一:边界测试
模块结构测试是基础
特点:
- 侧重于软件设计的最小单元的验证工作
- 侧重于构件中的内部处理逻辑和数据结构
- 进行的越早越好
何时进行单元测试?
通常在编码完成后进行
前期应提前准备:单元测试计划,编写测试用例,单元测试代码
↑一般由白盒测试工程师,开发人员完成
依据:源程序/项目的《详细设计》文档
一般步骤:
- 编译运行,进行语法正确性验证
- 静态测试,检查代码是否符合规范
- 动态测试,深入检查代码的正确性、容错性和边界值
集成测试
集成测试指将通过测试的单元模块组装成系统或子系统,再进行测试
内容
- 单元组装后的功能正确性
- 单元之间的接口
- 集成后的系统性能
分类:
- 一步到位的集成
- 增量集成
- 自顶向下测试
- 自底向上测试
- 组合方法(三明治):用自顶向下方法测试程序结构较高层,用自底向上方法测试其从属层
一步到位的集成
缺点:
- 需要所有单元就绪,不利于开发进度
- 问题定位较为困难
但是适合规模较小的应用
增量式测试
特点:
- 集成是逐步实现的
- 逐次将未曾集成测试的模块和已经集成测试的模块结合成程序包,再将这些模块集成为较大的系统
- 不需要所有单元就绪
- 适合规模较大的应用
- 相比于非增量测试有一定优越性
自顶向下法
首先集成主控模块,然后依照控制层次向下进行集成
策略有:广度优先,深度优先
特点:
- 可能要编写很多桩程序
- 主控模块错误可能发现的比较早
主控模块用作测试驱动模块,一次用一个实际模块替换一个桩模块
自底向上法
从程序模块结构的最底层的模块开始组装和测试
特点:
- 不需要桩模块
- 要写驱动模块
- 主控模块错误发现得比较迟
如果最上两层是自顶向下集成的,可以减少驱动模块的数量(组合方法)
回归测试
在程序有修改的情况下,保证原有功能正常的一种测试策略
冒烟测试——常用的集成测试方法
冒烟测试是时间关键项目的决定性机制
活动:
- 将已经转化成代码的软件构件集成到构建中
- 设计一系列测试以暴露影响构建正确完成其功能的错误
- 每天将构建与其他构建以及整个软件产品集成起来进行冒烟测试
好处
- 降低了集成风险
- 提高最终产品的质量
- 简化错误的诊断和修正
- 易于评估进展情况
面向对象软件的测试策略
面向对象环境中的单元测试
不再孤立地对单个操作进行测试 (传统的单元测试观点),而是将操作作为类的一部分
面向对象软件的类测试等同于传统软件的单元测试
面向对象环境中的集成测试
两种策略:
-
基于线程的测试
对响应系统的一个输入或事件所需的一组类进行集成。每个线程单独地集成和测试。应用回归测试以确保没有产生副作用
-
基于使用的测试
通过测试很少使用服务类的那些类(称为独立类)开始构造系统
独立类测试完成后,利用独立类测试下一层次的类(依赖类)
继续依赖类的测试直到完成整个系统
确认测试
始于集成测试的借书
测试集中于用户可见的动作和用户可识别的系统输出
系统测试
包含恢复测试,安全测试,压力测试,性能测试,部署测试
调试技巧
调试是使错误消除的过程,发生在测试之后
调试方法
- 蛮干法
- 回溯法
- 原因排除法
第十八章 测试传统的应用软件
软件测试基础
测试的目标:发现错误
黑盒测试:在软件接口处执行测试——检查系统的功能方面,而不考虑软件的内部结构(外部观察)
白盒测试:基于过程细节的封闭检查,贯穿软件的逻辑路径和构件间的协作(内部观察)
白盒测试
一种测试用例设计方法,一般在测试的早期进行
利用构件级设计的一部分所描述的控制结构来生成测试用例
利用白盒测试导出的测试用例可以:
- 保证一个模块的所有独立路径至少被执行一次
- 对所有的逻辑判定均需测试取真和取假两个方面
- 中上下边界以及可操作的范围内执行所有循环
- 检验内部数据结构以确保其有效性
基本路径测试
一种白盒测试技术
流图
- 合并顺序执行的语句
- 分离判定语句的不同条件
环路复杂性
-
V(G)=E-N+2
E是流图的边数,N是流图的节点数
-
域的数量=环复杂性
-
V(G)=P+1
P为包含在流图G中的判定节点数
↑V(G)的值提供了组成基本集合的独立路径的上界,并由此得出覆盖所有程序语句所需设计和运行的测试数量的上界
导出测试用例的步骤
- 画出流图
- 确定环复杂性,确定线性独立路径的数量
- 确定独立路径的基本集合
- 准备测试用例集,强制执行基本集合中的每条路径
控制结构测试
略
第二十五章 项目进度安排
### 挣值分析
按如下步骤确定挣值
-
为进度表中的每一个工作任务确定其预计工作的预算成本(BCWS)
-
将所有BCWS值加起来,可计算出完成工作的预算(BAC)
-
计算已完成工作的预算成本(BCWP),即该时间点已经实际完成的所有工作任务的BCWS的和
可以得到:
进度表执行指标SPI=BCWP/BCWS(效率指标,越接近1.0则效率越高)
进度表偏差SV=BCWP-BCWS(只表示与计划进度的偏差)
预计完成百分比值:BCWS/BAC(应该完成的)
特定时间实际完成工作的百分比值:BCWS/BAC(注意这里的BCWS和上面的不一样)
-
计算出已完成工作的实际成本ACWP
字如其名
成本执行指标CPI=BCWP/ACWP(越接近1.0表示项目与预算越接近)
成本偏差CV=BCWP-ACWP(表示在项目特定阶段的成本节省或短缺)
第二十六章 风险管理
风险管理策略:
- 主动风险策略
- 被动风险策略(印第安纳·琼斯)tmd,xs
工作产品:RMMM计划或者一组风险信息表单
RMMM:
- 风险缓解
- 检测
- 管理
软件风险
特性:
- 不确定性(不一定会发生)
- 损失(一旦发生就会产生恶心后果或损失)
风险类型:
-
项目风险
威胁到项目计划。
指预算、进度、人员、资源、利益相关者、需求等方面的潜在问题以及他们对软件项目的影响
-
技术风险
威胁到要开发软件的质量和交付时间。
指设计、实现、接口、验证和维护等方面潜在的问题
-
商业风险
威胁到要开发软件的生存能力
又分为:
- 市场风险
- 策略风险
- 销售风险
- 管理风险
- 预算风险
另一种风险分类方式:
-
已知风险
仔细评估项目计划、开发项目的商业及技术环境以及其他可靠的信息来源之后可以发现的那些风险
-
可预测风险
从过去的项目经验推断来的风险
-
不可预测风险
可能出现但是难以识别的风险
实施有效风险管理框架的七项原则
- 保持全面的观点
- 采用长远的观点
- 鼓励广泛交流
- 结合:考虑风险时必须与软件过程相结合
- 强调持续过程
- 开发共享的产品
- 鼓励协同工作
风险识别
上面的每一类风险又可以分为两种不同的类型
- 一般风险
- 产品特定的风险
识别方法
建立风险条目检查表,用于风险识别,主要用于识别下列几种类型中的一些已知/可预测风险
- 产品规模
- 商业影响
- 客户特性
- 过程定义
- 开发环境
- 开发技术
- 人员才干与经验
风险因素和驱动因子
项目管理者要识别印象软件风险因素的风险驱动因子
风险因素:
- 性能风险
- 成本风险
- 支持风险
- 进度风险
风险驱动因子对风险因素的影响
- 可忽略的
- 轻微的
- 严重的
- 灾难性的
风险预测
试图从两个方面来评估每一个风险
- 风险发生的可能性或概率
- 如果风险发生,风险相关问题产生的后果