本提纲可以完全摘抄,考试命中率100%,先上考试带的A4纸:
CASE
将各种软件工具、开发机器和一个存放开发过程信息的工程数据库组合起来形成一个软件工程环境;按照项目的进度、成本和质量限制,开发和维护满足用户需求的软件所必需的一组有序的软件开发活动集合。
不仅仅是一个简单的软件过程,而是一个通用的过程框架,可用于不同类型的应用系统,它是基于构件的,所构造的软件系统是由软件构件通过明确定义的接口相互链接所建造起来的。并且它使用 UML
语言来制定系统的所有蓝图。
软件过程模型是软件开发全过程中软件开发活动以及它们之间关系的结构框架,用于指导软件的开发。常用的软件过程模型有:
瀑布模型将开发阶段描述为从一个阶段瀑布般地转换到另一个阶段,一个阶段必须在另一个阶段开始之前完成,每一个阶段都伴随着定义明确的里程碑和可交付产品。顺序为:
优点:中间产品和接口的定义明确,开发人员可以专注于完成每一个小的阶段,测试和审核流程完备,系统整体质量高;
缺点:缺乏灵活性,速度慢,不能反映实际的代码开发方式;对开发人员的要求很高,必须在项目开始前说明全部需求;最终产品直到最后才出现,而软件客户无法在早期直到软件原型。
适用场合:①有稳定的产品定义和需求分析;②容易理解但很复杂的项目;③质量需求高于成本需求和进度需求;④开发团队的技术力量较弱或缺乏经验。
开发人员在与用户进行需求分析时,以较小代价快速建立一个能反映用户需求的原型系统,综合用户的意见对原型系统进行完善,然后再由用户评价,重复这一过程直到用户满意,再开始正式设计。
优点:符合人们认识事物的规律,缩短了用户和开发人员之间的距离,确保设计的软件是符合用户要求的,缩短了整体开发周期;
缺点:难以模拟大型系统和批处理系统,文档容易被忽略,项目难以清晰地规划和管理。
适用场合:①不能预先确切定义需求的软件系统;②开发人员不能很好地交流的情况。
先开发系统的主要功能,然后,随着时间推进,不断增加新的次要功能,最终开发出一个完整的软件产品。
优点:①有利于增加客户对系统的信心;②降低系统失败风险;提高系统可靠性,稳定性和可维护性;
缺点:①增量粒度难以选择;②每个增量必须依赖之前的增量,耦合度增加;③容易退化为边做边改,失去软件过程的整体性。
适用场合:①进行已有产品升级或新版本开发;②完成期限严格要求的产品;③已有原型系统;④开发人员整体水平有限,可以边学习边开发。
螺旋模型的基本做法是在“瀑布模型”的每⼀个开发阶段前,引入⼀个非常严格的风险识别、风险分析和风险控制。它把软件项目分解成⼀个个小项目,每个小项目都标识⼀个或多个主要风险,直到所有的主要风险因素都被确定。
四象限:螺旋模型每次迭代有四个任务,依次是:计划、目标/可选方案、风险评估、 开发与测试;
四循环:螺旋模型共有四次迭代,依次是:操作概念、软件需求、软件设计、开发与测试。
优点:①支持需求的动态变化,具有良好的扩展性;②易于用户和开发人员共同理解需求,还可作为继续开发的基础;③强调风险分析,使软件最终的安全性和稳定性都大大提升;
缺点:①需要开发人员有丰富的风险评估知识;②开发周期长,迭代次数多,可能延迟项目验收时间。
为缓和传统开发模型固守成规的缺点,提出了敏捷开发模型,它以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发,总体目标是:尽早地、持续性地交付有价值的软件,使客户满意。
敏捷宣言:
极限编程:
是典型的敏捷开发方法,包含 4
个理念:①交流:客户与开发人员之间持续地交换看法;②简单性:选择简单的实现来满足客户的需要;③勇气:尽早和经常性地做出交付的承诺;④反馈:各种反馈活动应该贯穿整个过程。
敏捷管理实践:
Scrum Master
带领团队成员准时例行沟通项目进展和解决方案;优点:①采用简单计划策略,不需要长期计划和复杂模型,开发周期短;②在全过程采用迭代增量开发、反馈修正和反复测试的方法,能够适应用户经常变化的需求;③注重市场快速反应能力,客户前期满意度高;
缺点:①注重人员的沟通,忽略文档的重要性,若项目人员流动大太,给维护带来不少难度;②对编码人员的经验要求高,若项目存在新手比较多时,老员工比较累。
适用范围:①项目经常发生变更;②高风险的项目实施;③开发人员水平高,可以参与决策;④有优秀的敏捷顾问。
项目进度:项目进度是对特定项目的软件开发周期的刻画。包括对项目阶段、步骤、活动的分解,对各个离散活动的交互关系的描述,以及对各个活动完成时间及整个项目完成时间的初步估算。
活动:项目的一部分,一般占用项目进度计划的一段时间;
里程碑:特定的时间节点,标志着活动的结束,通常伴随着提交产物;
WBS:Work Breakdown Structure,项⽬按⼀定的原则分解,项⽬分解成任务,任务再分解成⼀项项⼯作,再把⼀项项⼯作分配到每个⼈的⽇常活动中,直到分解不下去为⽌,树形表示;
WBS 分解方法:①类比法:参考类似的项目方法或模板;②自顶向下法;③自底向上法;
活动图:描述活动之间的依赖关系,图中结点是项目里程碑,线表示活动;
AOE 网络:有向图 G
中,若用顶点代表事件,有向边表示活动,有向边上的权值表示一项活动持续的时间,则称图 G
为 AOE
网络;
项目组织:
①代码行分析法;②功能点分析法;③专家判断技术;④标准回归技术;⑤神经网络技术;⑥贝叶斯分析技术;⑦类比法。
使软件项目的实施受到影响和损失、甚至导致失败的、可能会发生的事件。
计算机辅助软件工程,用来支持管理系统开发的、由各种计算机辅助软件和工具组成的大型综合性软件开发环境,如图工具、流程建模工具、文档编写工具、集成测试工具的集合。
需求是对期望的行为的表达,是用户需解决某一问题或达到某一目标所需的软件功能;
Object Constraint Language,是一个形式化语言,和 ER 图或 UML 紧密结合在一起,用于表示类图中的不变量、前置条件、后置条件、转移条件等,帮助类图表示地更清晰。
开发人员快速构建一个原型以确保是否符合用户需求,在需求确定后再开始正式开发;
软件系统设计是一个迭代的过程,最终结果是软件体系结构文档(SAD)。
自顶向下地分解软件涉及的每一个模块,帮助开发者更好地把握软件设计流程,几个流行的分解方案为:
当系统的每个活动都仅由对应的软件单元实现,并且每个软件单元的输入和输出都已经明确地被定义时,设计才可以说是模块化的;
如果一个软件单元的接口能够准确无误地指定该单元的外部可见行为,则称该软件单元是定义明确的;
将软件分解形成为构件后,将它们合适地排列以展示各个构件之间的交互和系统整体的架构的一种表示形式;体系结构视图包含以下几种:
体系结构风格反映了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
经典的体系结构风格:
管道/过滤器:将数据输入到过滤器中得到输出数据,通过管道将数据从一个过滤器中传输到下一个过滤器;
层次结构:整个系统被组织成一个分层结构,每一层为上层提供服务,并作为下一层的客户。
优点:
缺点:
C/S 风格:C/S 体系结构有三个主要组成部分:客户机、服务器和专用的网络;
B/S 风格:B/S体系结构有三个主要组成部分:浏览器、 Web 服务器、数据库服务器;
设计原则是指把系统功能和行为分解成模块的指导方针。
六种重要的设计原则:
模块化:把系统中各不相关的部分进行分离的原则,以便于各部分能够独立研究,也称为关注点分离,每个模块都有自己唯一的目的,并且相对独立于其它模块。
使用两个概念来度量模块的独立程度:耦合度和内聚度;
耦合度:两个模块之间存在着很强的依赖关系称为紧密耦合,两个模块之间存在较少依赖关系称为松散耦合,模块之间没有任何依赖关系称为无耦合。耦合越松散,模块之间的联系就越小,模块的独立性就越强。
常见的耦合类型:
尽量使用数据耦合,少用控制耦合,限制公共耦合的范围,完全不采用内容耦合。
内聚度:内聚是衡量一个模块内部各个元素彼此结合的紧密程度,一个模块内聚程度越高,说明该模块内部各元素之间的关联也就越强。
内聚度由低到高为:
接口:接口定义了模块能正确工作的环境,以及格式化的输入输出,隐藏了模块实现细节;
信息隐藏:对使用模块的用户隐藏模块实现相关的信息,例如用户只需要知道函数能够排序,而不需管其底层是冒泡排序还是快速排序;
增量式开发:将每个模块看作一个增量组件,并按优先级分批次分析、设计、开发、测试和交付增量组件;
抽象:忽略细节,提炼出模块之间的共性,或建设整体视图,或设计接口类;
通用性:开发软件时,尽量使其成为通用的软件,以便在将来将其复用到另一系统中;
封装、继承和多态;
单一职责原则:一个类只负责一个职责,这样可以增加模块的可复用性,系统整体高内聚、低耦合;
开闭原则:一个软件实体应当对扩展开放,对修改关闭,即在不改变本身代码的情况下其行为能扩展,面临新的需求时,不要更改已有的代码,而是在其基础上进行扩展;
里氏代换原则:一个软件如果使用的是一个父类的话,那么一定适用于其子类,而察觉不出父类对象和子类对象的区别。也即是说,在软件里面,把父类替换成它的子类,程序的行为不会有变化,简单地说,子类型必须能够替换掉它们的父类型;
依赖倒转原则:高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
例如,下图1未实现依赖倒转原则,图2实现了依赖倒转原则:
合成复用原则:尽量使用对象组合,而不是继承来达到复用的目的;
例如,下图1是继承复用,冗余项多且庞杂,图2是聚合复用,简介且易维护:
迪米特法则:又称为最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用,这样,当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易;
例如,下图1未使用迪米特原则,图2使用了迪米特原则:
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,设计模式通过实现面向对象七大原则,从而达到了代码复用、增加可维护性的目的。
单例模式:这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
建造者模式:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
实例:
用建造者(Builder)模式描述客厅装修。
分析:客厅装修是一个复杂的过程,它包含墙体的装修、电视机的选择、沙发的购买与布局等。客户把装修要求告诉项目经理,项目经理指挥装修工人一步步装修,最后完成整个客厅的装修与布局,所以本实例用建造者模式实现比较适合。
这里客厅是产品,包括墙、电视和沙发等组成部分。具体装修工人是具体建造者,他们负责装修与墙、电视和沙发的布局。项目经理是指挥者,他负责指挥装修工人进行装修。
另外,客厅类中提供了 show()
方法,可以将装修效果图显示出来。客户端程序通过对象生成器类 ReadXML
读取 XML
配置文件中的装修方案数据,调用项目经理进行装修。其类图如图所示:
建造者模式的主要优点如下:
其缺点如下:
观察者模式:观察者(Observer)是指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
模式动机:建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
实例:
利用观察者模式设计一个程序,分析人民币汇率的升值或贬值对进口公司进口产品成本或出口公司的出口产品收入以及公司利润率的影响。
分析:当“人民币汇率”升值时,进口公司的进口产品成本降低且利润率提升,出口公司的出口产品收入降低且利润率降低;当“人民币汇率”贬值时,进口公司的进口产品成本提升且利润率降低,出口公司的出口产品收入提升且利润率提升。
这里的汇率(Rate)类是抽象目标类,它包含了保存观察者(Company)的 List 和增加/删除观察者的方法,以及有关汇率改变的抽象方法 change(int number);而人民币汇率(RMBrate)类是具体目标, 它实现了父类的 change(int number) 方法,即当人民币汇率发生改变时通过相关公司;公司(Company)类是抽象观察者,它定义了一个有关汇率反应的抽象方法 response(int number);进口公司(ImportCompany)类和出口公司(ExportCompany)类是具体观察者类,它们实现了父类的 response(int number) 方法,即当它们接收到汇率发生改变的通知时作为相应的反应。下图所示是其 UML 结构图。
观察者模式的优点:
观察者模式的缺点:
中介者模式:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
实例:
用中介者模式编写一个“房地产交流平台”程序。
分析:首先,定义一个中介公司(Medium)接口,它是抽象中介者,它包含了客户注册方法 register(Customer member) 和信息转发方法 relay(String from,String ad);再定义一个房地产中介(EstateMedium)公司,它是具体中介者类,它包含了保存客户信息的 List 对象,并实现了中介公司中的抽象方法。
然后,定义一个客户(Customer)类,它是抽象同事类,其中包含了中介者的对象,和发送信息的 send(String ad) 方法与接收信息的 receive(String from,String ad) 方法的接口,由于本程序是窗体程序,所以本类继承 JPmme 类,并实现动作事件的处理方法 actionPerformed(ActionEvent e)。
最后,定义卖方(Seller)类和买方(Buyer)类,它们是具体同事类,是客户(Customer)类的子类,它们实现了父类中的抽象方法,通过中介者类进行信息交流,其结构 UML 图如下:
中介者模式的优点为:
中介者模式的缺点为:
有两种类型的复用:生产者复用和消费者复用;
XP、结对编程、融合、小组协同;
error
导致的;fault
导致的;静态测试(程序不执行):一般是检查代码的风格和规范。
动态测试(程序执行):通过选择适当的测试用例,执行程序。
黑盒测试(测试功能):不考虑程序的内部结构与特性,只根据程序功能或程序的外部特性设计测试用例。
等价类分类法:将可能的输入划分成若干等价的类,每一个类选择一个测试用例;
例如,注册某网站。要求:用户名的长度为812的数字与字母组合而成的字符,,密码长度为616位的数字、字母的组合。请写出测试案例:
确定了等价类之后我们就可以设计测试用例了,测试用例需要覆盖到所有的等价类,即有效等价类和无效等价类。具体情况请看下表:
边值分析法:对输入的边界值进行测试,例如,对16-bit 的整数而言 32767 和 -32768 是边界;屏幕上光标在最左上、最右下位置。
错误推测法:在测试程序时,人们可以根据经验或直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的测试用例的方法。
因果图法:适合输入条件比较多的情况,可以测试所有的输入条件的排列组合。“ 因 ” 就是输入条件,“ 果 ” 就是输出结果。
白盒测试(测试结构):分析程序的内部逻辑结构,注意选择适当的覆盖标准,设计测试用例,对主要路径进行尽可能多的测试。
白盒法又称为逻辑覆盖法,常用的逻辑覆盖标准:
true
或 false
各一次;true
或 false
各一次,满足条件覆盖的,不一定满足判定覆盖;i
有 n
个条件,每个条件有 true
和 false
选项,则至少需要 2^n
个用例才能覆盖语句 i
。把功能模块或程序单元组合起来进行测试,发现模块在组合过程中的缺陷。
集成测试的分类:
非增量式集成策略:对所有模块进行单元测试后,将各模块连接起来,把连接后的程序当作一个整体进行测试。
增量式集成策略:逐次将未曾集成测试的模块和已经集成测试的模块(或子系统)结合成程序包,再将这些模块集成为较大系统,在集成的过程中边连接边测试,以发现连接过程中产生的问题。
增量式集成测试又可以分为三种不同的方法:
自顶向下增量式测试:模块集成的顺序是首先集成主控模块(主程序),然后依照控制层次结构向下进行集成。从属于主控模块的按 DFS
或 BFS
方式集成到结构中去。
整个过程由 3
个步骤完成:
例题:对如下结构采用自顶向下深度优先策略进行测试:
优缺点分析:
自底向上增量式测试:最常用的集成策略,从具有最小依赖性的底层组件开始,按照依赖关系树的结构,逐层向上集成,以检验系统的稳定性。
整个过程由 4
个步骤完成:
优缺点分析:
优点:①对底层组件行为较早验证;②工作最初可以并行集成,比自顶向下效率高;减少了桩的工作量;③能较好锁定软件故障所在位置。
缺点:①驱动的开发工作量大;②对高层的验证被推迟,设计上的错误不能被及时发现。
适用范围:①适应于底层接口比较稳定;②高层接口变化比较频繁;③底层组件较早被完成。
三明治增量式测试:把系统划分成三层,中间一层为目标层,目标层之上采用自顶向下集成,之下采用自底向上集成。
整个过程由 4
个步骤完成:
优缺点分析:
播撒模型:
Mills 模型:人工随机置入错误 M 个错误,测试得出 m 个人工置入的错误,n 个程序固有的错误,则估算系统固有错误为:
N = n × M m N=\frac{n×M}{m} N=mn×M
Hyman 模型:两人同时进行测试,A 发现 n 个错误,B 发现 m 个错误,其中共同错误有 q 个,则估算系统的固有错误为:
N = m × n q N=\frac{m×n}{q} N=qm×n
静态模型:根据软件的规模和复杂性进行估计。
根据测试覆盖率的预测模型:
步骤:
earliest(j) = max{earliest(i) + w(i, j)}
;latest(i) = mim{latest(j) - w(i, j)}
;例1
如下图所示的AOE网(弧上权值代表活动的持续天数,求:
1)绘制事件的最早发生时间和最晚发生时间;
2)绘制活动的最早开始时间和最晚开始时间;
3)哪些是关键活动,给出关键路径;
4)完成此工程最少所需要多少天。
基本工作量计算公式如下:
E = a × K L O C b × F E=a×KLOC^b×F E=a×KLOCb×F
方式 | a | b |
---|---|---|
有机 | 2.4 | 1.05 |
半有机 | 3.0 | 1.12 |
嵌入式 | 3.6 | 1.2 |
E = a × K L O C b × 1 E=a×KLOC^b×1 E=a×KLOCb×1
一个 33.3 KLOC
的软件开发项目,属于中等规模、半有机型的项目,采用基本COCOMO
:a = 3.0,b = 1.12,则:
E = 3.0 × 33. 3 1.12 × 1 = 152 p m E= 3.0×33.3^{1.12}×1=152pm E=3.0×33.31.12×1=152pm
方式 | a | b |
---|---|---|
有机 | 2.8 | 1.05 |
半有机 | 3.0 | 1.12 |
嵌入式 | 3.2 | 1.2 |
F = ∏ i = 1 17 E M i F=\prod_{i=1}^{17}{EM_i} F=i=1∏17EMi
E = a × K L O C b × F E=a×KLOC^b×F E=a×KLOCb×F
一个 33.3 KLOC
的软件开发项目,属于中等规模、半有机型的项目,采用中等 COCOMO
模型。 a = 3.0,b=1.12,则:
F = 0.70 × 0.85 × . . . × 1.15 = 1.09 F=0.70×0.85×...×1.15=1.09 F=0.70×0.85×...×1.15=1.09
E = 3.0 × 33. 3 1.12 × 1.09 = 16 p m E=3.0×33.3^{1.12}×1.09=16pm E=3.0×33.31.12×1.09=16pm
b = 0.91 + 0.01 ∑ i = 1 5 b i b=0.91+0.01\sum_{i=1}^{5}{b_i} b=0.91+0.01i=1∑5bi
F = ∏ i = 1 17 E M i F=\prod_{i=1}^{17}{EM_i} F=i=1∏17EMi
E = a × K L O C b × F E=a×KLOC^b×F E=a×KLOCb×F
a
是校正常数,通常取值 2.94
(根据公司大量数据进行调整)。
在 ER 图中有如下 4 个成分:
例题1:用图书、作者两个实体及其属性和联系构建E-R图。
例题2:某企业集团有若干工厂,每个工厂生产多种产品,且每一种产品可以在多个工厂生产,每个工厂按照固定的计划数量生产产品,计划数量不低于300;每个工厂聘用多名职工,且每名职工只能在一个工厂工作,工厂聘用职工有聘期和工资。工厂的属性有工厂编号、厂名、地址,产品的属性有产品编号、产品名、规格,职工的属性有职工号、姓名、技术等级。
类图以反映类的结构(属性、操作)以及类之间的关系为主要目的,描述了软件系统的结构,是一种静态建模方法。从上到下分为三部分,分别是类名、属性和操作。
类图中的关系:
依赖关系:描述了一个类的变化对依赖于它的类产生影响的情况;
虚线 + 箭头表示
关联关系:用带箭头的线段表示,表示类之间的联结,一个类使用了另一个类的方法;
聚合关系:特殊关联关系,指明一个聚集(整体)和组成部分之间的关系。例如,多名学生聚合成了一个班级,学生不会因为班级的解散而无法存在,教室需要同时知道班级和学生的信息,二者的生命周期是独立的;
组合关系:语义更强的聚合,部分和整体具有相同的生命周期。例如,学生由器官组成,器官的生命周期被严格封装在学生中,只需要了解学生的信息即可;
泛化关系:在面向对象中一般称为继承关系,存在于父类与子类、父接口与子接口之间;
实现关系:对应于类和接口之间的关系;
虚线 + 空心三角形表示
例题1
例题2
有一工业生产线,要完成两项操作,分别为变迁 t1 和 t2 表示,变迁 t1 将进入生产线,半成品 s1s2 用两个部件 s3 固定在一起,后形成中间件 s4。然后第2个变迁 t2 将 s4 和 s5 用 3 个部件 s3 固定在一起形成中间件 s6。完成 t1 和 t2 都需要用到工具 s7。
假设受空间限制,s2、s5 最多不能超过 100 件, s4 最多不能超过 5 件,s3 最多不能超过 1000 件。
其 Petri 网结果如下:
顶层图:中间的椭圆是需要开发的系统 , 周边的矩形表示外部实体人或组织;
中层图:将 “顶层数据流图” 进行细化,外部实体不变;
底层图:针对每个加工 节点 , 将其拆分 , 绘制其中的更详细的数据流转情况;
**例题:**图书预订系统:书店向顾客发放订单,顾客将所填订单交由系统处理,系统首先依据图书目录对订单进行检查并对合格订单进行处理,处理过程中根据顾客情况和订单数目将订单分为优先订单与正常订单两种,随时处理优先订单,定期处理正常订单。最后系统根据所处理的订单汇总,并按出版社要求发给出版社。
类似于顶层的数据流图,描述了系统和用户的上层交互情况。
用例图中的关系及解释
例题1:
参与者:经理,安全主管,保安
用例:管理人事,批准预算,批准安全证书,监视周边
例题 2:
短途旅行但汽车的油不足以应付全部路程。那么为汽车加油的动作在旅行的每个场景(事件流)中都会出现,不加油就不会完成旅行。吃饭则可以由司机决定是否进行,不吃饭不会影响旅行的完成。
故障树是一种为研究系统某功能故障而建立的一种倒树状的逻辑因果关系图。
割集树的边缘就是故障树的割集,表示引起树顶失效所需事件的最小集合。
若已知故障树的割集以及底事件发送的概率,则顶事件发送的概率为各割集元素发生概率之和。