开发和维护
软件常常是不可维护的
软件通常没有适当的文档资料
软件成本在计算机系统总成本中所占比例逐年上升
软件开发生产率提高的速度,既跟不上硬件的发展速度,也远远跟不上计算机应用迅速普及深入的趋势
等……
(1)与软件本身的特点有关
软件是指逻辑部件,可见性差
管理和控制软件开发很困难
客观上软件维护比较困难
不同于程序,规模庞大,需要人员协作和科学管理
(2)与软件开发与维护的方法不正确有关
采用了错误的方法和技术
忽视软件需求分析的重要性,过早地开始编码工作
轻视软件维护的重要性
(3)软件是有生命周期
软件从定义、开发、使用、维护到终止的时期
消除软件危机
(1)对软件有一个正确的认识
软件=程序+方法+规则+数据+文档
软件文档:在软件开发中产生的,开发、使用和维护程序所需要的图文资料。用户文档和系统文档
(2)软件开发应该组织良好、管理严密、协调配合
(3)推广使用成功的技术和方法
(4)应用开发和使用好的软件工具
软件工程是从(技术)和(管理)两方面研究如何更好地开发和维护计算机软件的一门新兴学科。生命周期方法学的目的和实质是控制开发工作的(复杂性),通过有限的确定步骤,把用户需求从抽象的逻辑概
念转化为具体的物理实现。
软件工程的基本目标:开发高质量的软件
软件工程就是为了经济地获得可靠的且能在实际机器上有效运行的软件,而建立和使用完善的工程原理
软件工程是(1)把系统的、规范的、可度量的途径应用于软件开发、运行和维护的过程;(2)研究(1)中提到的途径
1.用分阶段的生命周期计划严格管理
2.坚持进行阶段评审
3.实行严格的产品控制
4.采用现代程序设计技术
5.结果应能清楚的审查
6.开发小组的人员应少而精
7.承认不断改进软件工程实践的必要性
方法学(methodology):指在软件生命周期全过程中使用的一整套技术的集合,也称为范型(paradigm)
包括三个要素,这就是方法、工具和过程
方法是完成软件开发的各项任务的技术方法,回答“如何做”的问题
工具是为方法的运用提供自动的或半自动的软件支撑环境
过程是为了获得高质量的软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。
又称,生命周期方法或结构化范型
将软件过程依次分成若干阶段
按顺序开展每个阶段的任务
每个阶段进行严格的技术审查和管理复审
提交“最新的”文档
优点
通过将软件生命周期划分成若干个阶段降低了整个软件开发过程的困难程度;
每个阶段结束前的严格审查保证了软件的质量,提高了软件的可维护性
缺点
当软件规模庞大,或者对软件的需求是模糊的或会随时间而变化的时候,使用传统方法学开发软件往往不成功,而且维护起来仍然很困难。
原因:把数据和操作人为地分离成了两个独立的部分。(只能面对行为或者面对数据,不能兼得)
出发点和基本原则:模拟人类认识和解决问题的方法和过程
主动反复迭代的演化过程
把数据和行为封装在一起
面向对象方法=对象+类+继承+消息通信
4个要点
把对象(Object)作为融合了数据及在数据上的操作行为的统一软件构件
把所有对象都划分成类(Class)
按照父类(或称基类)与子类(或称派生类)的关系,把若干个相关类组成一个层次结构的系统(也称为类等级)
对象彼此间仅能通过发送消息互相联系
优点
降低了软件产品的复杂性
提高了软件的可理解性
简化了软件的开发和维护工作
促进了软件重用
阶段间具有顺序性和依赖性
清楚地区分逻辑设计与物理设计,尽可能推迟程序的物理实现的观点
质量保证的观点:每个阶段都必须完成规定的文档,没有交出合格的文档就是没有完成该阶段的任务;每个阶段结束前都要对所完成的文档进行评审(也是优点)
优点
可强迫开发人员采用规范的方法;
严格地规定了每个阶段必须提交的文档;
要求每个阶段交出的所有产品都必须经过质量保证小组的仔细验证。
缺点
“瀑布模型是由文档驱动的”,缺乏灵活性:
仅通过静态的规格说明很难全面正确地认识动态的软件产品。
要求用户不经过实践就提出完整准确的需求是不切实际的。
由于瀑布模型完全依赖于书面的规格说明,很可能导致最终开发出的软件不能真正满足用户的需要。
优点:
有助于获取用户需求,加强对需求的理解
尽早发现软件中的错误
支持需求的动态变化
缺点:
不能支持风险分析
是为获得高质量软件所需完成的一系列任务的框架,他规定了完成各项任务的工作步骤
定义了运用方法的顺序、应交付的文档、所需采取的管理措施,以及标示阶段任务的里程碑
通常使用生命周期模型简洁地描述软件过程
Rational公司推出的一种完整的软件过程
迭代开发(可交付版本)
管理需求(用例分析来捕获需求)
使用基于构件的体系结构
可视化建模(UML)
验证软件质量(内建的质量评估过程)
控制软件变更
(1)客户作为开发团队成员(On Site Customer)
(2)计划博弈(Planning Game)
要求结合项目进展和技术情况,确定下一阶段要开发与发布的系统范围
(3)系统隐喻(System Metaphor)
通过隐喻来描述系统如何运作、新的功能以何种方式加入到系统。它通常包含了一些可以参照和比较的类和设计模式
(4)简化设计(Simple Design)
(5)集体拥有代码(Collective Code Ownership)
(6)结对编程(Pair Programming)
(7)测试驱动(Test-driven)
(8)小型发布(Small Releases)
(9)重构(Refactoring)
代码重构是指在不改变系统行为的前提下,重新调整、优化系统的内部结构以减少复杂性、消除冗余、增加灵活性和提高性能。
(10)持续集成(Continuous integration)
提倡在一天中集成系统多次,而且随着需求的改变,要不断的进行回归测试。
(11)代码规范(Coding Standards)
(12)每周40小时工作制 ( 40-hour Week )
实质:一次简化、压缩了的需求分析和设计过程
技术可行性:e.g从软件的功能可行性考虑
经济可行性
操作可行性
1、复查系统规模和目标
2、研究目前正在使用的系统
3、导出新系统的高层逻辑模型
4、进一步定义问题
5、导出和评价供选择的解法
6、推荐行动方针
7、草拟开发计划书
8、书写文档提交审查
描绘物理系统的传统工具,包括程序、文档、数据库和人工过程等
它表达了数据在系统各部件之间的流动情况,≠控制、处理信息(不同于程序流程图)
是系统逻辑功能的图形表示,是一种分析员与用户极好的通信工具
左下数据字典的符号
货币的时间价值
投资回收期:使累计的经济效益等于最初投资所需要的时间
纯收入
投资回收率j:投资回收率等于银行的年利率,则此系统没有必要开发,因为它不能增加收入。所以只有投资回收率大于年利率时,才考虑开发问题。
现在的投资额P=F1/(1+j)+F2/(1+j)2+…+Fn/(1+j)n
Fn表示第n年底的效益,一般设生命周期为5年
要求编写的文档:需求规格说明书、(初步的)用户使用手册、确认测试计划
获取需求的方法:访谈、面向数据流自顶向下求精,快速建立软件原型、应用规格说明技术
常用的需求分析的方法 :
面向数据流的结构化分析方法
面向数据结构
对象
1.功能要求:划分出系统必须完成的所有功能
2 性能要求:系统必须满足的定时约束或容量约束
例如:速度(系统的响应时间)、信息速率、主存容量、磁盘容量、安全性
3 运行要求(可靠性和可用性需求):运行环境、软硬件配置等可靠性和可用性需求(量化了用户可以使用系统的程度)
4 出错处理需求:说明系统对环境错误应该怎样响应,对应用系统本身错误的检测应该仅限于系统的关键部分,而且应该尽量少
5 接口需求:描述与环境通信的格式,e.g:用户接口需求、 硬件接口需求、 软件接口需求、 通信接口需求
6 约束:用户和环境强加给项目的限制条件含:精度、工具和语言约束、设计约束、使用标准、使用硬件平台
7 逆向需求:说明软件系统不应该做什么
8 将来可能提出来的需求
需求分析借助于当前系统的逻辑模型导出目标系统的逻辑模型,解决目标系统“做什么”的问题
建立数据又称"信息"(E-R图)、功能(数据流图、数据字典)、行为(状态转换图)三种模型,主要的处理算法描述逻辑模型(IPO),写出软件需求规格说明书(用自然语言完整、准确、具体描述需求分析的任务)
当数据模型达到3NF,一般情况下就能满足数据库应用的需要
也参看上面的 逻辑设计:关系数据库规范化 软设考点
也参看上面的 3.1概念模型(人)【e.g:E-R模型】软设考点
IPO图是输入/处理/输出图的简称,
由美国IBM公司发展完善起来的一种图形工具
为模块写的处理说明及接口说明
改进样式
一致性:在所有需求中,任何一条需求不能和其他需求互相矛盾。(形式化描述)
完整性:软件规格说明书必须包括用户需求的每一个功能或性能。(原型)
现实性:指定的需求应是用现有的硬件技术和软件技术可以实现的。(仿真和模拟)
有效性:软件需求确实能解决用户所面对的问题。(原型)
软件设计涉及软件的结构、过程(模块的操作细节)、和模块的设计。模块的内部过程描述就是模块内部的(算法设计),它的表达形式就是详细设计语言
面向数据流的设计是以需求分析阶段产生的数据流图为基础,按一定的步骤映射成软件结构,因此又称为结构化设计
逐步求精:人类解决复杂问题时所采用的的基本方法,也是很多软件工程技术(e.g:规格说明技术、设计和实现技术)的基础
抽象:把这些相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。
模块化:就是把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。
信息隐蔽原理:设计和确定模块时,一个模块内包含的信息(过程或数据)对于不需要这些信息的模块来说,是不能访问的
局部化:是把一些关系密切的软件元素物理地放得彼此靠近。显然, 局部化有助于实现信息隐藏
模块独立性的概念是模块化、抽象化、信息隐蔽概念的一个直接产物
模块的独立程度可以由两个定性标准度量,这两个标准分别称为内聚和耦合
是对一个软件结构内不同模块之间互连程度的度量
(1) 内容耦合: 一个模块直接影响另一个模块,调用或操纵其他模块的数据
如果发生下列情形,两个模块之间就发生了内容耦合 :
一个模块直接访问另一个模块的内部数据;
一个模块不通过正常入口转到另一模块内部;
两个模块有一部分程序代码重迭(只可能出现在汇编语言中);
一个模块有多个入口。
(2) 公共耦合:若一组模块都访问同一个公共数据环境,则它们之间的耦合就称为公共耦合。公共的数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。
复杂度与模块数成正比。
(3) 外部耦合: 一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息,则称之为外部耦合。
(4) 控制耦合:如果一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能。(多余,适当分解用数据耦合替之)
功能代码属于控制元素,传递功能代码==控制耦合
(5) 标记耦合:一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构的子结构,而不是简单变量。
标记耦合与数据耦合形式相同,区别在于调用时传递的参数是否为基本数据类型
(6) 数据耦合:一个模块访问另一个模块时,彼此之间是通过简单数据参数 (不是控制参数、公共数据结构或外部变量) 来交换输入、输出信息的。
特征耦合:只使用传进来的部分参数
(7) 非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。
尽量使用数据耦合
少用控制耦合和特征耦合
限制公共环境耦合的范围
完全不用内容耦合
标志着一个模块内各个元素彼此结合的紧密程度
实践表明内聚更重要,应该把更多注意力集中到提高模块的内聚程度上
偶然内聚->逻辑内聚->时间内聚->过程内聚->通信内聚->顺序内聚->功能内聚
偶然内聚:如果一个模块完成一组任务,这些任务彼此间即使有关系,关系也是很松散的,就叫做偶然内聚
逻辑内聚
时间内聚
过程内聚:如果一个模块内的处理元素是相关的而且以特定次序执行,则称为过程内聚。
通信内聚:如果模块中所有元素都使用同一个输入数据和(或)产生同一个输出数据,则称为通信内聚。
例如,一个模块的功能是从输入的文件中读出数据,然后由这些数据产生报表,同时也由这些数据产生单项报表。
例如:从同一磁带上读取不相干的数据 —— 可能破坏独立性
顺序内聚
功能内聚
(1)提高模块独立性
(2)模块规模适中
(3)选择适当的深度、宽度、扇出和扇入
对宽度影响最大的因素是模块的扇出(直接控制、调用的模块数,最好3-4)
扇出太大,可以适当增加中间层次的控制模块。
扇出太小,可以把下级模块进一步分解成若干功能模块或者合并到上级去。
好的软件结构顶层扇出比较高,中层扇出较少
(4)模块的作用域应在其控制域之内
模块的作用域:受模块判定条件影响的所有模块集合
模块的控制域:模块本身以及所有直接从属模块的集合
(5)降低接口的复杂程度
(6)单出单入,避免内容耦合
(7)模块功能可预测
相同输入必产生相同输出
反例:模块中使用全局变量或静态变量,则可能导致不可预测
SD:Structural Design
面向数据流的设计方法把信息流映射成软件结构。
信息流有下述两种类型
变化流:信息通常以“外部世界”的形式进入软件系统,经过处理以后再以“外部世界”的形式离开系统
事务流:数据沿输入通路到达一个处理T,这个处理根据输入数据的类型在若干动作序列中选出一个执行
详细设计的任务是确定每个模块的(内部特性)
软件详细设计的目标不仅是逻辑上正确地实现每个软件模块的功能,还应使软件设计的处理过程清晰易懂
数据元素彼此间的逻辑关系有顺序、选择和重复
只允许使用顺序、IF-THEN-ELSE分支和DO-WHILE型循环这三种基本控制结构,称为经典的结构程序设计
还允许使用DO-CASE多分支结构和DO-UNTIL循环结构,称为扩展的结构程序设计
如果再加上允许使用LEAVE(或BREAK)结构,称为修正的结构程序设计
系统响应时间
用户帮助设施
出错信息处理
命令交互
流程图的缺点
本质上不支持逐步求精:过早考虑控制流程而非全局结构
流程图中的流线转移方向任意;可能破坏单入、单出程序结构
不适于表示数据结构和模块调用关系
对于大型软件而言过于琐碎,不易阅读和修改。
见 McCabe度量法
测试部分参考测试
需求分析-对应-确认测试(需求规格说明书为基础)
设计-集成测试
编码-单元测试
1.程序内部的文档:标识符、注释、程序视觉组织
注释分为序言性注释和功能性注释两类。
2.数据说明:次序、注解
3.语句构造
4.输入输出
5.效率:程序运行时间、存储器、IO
暴露程序中的错误
测试方法:黑盒(功能)测试、白盒(结构)测试
1.模块(单元)测试
2.子系统测试:接口的错误
3.系统测试:软设、需求说明中的错误
4.验收(确认)测试:需求说明中的错误
5.平行运行
测试用例
自顶向下集成
优:较早地验证了主要功能,早期即可发现上层错误;无需测试驱动程序,只需一个驱动,减少驱动器开发的费用。
缺:需要存根程序,柱的开发量大;底层验证被推迟;底层组件测试不充分。
适应于产品控制结构比较清晰和稳定;高层接口变化较小;底层接口未定义或经常可能被修改;产口控制组件具有较大的技术风险,需要尽早被验证;希望尽早能看到产品的系统功能行为。
自底向上集成反之
适应于底层接口比较稳定;高层接口变化比较频繁;底层组件较早被完成。
参考2.2.2 白盒检测【结构检测】
环形复杂度=独立路径数
纠错,发生在测试之后
蛮干法、回溯法、原因排除法(对分查找发、归纳法、演绎法)
提高软件质量和可靠性的技术:避开错误+容错
软件可靠性:程序在给定的时间间隔内,按照规格说明书的规定成功地运行的概率
软件可用性:程序在给定的时间点,按照规格说明书的规定成功地运行的概率
软件维护:在软件已经交付使用之后,为了改正错误或满足新的需要而修改软件的过程。
软件可维护性:维护人员理解、改正、改动和改进这个软件的难易程度
按多到少
完善性:为了增加新功能,修改已有功能,改造界面,增加HELP等,而修改软件
适应性:变化了的环境(如软\硬件升级、新数据库等)适当地配合而修改软件
改正性
预防性
结构化与非结构化维护差别很大
维护的问题很多
库存目录分析
文档重构
逆向工程
代码重构
数据重构
正向工程
参考 大概看一下
解空间对象:计算机中的实体(取决于语言)
e.g:汇编语言-存储单元、面向过程语言-预定义类型的变量数组记录文件
消息:要求某个对象执行在定义他的类中所定义的某个操作的规格说明。
多态性:类的不同层次中共用一个方法
e.g:c++,虚函数,动态(滞后)联编
重载
e.g:c++,静态(先前)联编
对象是面向对象开发方法的基本单位,它是一组 (属性) 和它可以执行的一组 (操作) 的封装体。应用执行对象的 (操作/方法) 可以改变该对象的 (属性/状态) 。
顺序图与通信图统称交互图,通信图(协作图)相较顺序图少了对时间的描述
UML 表述的动态模型中,顺序图描述对象之间的 (动态交互) ,重点体现对象间消息传递的(时间顺序)。
UML是面向对象设计的建模工具,独立于任何具体程序设计语言
通过计划、组织和控制等一系列活动,合理地配置和使用各种资源,以达到既定目标的过程
代码行技术:较简单的定量估算软件规模的方法
输入项数(Inp):用户向软件输入的项数,这些输入给软件提供面向应用的数据。
输出项数(Out):软件向用户输出的项数,它们向用户提供面向应用的信息,例如,报表和出错信息等。报表内的数据项不单独计数。
查询数(Inq):查询即是一次联机输入,它导致软件以联机输出方式产生某种即时响应。
主文件数(Maf):逻辑主文件(即数据的一个逻辑组合,它可能是大型数据库的一部分或是一个独立的文件)的数目。
外部接口数(Inf) :机器可读的全部接口(例如,磁盘或磁带上的数据文件)的数量,用这些接口把信息传送给另一个系统。
不能显示表示依赖关系
难以判断主攻、主控
软件配置管理:是在软件的整个生命期内管理变化的一组活动。
具体地说,这组活动用来:
①标识变化;
②控制变化;
③确保适当地实现了变化;
④向需要知道这类信息的人报告变化
软件配置管理主要有5项任务:标识、版本控制、变化控制、配置审计和报告
软件过程的输出信息可以分为3类:
计算机程序(源代码和可执行程序);
描述计算机程序的文档(供技术人员或用户使用);
数据(程序内包含的或在程序外的)。
把它们统称为软件配置,而这些项就是软件配置项。
基线:通过了正式复审的软件配置项
COCOMO2模型
COCOMO是构造性成本模型(constructive cost model)的缩写
三个层次的估算模型分别是
应用系统组成模型
这个模型主要用于估算构建原型的工作量,模型名字暗示在构建原型时大量使用已有的构件。
早期设计模型
这个模型适用于体系结构设计阶段。
后体系结构模型
这个模型适用于完成体系结构设计之后的软件开发阶段。
CMM
能力成熟度的5个等级从低到高依次是
初始级(又称为1级),
可重复级(又称为2级)
已定义级(又称为3级),
已管理级(又称为4级)
优化级(又称为5级