# 51 ~ 100

1665792618560

开放式源码指的是开放源码界所用的一种运作方式。开放式源码项目有一个特别之处,就是程序开发人员在地域上分布很广。这使得它和其他敏捷方法不同,因为一般的敏捷方法都强调项目组成员在同一地点工作。

功用驱动开发方法(Feature Driven Development,FDD)致力于短时的迭代,阶段和可见可用的功能。在 FDD 中,编程开发人员分成首席程序员和 “类” 程序员(class owner)两类。

1665792700642

软件工程中系统化的方法有时候也叫软件过程。所有软件过程都包含下表所示的 4 项基本活动:

1665792772773

瀑布模型是经典的软件开发模型,瀑布模型是最早使用的软件生存周期模型之一,其特点是因果关系紧密相连,前一个阶段工作的结果是后一个阶段工作的输入。或者说,每一个阶段都是建立在前一个阶段的正确结果之上,前一个阶段的错误和疏漏会隐蔽地带入后一个阶段。这种错误有时甚至可能是灾难性的,因此每一个阶段工作完成后,都要进行审查和确认。其活动之间存在因果关系,前一阶段工作的结果是后一阶段工作的输入描述。

1665792982744

快速应用开发利用了基本构件开发方法的思想,大量采用现成的构件进行系统的开发,所以速度很快。但这种开发,要求系统模块化程度高,因为只有这样,才能更好利用现有的构件。

螺旋模型的图示如下:

1665793070002

1665793100139

逆向工程导出的信息可分为如下 4 个抽象层次。

①实现级:包括程序的抽象语法树、符号表等信息。

②结构级:包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图等。

③功能级:包括反映程序段功能及程序段之间关系的信息。

④领域级:包括反映程序分量或程序与应用领域概念之间对应关系的信息。

1665793331348

原型模型又称快速原型。原型模型主要有两个阶段:①原型开发阶段。软件开发人员根据用户提出的软件系统的定义,快速地开发一个原型。该原型应该包含目标系统的关键问题和反映目标系统的大致面貌,展示目标系统的全部或部分功能、性能等。②目标软件开发阶段。在征求用户对原型的意见后对原型进行修改完善,确认软件系统的需求并达到一致的理解,进一步开发实际系统。

瀑布模型可以说是最早使用的软件生存周期模型之一。由于这个模型描述了软件生存的一些基本过程活动,所以它被称为软件生存周期模型。这些活动从一个阶段到另一个阶段逐次下降,形式上很像瀑布。瀑布模型的特点是因果关系紧密相连,前一个阶段工作的结果是后一个阶段工作的输入。

螺旋模型是在快速原型的基础上扩展而成的。这个模型把整个软件开发流程分成多个阶段,每个阶段都由 4 部分组成,它们是:①目标设定。为该项目进行需求分析,定义和确定这一个阶段的专门目标,指定对过程和产品的约束,并且制定详细的管理计划。②风险分析。对可选方案进行风险识别和详细分析,制定解决办法,采取有效的措施避 免这些风险。③开发和有效性验证。风险评估后,可以为系统选择开发模型,并且进行原型开发,即开发软件产品。④评审。对项目进行评审,以确定是否需要进入螺旋线的下一次回路,如果决定继续,就要制定下一阶段计划。

V 模型是一种典型的测试模型。在 V 模型中测试过程被加在开发过程的后半部分,分别包括单元测试、集成测试、系统测试和验收测试。

1665793524480

RUP 软件开发生命周期是一个二维的软件开发模型,其中有 9 个核心工作流,分别为:业务建模、需求、分析与设计、实现、测试部署、配置与变更管理、项目管理以及环境。

RUP 把软件开发生存周期划分为多个循环,每个循环生成产品的一个新的版本,每个循环依次由 4 个连续的阶段组成,每个阶段完成确定的任务。这 4 个阶段分别为:

初始阶段:定义最终产品视图和业务模型,并确定系统范围。

细化阶段:设计及确定系统的体系结构,制定工作计划及资源要求。

构造阶段:构造产品并继续演进需求、体系结构、计划直至产品提交。

移交阶段:把产品提交给用户使用。

每个阶段都有一个或多个连续的迭代组成。迭代并不是重复地做相同的事,而是针对不同用例的细化和实现。每一个迭代都是一个完整的开发过程,它需要项目经理根据当前迭代所处的阶段以及上次迭代的结果,适当地对工作流中的行为进行裁剪。在每个阶段结束前有一个里程碑评估该阶段的工作。如果未能通过该里程碑的评估,则决策者应该做出决定,是取消该项目还是继续该阶段的工作。

与其他软件开发过程相比,RUP 具有自己的特点,即 RUP 是用例驱动的、以体系结构为中心的、迭代和增量的软件开发过程

1665793888682

基于 UML 的需求分析过程大致可分为以下步骤:

①利用用例及用例图表示需求。从业务需求描述出发获取执行者和场景;对场景进行汇总、分类、抽象,形成用例;确定执行者与用例、用例与用例图之间的关系,生成用例图。

②利用包图和类图表示目标软件系统的总体框架结构。根据领域知识、业务需求描述和既往经验设计目标软件系统的顶层架构;从业务需求描述中提取 “关键概念”,形成领域概念模型;从概念模型和用例出发,研究系统中主要的类之间的关系,生成类图。

1665794043163

结构化分析方法的基本思想是自顶向下,逐层分解,把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题。经过逐层分解,每个最低层的问题都是足够简单、容易解决的。

结构化方法分析模型的核心是数据字典,围绕这个核心,有三个层次的模型,分别是数据模型、功能模型和行为模型(也称为状态模型)。在实际工作中,一般使用 E-R 图表示数据模型,用 DFD 表示功能模型,用状态转换图表示行为模型。这三个模型有着密切的关系,它们的建立不具有严格的时序性,而是一个迭代的过程。

dfd:数据流图

1665794156385

一个大型的软件系统的需求总是有变化的。对许多项目来说,系统软件总需要不断完善,一些需求的改进是合理的而且不可避免,要使得软件需求完全不变更,也许是不可能的,但毫无控制的变更是项目陷入混乱、不能按进度完成,或者软件质量无法保证的主要原因之一。一个好的变更控制过程,给项目风险承担者提供了正式的建议需求变更机制,可以通过变更控制过程来跟踪已建议变更的状态,使已建议的变更确保不会丢失或疏忽。需求变更管理过程如下图所示:

1665794245883

①问题分析和变更描述。这是识别和分析需求问题或者一份明确的变更提议,以检查它的有效性,从而产生一个更明确的需求变更提议。

②变更分析和成本计算。使用可追溯性信息和系统需求的一般知识,对需求变更提议进行影响分析和评估。变更成本计算应该包括对需求文档的修改、系统修改的设计和实现的成本。一旦分析完成并且确认,应该进行是否执行这一变更的决策。

③变更实现。这要求需求文档和系统设计以及实现都要同时修改。如果先对系统的程序做变更,然后再修改需求文档,这几乎不可避免地会出现需求文档和程序的不一致。 自动化工具能够帮助变更控制过程更有效地运作。许多团队使用商业问题跟踪工具来收集、存储和管理需求变更。用这样的工具创建的最近提交的变更建议清单,可以用作 CCB 会议的议程。问题跟踪工具也可以随时按变更状态分类报告出变更请求的数目。 因为可用的工具、厂商和特性总在频繁地变化,所以这里无法给出有关工具的具体建议。但工具应该具有以下几个特性,以支持需求变更过程: ①可以定义变更请求中的数据项; ②可以定义变更请求生命周期的状态转换模型; ③可以强制实施状态转换模型,以便只有授权用户可以做出允许的状态变更; ④可以记录每一个状态变更的日期和做出这一变更的人; ⑤可以定义当提议者提交新请求或请求状态被更新时,哪些人可以自动接收电子邮件通知; ⑥可以生成标准的和定制的报告和图表。 有些商业需求管理工具内置有简单的变更建议系统。这些系统可以将提议的变更与某一特定的需求联系起来,这样无论什么时候,只要有人提交了一个相关的变更请求,负责需求的每个人都会收到电子邮件通知。

1665794542818

敏捷方法是从 20 世纪 90 年代开始逐渐引起广泛关注的一些新型软件开发方法,以应对快速变化的需求。敏捷方法的核心思想主要有以下三点。

①敏捷方法是 “适应性” 而非 “预设性” 的。传统方法试图对一个软件开发项目在很长的时间跨度内做出详细的计划,然后依计划进行开发。这类方法在计划制定完成后拒绝变化。而敏捷方法则欢迎变化,其实它的目的就是成为适应变化的过程,甚至能允许改变自身来适应变化。

②敏捷方法是以人为本,而不是以过程为本。传统方法以过程为本,强调充分发挥人的特性,不去限制它,并且软件开发在无过程控制和过于严格烦琐的过程控制中取得一种平衡,以保证软件的质量。

③迭代增量式的开发过程。敏捷方法以原型开发思想为基础,采用迭代增量式开发,发行版本小型化。 与 RUP 相比,敏捷方法的周期可能更短。敏捷方法在几周或者几个月的时间内完成相对较小的功能,强调的是能尽早将尽量小的可用的功能交付使用,并在整个项目周期中持续改善和增强,并且更加强调团队中的高度协作。

相对而言,敏捷方法主要适合于以下场合:
①项目团队的人数不能太多,适合于规模较小的项目。
②项目经常发生变更。敏捷方法适用于需求萌动并且快速改变的情况,如果系统有比较高的关键性、可靠性、安全性方面的要求,则可能不完全适合。
③尚风险项目的实施。
④从组织结构的角度看,组织结构的文化、人员、沟通性决定了敏捷方法是否使用。

1665795152084

1665795304600

软件开发环境(Software Development Environment)是支持软件产品开发的软件系统。它由软件工具集和环境集成机制构成,前者用来支持软件开发的相关过程、活动和任务年;后者为工具集成和软件开发、维护和管理提供统一的支持,它通常包括数据集成、控制集成和界面集成。

数据集成机制提供了存储或访问环境信息库的统一的数据接口规范;界面集成机制采用统一的界面形式,提供统一的操作方式;控制集成机制支持各开发活动之间的通信、切换、调度和协同工作。

1665795499878

类封装了信息和行为,是面向对象的重要组成部分。设计类是面向对象设计过程中最重要的组成部分,也是最复杂和最耗时的部分。在面向对象设计过程中,类可以分为三种类型:实体类、边界类和控制类。

实体类映射需求中的每个实体。实体类保存需要存储在永久存储体中的信息。实体类是对用户来说最有意义的类,通常采用业务领域术语命名,一般来说是一个名词,在用例模型向领域模型的转化中,参与者一般对应于实体类。

控制类是用于控制用例工作的类,一般是由动宾结构的短语(“动词 + 名词” 或 “名词 + 动词”)转化而来的名词。控制类用于对一个或几个用例所特有的控制行为进行建模,控制对象(控制类的实例)通常控制其他对象。因此它们的行为具有协调性。

边界类用于封装在用例内、外流动的信息或数据流。边界类是一种用于对系统外部环境与其内部运作之间的交互进行建模的类,用于实现目标软件系统与外部系统或外部设备之间的信息交流和互操作。

1665795721123

快速应用开发(Rapid Application Development,RAD)是一种比传统生存周期法快得多的开发方法,它强调极短的开发周期。RAD 模型是瀑布模型的一个高速变种,通过使用基于构件的开发方法获得快速开发。如果需求理解得很好,且约束了项目范围,利用这种模型可以很快地开发出功能完善的信息系统。但是 RAD 也具有以下局限性:
①并非所有应用都适合 RAD。RAD 对模块化要求比较高,如果有哪一项功能不能被模块化,那么 RAD 所需要的构建就会有问题;如果高性能是一个指标,且该指标必须通过调整接口使其适应系统构件才能获得,则 RAD 也有可能不能奏效。

②开发者和客户必须在很短的时间完成一系列的需求分析,任何一方配合不当,都会导致 RAD 项目失败。

③RAD 只能用于管理信息系统的开发,不适合技术风险很高的情况。例如,当一个新系统要采用很多新技术,或当新系统与现有系统有较高的互操作性时,就不适合使用 RAD。

1665795868776

逆向工程与重构工程是目前预防性维护采用的主要技术。所谓软件的逆向工程就是分析已有的程序,寻求比源代码更高级的抽象表现形式。一般认为,凡是在软件生命周期内将软件某种形式的描述转换成更为抽象形式的活动都可称为逆向工程。逆向工程导出的信息可以分为如下 4 个抽象层次。 ①实现级:包括程序的抽象语法树、符号表等信息。 ②结构级:包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图等。 ③功能级:包括反映程序段功能及程序段之间关系的信息。 ④领域级:包括反映程序分量或程序诸实体与应用领域概念之间对应关系的信息。显然,上述信息的抽象级别越高,它与代码的距离就越远,通过逆向工程恢复的难 度亦越大,而自动工具支持的可能性相对变小,要求人参与判断和推理的工作增多。

软件系统工具的种类繁多,很难有统一的分类方法。通常可以按软件过程活动将软件工具分为软件开发工具、软件维护工具 、软件管理和软件支持工具。

软件开发工具:需求分析工具、设计工具、编码与排错工具。

软件维护工具:版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工程工具。

软件管理和软件支持工具:项目管理工具、配置管理工具、软件评价工具、软件开发工具的评价和选择。

1665796558267

软件开发环境(Software Development Environment,SDE)是指支持软件的工程化开发和维护而使用的一组软件,由软件工具集和环境集成机制构成。

软件开发环境应支持多种集成机制,例如,平台集成、数据集成、界面集成、控制集成和过程集成等。

软件开发环境应支持小组工作方式,并为其提供配置管理,环境的服务可用于支持各种软件开发活动,包括分析、设计、编程、调试和文档等。 较完善的软件开发环境通常具有多种功能,例如,软件开发的一致性与完整性维护,配置管理及版本控制,数据的多种表示形式及其在不同形式之间的自动转换,信息的自动检索与更新,项目控制和管理,以及对开发方法学的支持。软件开发环境具有集成性、开放性、可裁减性、数据格式一致性、风格统一的用户界面等特性,因而能大幅度提高软件生产率。

集成机制根据功能的不同,可划分为环境信息库、过程控制与消息服务器、环境用户界面三个部分。

1. 环境信息库。环境信息库是软件开发环境的核心,用以存储与系统开发有关的信息,并支持信息的交流与共享。环境信息库中主要存储两类信息,一类是开发过程中产生的有关被开发系统的信息,例如,分析文档、设计文档和测试报告等;另一类是环境提供的支持信息,例如,文档模板、系统配置、过程模型和可复用构件等。

2. 过程控制与消息服务器。过程控制与消息服务器是实现过程集成和控制集成的基础。过程集成是按照具体软件开发过程的要求进行工具的选择与组合,控制集成使各工具之间进行并行通信和协同工作。

3. 环境用户界面。环境用户界面包括环境总界面和由它实行统一控制的各环境部件及工具的界面。统一的、具有一致性的用户界面是软件开发环境的重要特征,是充分发挥环境的优越性、高效地使用工具并减轻用户的学习负担的保证。

1665797168165

户界面设计的基本原则是从实践中总结出来的一些设计规则。Theo Maiidel 在他的界面设计著作中提出 3 条 “黄金规则”:

①让用户拥有控制权 用户希望控制计算机,而不是被计算机控制,因此在设计人机界面时应遵循以下原则:交互模式的定义不能强迫用户进入不必要的或不希望的动作的方式;提供灵活的交互;允许用户交互可以被中断和撤销;当技能级別增长时可以使交互流水化并允许定制交互;使用户隔离内部技术细节。

②减少用户的记忆负担 要求用户记住的东西越多,与系统交互时出错的可能也越大,因此好的用户界面设计不应加重用户的记忆负担。减少用户记忆负担的设计原则为:减少对短期记忆的要求;建立有意义的默认值;定义直觉性的捷径;界面的视觉布局应该基于真实世界的隐喻;以不断进展的方式祸示信息。

③保持界面一致 用户应该以一致的方式展示和获取信息,这意味着:所有可视信息的组织遵循统一的设计标准,所有屏幕显示都遵守该标准。输入机制被约束到有限的集合内,在整个软件系统中被一致地使用,同时从任务到任务的导航机制也被一致地定义和实现。保持界面一致性的设计原则包括以下内容:允许用户将当前任务放在有意义的语境中;在应用系列内保持一致性;不要改变用户己经熟悉的用户交互模型。

1665797470192

1665797494797

版本控制软件提供完备的版本管理功能,用于存储、追踪目录(文件夹)和文件的修改历史,是软件开发者的必备工具,是软件公司的基础设施。版本控制软件的最高目标,是支持软件公司的配置管理活动,追踪多个版本的开发和维护活动,及时发布软件。SCCS 是元老级的版本控制软件,也叫配置管理软件

1665797620517

软件重用是指在两次或多次不同的软件开发过程中重复使用相同或相似软件元素的过程。按照重用活动是否跨越相似性较少的多个应用领域,软件重用可以区别为横向重用和纵向重用。

横向重用是指重用不同应用领域中的软件元素,例如数据结构、分类算法和人机界面构建等。标准函数是一种典型的、原始的横向重用机制。

纵向重用是指在一类具有较多公共性的应用领域之间进行软部件重用。纵向重用活动的主要关键点是域分析:根据应用领域的特征及相似性预测软部件的可重用性。

1665797759558

常用的面向对象设计原则包括开闭原则、里氏替换原则、依赖倒置原则、组合 / 聚合复用原则、接口隔离原则和最少知识原则等。这些设计原则首先都是面向复用的原则,遵循这些设计原则可以有效地提高系统的复用性,同时提高系统的可维护性。

最少知识原则(也称为迪米特法则)是面向对象设计原则之一,指一个软件实体应当尽可能少地与其他实体发生相互作用。这样,当一个实体被修改时,就会尽可能少地影响其他的实体。 最少知识原则主要用于控制信息的过载。在将最少知识原则运用到系统设计中时, 要注意以下几点:

①在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用。一个处在松稱合中的类一旦被修改,不会对关联的类造成太大波动。

②在类的结构设计上,每个类都应当尽量降低其属性和方法的访问权限。

③在类的设计上,只要有可能,一个类型应当设计成不变类。

④在对其他类的引用上,一个对象对其他对象的引用应当降到最低。

1665797927130

软件开发方法是指软件开发过程所遵循的办法和步骤,从不同的角度可以对软件开发方法进行不同的分类。

形式化方法是一种具有坚实数学基础的方法,从而允许对系统和开发过程做严格处理和论证,适用于那些系统安全级别要求极高的软件的开发。形式化方法的主要优越性在于它能够数学地表述和研究应用问题及软件实现。但是它要求开发人员具备良好的数学基础。用形式化语言书写的大型应用问题的软件规格说明往往过于细节化,并且难于为用户和软件设计人员所理解。由于这些缺陷,形式化方法在目前的软件开发实践中并未得到普遍应用。

净室软件工程(Cleanroom Software Engineering,CSE)是软件开发的一种形式化方法,可以开发较高质量的软件。它使用盒结构规约进行分析和建模,并且将正确性验证作为发现和排除错误的主要机制,使用统计测试来获取认证软件可靠性所需要的信息。CSE 强调在规约和设计上的严格性,还强调统计质量控制技术,包括基于客户对软件的预期使用测试

1665798232398

1665798310501

1665798353963

用例之间的关系主要有包含、扩展和泛化,利用这些关系,把一些公共的信息抽取出来,以便于复用,使得用例模型更易于维护。

①包含关系。当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示它们。其中这个提取出来的公共用例称为抽象用例,而把原始用例称为基本用例或基础用例。

②扩展关系。如果一个用例明显地混合了两种或两种以上的不同场景,即根据情况可能发生多种分支,则可以将这个用例分为一个基本用例和一个或多个扩展用例,这样使描述可能更加清晰。

③泛化关系。当多个用例共同拥有一种类似的结构和行为的时候,可以将它们的共性抽象成为父用例,其他的用例作为泛化关系中的子用例。在用例的泛化关系中,子用例是父用例的一种特殊形式,子用例继承了父用例所有的结构、行为和关系。

1665798553850

面向对象设计的基本任务,把面向对象分析模型转换为面向对象设计模型。

面向对象的分析模型主要由顶层架构图、用例与用例图、领域概念模型构成。

设计模型则包含以包图表示的软件体系结构图、以交互图表示的用例实现图、完整精确的类图、针对复杂对象的状态图和描述流程化处理过程的活动图等。

1665798788922

结构化程序设计采用自顶向下、逐步求精及模块化的程序设计方法,通过顺序、分支和循环三种基本的控制结构可以构造出任何单入口单出口的程序。

1665798808664

目选项所列举的图与开发阶段的对应关系为:

1、需求分析阶段:数据流图。

2、概要设计阶段:模块结构图、层次图和 HIPO 图。(描述程序的结构)

3、详细设计阶段:程序流程图、伪代码、盒图。

1665798958368

1665798995207

结构化分析方法是一种面向数据流的需求分析方法,其基本思想是自顶向下逐层分解。数据流图是进行结构化分析时所使用的模型,其基本成分包括数据流、加工、数据 存储和外部实体。在进行结构化设计时,通过对数据流图进行变换分析和事务分析可以导出程序结构图。

数据库设计可以分为 4 个主要阶段:

①用户需求分析。数据库设计人员采用一定的辅助工具对应用对象的功能、性能、限制等要求所进行的科学分析。

②概念设计。概念结构设计是对信息分析和定义,如视图模型化、视图分析和汇总。对应用对象精确地抽象、概括而形成的独立于计算机系统的企业信息模型。描述概念模型的较理想的工具是 E-R 图。

③逻辑设计。将抽象的概念模型转化为与选用的 DBMS 产品所支持的数据模型相符合的逻辑模型,它是物理设计的基础。包括模式初始设计、子模式设计、应用程序设计、模式评价以及模式求精。

④物理设计。逻辑模型在计算机中的具体实现方案。

UML 是面向对象软件的标准化建模语言,其中状态图、活动图、顺序图和通信图可以用来对系统的动态行为进行建模。活动图展现了在系统内从一个活动到另一个活动的流程。活动图强调对象之间的控制流程。在活动图上可以表示分支和汇合。活动图与传统的程序流程图是不等价的。

1665799346036

结构化方法也称为生命周期法,是一种传统的信息系统开发方法,由结构化分析、 结构化设计和结构化程序设计三部分组成,其精髓是自顶向下、逐步求精和模块化设计。

结构化方法的主要特点是:开发目标清晰化、开发工作阶段化、开发文档规范化和设计方法结构化。结构化方法特别适合于数据处理领域的问题,但是不适应于规模较大、比较复杂的系统开发。结构化方法的缺点是开发周期长、难以适应需求的变化、很少考虑数据结构。

面向对象方法是目前比较主流的开发方法。面向对象方法是系统的描述及信息模型的表示与客观实体相对应,符合人们的思维习惯,有利于系统开发过程中用户与开发人员的交流和沟通,缩短开发周期,提高系统开发的正确性和效率。可以把结构化方法和面向对象方法结合起来进行系统开发。首先使用结构化方法进行自顶向下的整体划分; 然后再自底向上地采用面向对象方法开发系统。

敏捷方法是从 20 世纪 90 年代开始逐渐引起广泛关注的一种新型软件开发方法,以应对快速变化的需求。敏捷方法是一种以人为核心、迭代、循序渐进的开发方法。敏捷方法强调,让客户满意和软件尽早增量发布:小而高度自主的项目团队;非正式 g 方法: 最小化软件工程工作产品以及整体精简开发。与传统方法相比,敏捷开发方法比较适合需求变化较大或者开发前期需求不是很清晰的项目,以它的灵活性来适应需求的变化。

面向服务的方法以粗粒度、松散耦合和基于标准的服务为基础,增强了系统的灵活性、可复用性和可演化性。

1665799742763

1665799773759

解释器模式属于类的行为模式,描述了如何为语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子,这里的 “语言” 是使用规定格式和语法的代码。

策略模式是一种对象的行为型模式,定义一系列算法,并将每个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化,其目的是将行为和环境分隔,当出现新的行为时,只需要实现新的策略类。

中介者模式是一种对象的行为行模式,通过一个中介对象来封装一系列的对象交互。中介者使得各对象不需要现实地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者对象的存在保证了对象结构上的稳定,也就说说系统的结构不会因为新对象的引入带来人量的修改工作。

迭代器模式是一种对象的行为型模式,提供了一种方法来访问聚合对象,而不用暴露这个对象的内部表示。迭代器模式支持以不同的方式遍历一个聚合对象。 由上述可知,与题目所描述场景符合的是中介者模式。

1665800008154

1665800051028

软件设计包括体系结构设计、接口设计、数据设计和过程设计。

结构设计:定义软件系统各主要部件之间的关系。

数据设计:将模型转换成数据结构的定义。好的数据设计将改善程序结构和模块划分,降低过程复杂性。

接口设计(人机界面设计):软件内部,软件和操作系统间以及软件和人之间如何通信。

过程设计:系统结构部件转换成软件的过程描述。

# 101 ~ 117

1665541151060

RUP 中的软件过程在时间上被分解为 4 个顺序的阶段,分别是初始阶段、细化阶段、构建阶段和移交阶段。

初始阶段的任务是为系统建立业务模型并确定项目的边界。细化阶段的任务是分析问题领域,建立完善的架构,淘汰项目中最高风险的元素。在构建阶段,要开发所有剩余的构件和应用程序功能,把这些构件集成为产品。移交阶段的重点是确保软件对最终用户是可用的。

基于 RUP 的软件过程是一个迭代过程,通过初始、细化、构建和移交 4 个阶段就是一个开发周期,每次经过这 4 个阶段就会产生一代产品,在每一轮迭代中都要进行测试与集成。

1665800786385

题目所给出的应用中,不希望在不同的宣传产品与具体所采用的出版方式之间建立一个固定的绑定关系,以避免这两者之间的紧耦合关系。这种情形适合于采用 Bridge(桥接)模式。

桥接模式属于结构型设计模式的一种。结构型模式描述如何将类或对象合在一起形成更大的结构。桥接模式将抽象部分与它的实现部分分离,使它们都可以独立地变化。

在以下情况可以使用 Bridge 模式:

①不希望在抽象以及抽象的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻可以选择或切换实现部分;

②类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充,使用 Bridge 模式可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

③对一个抽象的实现部分的修改应该对用户不产生影响,即客户的代码不必重新编译。

1665801143366

1665801355164

1665801398179

1665801488383

1665801575554

1665801603664

1665801640101

RUP 将项目管理、业务建模、分析与设计等统一起来,贯穿整个开发过程。RUP 中的软件过程在时间上被分解为 4 个顺序的阶段,分别是初始阶段、细化阶段、构建阶段和移交阶段。每个阶段结束时都要安排一次技术评审,以确定这个阶段的目标是否已经满足。如果评审结果令人满意,就可以允许项目进入下一个阶段。可以看出,基于 RUP 的软件过程是一个迭代和增量的过程。通过初始、细化、构建和移交 4 个阶段就是一个开发周期,每次经过这 4 个阶段就会产生一代软件。除非产品退役,否则通过重复同样的 4 个阶段,产品将演化为下一代产品,但每一次的侧重点都将放在不同的阶段上。这样做的好处是在软件开发的早期就可以对关键的、影响大的风险进行处理。

1665801754500

软件重用是指在两次或多次不同的软件开发过程中重复使用相同或相似软件元素的过程。软件元素包括程序代码、测试用例、设计文档、设计过程、需求分析文档甚至领域知识

通常,可重用的元素也称作软构件,可重用的软构件越大,重用的粒度越大。使用软件重用技术可以减少软件开发活动中大量的重复性工作,这样就能提高软件生产率,降低开发成本,缩短开发周期。同时,由于软构件大都经过严格的质量认证,并在实际运行环境中得到校验,因此,重用软构件有助于改善软件质量。此外,大量使用软构件,软件的灵活性和标准化程度也可望得到提高。

1665801963210

1665802003510

1665802018536

里氏替换原则是面向对象设计原则之一,由 Barbara liskov 提出,其基本思想是,一个软件实体如果使用的是一个基类对象,那么一定适用于其子类对象,而且觉察不出基类对象和子类对象的区别,即把基类都替换成它的子类,程序的行为没有变化。反过来则不一定成立,如果一个软件实体使用的是一个子类对象,那么它不一定适用于基类对象。 在运用里氏替换原则时,尽量将一些需要扩展的类或者存在变化的类设计为抽象类 或者接口,并将其作为基类,在程序中尽量使用基类对象进行编程。由于子类继承基类并实现其中的方法,程序运行时,子类对象可以替换基类对象,如果需要对类的行为进行修改,可以扩展基类,增加新的子类,而无需修改调用该基类对象的代码。

1665802206664

装饰(Decorator)模式可以在不修改对象外观和功能的情况下添加或删除对象功能。它可以使用一种对客户端来说是透明的方法来修改对象的功能,也就是使用初始类的子类实例对初始对象进行授权。装饰模式还为对象动态地添加了额外的重任,这样就在不使用静态继承的情况下,为修改对象功能提供了灵活的选择。 在以下情况中,应该使用装饰模式:

・ 想要在单个对象中动态并且透明地添加责任,而这样并不会影响其他对象;

・ 想要在以后可能要修改的对象中添加责任;

・ 当无法通过静态子类化实现扩展时。

1665802498039

1665802509630

软件重用分垂直式重用与水平式重用,垂直式重用是指局限于某一垂直领域的重用,如只在电力系统中用到的构件;而水平式重用是指通用领域的重用,如标准函数库,任何软件都能用,所以是水平式重用。

# 126 ~

1665729141295

白盒测试也称为结构测试,主要用于软件单元测试阶段,测试人员按照程序内部逻辑结构设计测试用例,检测程序中的主要执行通路是否都能按预定要求正确工作。白盒测试方法主要有控制流测试、数据流测试和程序变异测试等。

控制流测试根据程序的内部逻辑结构设计测试用例,常用的技术是逻辑覆盖。主要的覆盖标准有语句覆盖、判定覆盖、条件覆盖、条件 / 判定覆盖、条件组合覆盖、修正的条件 / 判定覆盖和路径覆盖等。

语句覆盖是指选择足够多的测试用例,使得运行这些测试用例时,被测程序的每个语句至少执行一次。

判定覆盖也称为分支覆盖,它是指不仅每个语句至少执行一次,而且每个判定的每种可能的结果(分支)都至少执行一次。

条件覆盖是指不仅每个语句至少执行一次,而且使判定表达式中的每个条件都取得各种可能的结果。

条件 / 判定覆盖同时满足判定覆盖和条件覆盖。它的含义是选取足够的测试用例,使得判定表达式中每个条件的所有可能结果至少出现一次,而且每个判定本身的所有可能结果也至少出现一次。

条件组合覆盖是指选取足够的测试用例,使得每个判定表达式中条件结果的所有可能组合至少出现一次。

修正的条件 / 判定覆盖。需要足够的测试用例来确定各个条件能够影响到包含的判定结果。

路径覆盖是指选取足够的测试用例,使得程序的每条可能执行到的路栏都至少经过一次(如果程序中有环路,则要求每条环路路径至少经过一次)。

1665729591809

软件测试在将软件交付给客户之前所必须完成的重要步骤。软件调试(排错)与成功的测试形影相随。测试成功的标志是发现了错误,根据错误迹象确定错误的原因和准确位置,并加以改正,主要依靠软件调试技术。

软件调试与软件测试区别主要体现在以下几个方面:

①测试的目的是找出存在的错误,而调试的目的是定位错误并修改程序以修正错误;

②调试是测试之后的活动,测试和调试在目标、方法和思路上都有所不同;

③测试从一个已知的条件开始,使用预先定义的过程,有预知的结果;调试从一个未知的条件开始,结束的过程不可预计;

④测试过程可以实现设计,进度可以实现确定;而调试不能描述过程或持续时间。

1665729745700

根据国家标准 GB/T15532-2008,软件测试可分为单元测试、集成测试、配置项测试、系统测试、验收测试和回归测试等类别。

单元测试也称为模块测试,测试的对象是可独立编译或汇编的程序模块、软件构件或面向对象软件中的类(统称为模块),其目的是检查每个模块能否正确地实现设计说明中的功能、性能、接口和其他设计约束等条件,发现模块内可能存在的各种差错。单元测试的技术依据是软件详细设计说明书

集成测试的目的是检查模块之间,以及模块和己集成的软件之间的接口关系,并验证已集成的软件是否符合设计要求。集成测试的技术依据是软件概要设计文档

系统测试的对象是完整的、集成的计算机系统,系统测试的目的是在真实系统工作环境下,验证完整的软件配置项能否和系统正确连接,并满足系统 / 子系统设计文档和软件开发合同规定的要求。系统测试的技术依据是用户需求或开发合同。

配置项测试的对象是软件配置项,配置项测试的目的是检验软件配置项与软件需求规格说明的一致性。

确认测试主要验证软件的功能、性能和其他特性是否与用户需求一致。

验收测试是指针对软件需求规格说明,在交付前以用户为主进行的测试。 回归测试的目的是测试软件变更之后,变更部分的正确性和对变更需求的复合型,以及软件原有的、正确的功能、性能和其他规定的要求的不损害性。

1665730955800

EJB 分为会话 Bean、实体 Bean 和消息驱动 Bean。

1. 会话 Bean:用于实现业务逻辑,它可以是有状态的,也可以是无状态的。每当客户端请求时,容器就会选择一个会话 Bean 来为客户端服务。会话 Bean 可以直接访问数据库,但更多时候,它会通过实体 Bean 实现数据访问。

2. 实体 Bean:用于实现 O/R 映射,负责将数据库中的表记录映射为内存中的实体对象,事实上,创建一个实体 Bean 对象相当于新建一条记录,删除一个实体 Bean 会同时从数据库中删除对应记录,修改一个实体 Bean 时,容器会自动将实体 Bean 的状态和数据库同步。

3. 消息驱动 Bean 是 EJB3.0 中引入的新的企业 Bean,它基于 JMS 消息,只能接收客户端发送的 JMS 消息然后处理。MDB 实际上是一个异步的无状态会话 Bean,客户端调用 MDB 后无需等待,立刻返回,MDB 将异步处理客户请求。这适合于需要异步处理请求的场合,比如订单处理,这样就能避免客户端长时间的等待一个方法调用直到返回结果。

1665731228152

外部设计处于软件设计的开始阶段,主要是按系统需求说明来确定此系统的软件结构和对应于系统需求说明,设计出各个功能部分的功能和接口。

内部设计处于软件工程中的概要设计阶段,按照外部设计中确立的系统软件结构,来细化此系统各个功能部件以及各个部件接口的设计,并且详细给出各个功能部件详细的数据输入、输出设计。内部设计细化外部设计中的各种功能。

1665738570620

与传统的结构化系统相比,面向对象系统具有三个明显特征,即封装性、继承性与多态性。封装性决定了面向对象系统的测试必须考虑到信息隐蔽原则对测试的影响,以及对象状态与类的测试序列,因此在测试一个类时,仅对该类的每个方法进行测试是不够的;继承性决定了面向对象系统的测试必须考虑到继承对测试充分性的影响,以及误用引起的错误;多态性决定了面向对象系统的测试必须考虑到动态绑定对测试充分性的影响、抽象类的测试以及误用对测试的影响。

1665744130035

单元测试也称为模块测试,测试的对象是可独立编译或汇编的程序模块、软件构件或面向对象软件中的类(统称为模块),其目的是检查每个模块能否正确地实现设计说明中的功能、性能、接口和其他设计约束等条件,发现模块内可能存在的各种差错。单元测试的技术依据是软件详细设计说明书。

测试一个模块时,可能需要为该模块编写一个驱动模块和若干个桩模块。

驱动模块用来凋用被测模块,它接收测试者提供的测试数据,并把这些数据传送给被测模块,然后从被测模块接收测试结果,并以某种可见的方式将测试结果返回给测试人员;

桩模块用來模拟被测模块所调用的子模块,它接受被测模块的调用,检验调用参数,并以尽可能简单的操作模拟被调用的子程序模块功能,把结果送回被测模块。顶层模块测试时不需要驱动模块,底层模块测试时不要桩模块。

笮元测试策略主要包括自顶向下的单元测试、自底向上的单元测试、孤立测试和综合测试策略。

①自顶向下的单元测试先测试上层模块,再测试下层模块。测试下层模块时由于它的上层模块已测试过,所以不必另外编写驱动模块。

②自底向上的单元测试。自底向上的单元测试先测试下层模块,再测试上层模块。测试上层模块由于它的下层模块己经测试过,所以不必另外编写桩模块。

③孤立测试不需要考虑每个模块与其他模块之间的关系,逐一完成所有模块的测试。由于各模块之间不存在依赖性,单元测试可以并行进行,但因为需要为每个模块单独设计驱动模块和桩模块,增加了额外的测试成本。

④综合测试。上述三种单元测试策略各有利弊,实际测试时可以根据软件特点和进度安排情况,将几种测试方法混合使用。

1665744558639

原型是软件系统的初始版本,用来演示概念并尝试设计选择,通常用来发现更多的问题和可能的解决方案。快速迭代式的原型开发能够有效控制成本,根据原型与最终产品之间的关系,原型开发分为三类:抛弃式原型开发利用原型验证和澄清系统的需求描述,重新构造系统:演化式原型开发逐步改进和细化原型,将原型进化直至产生出目标系统;增量式原型开发在建立软件总体设计的基础上,采用增量开发方法,使原型成为最终系统。

1665744690686

系统输入设计中,通常通过内部控制的方式验证输入数据的有效性。数据类型检查确保输入了正确的数据类型;自检位用于对主关键字进行基于校验位的检查;域检査用于验证数据是否位于合法的取值范围;格式检查按照已知的数据格式对照检查输入数据的格式。

1665744866957

静态分析通过解析程序文本从而识别出程序语句的各个部分,审查可能的缺陷和异常之处,静态分析包括五个阶段:

控制流分析阶段找出并突出显示那些带有多重出口或入口的循环以及不可达到的代码段;

数据使用分析阶段突出程序中变量的使用情况;

接口分析阶段检查子程序和过程声明及它们使用的一致性;

信息流分析阶段找出输入变量和输出变量之间的依赖关系:

路径分析阶段找出程序中所有可能的路径并画出在此路径中执行的语句。

1665744981097

人的因素在系统输入设计中扮演了很重要的角色。输入应该尽可能地简单,以降低错误发生的可能性,如对于范围可控的数据,使用选择的方式替代用户输入;只输入变化的数据等。输入应该尽可能使用已有含义明确的设计,需要采用模仿的方式而非创新。为了避免用户理解的二义性,应该对表格中输入的数据给出提示信息。

1665745137291

系统测试是将已经确认的软件、计算机硬件、外设和网络等其他因素结合在一起,进行信息系统的各种组装测试和确认测试,其目的是通过与系统的需求相比较,发现开发的系统与用户需求不符或矛盾的地方。

系统测试是根据系统方案说明书来设计测试例子的,

常见的系统测试主要有以下内容:

  1. 恢复测试:恢复测试监测系统的容错能力。检测方法是采用各种方法让系统出现故障,检验系统是否按照要求能从故障中恢复过来,并在约定的时间内开始事务处理,而且不对系统造成任何伤害。如果系统的恢复是自动的(由系统自动完成),需要验证重新初始化、检查点、数据恢复等是否正确。如果恢复需要人工干预,就要对恢复的平均时间进行评估并判断它是否在允许的范围内。
  2. 安全性测试:系统的安全性测试是检测系统的安全机制、保密措施是否完善,主要是为了检验系统的防范能力。测试的方法是测试人员模拟非法入侵者,采用各种方法冲破防线。系统安全性设计准则是使非法入侵者所花费的代价比进入系统后所得到的好处要大,此时非法入侵已无利可图。
  3. 强度测试:是对系统在异常情况下的承受能力的测试,是检查系统在极限状态下运行时,性能下降的幅度是否在允许的范围内。因此,强度测试要求系统在非正常数量、频率或容量的情况下运行。强度测试主要是为了发现在有效的输入数据中可能引起不稳定或不正确的数据组合。例如,运行使系统处理超过设计能力的最大允许值的测试例子;使系统传输超过设计最大能力的数据,包括内存的写入和读出等。
  4. 性能测试:检査系统是否满足系统设计方案说明书对性能的要求。性能测试覆盖了软件测试的各阶段,而不是等到系统的各部分都组装之后,才确定系统的真正性能。通常与强度测试结合起来进行,并同时对软件、硬件进行测试。软件方面主要从响应时间、处理速度、吞吐量、处理精度等方面来检测。
  5. 可靠性测试:通常使用以下两个指标来衡量系统的可靠性:平均失效间隔时间 MTBF (mean time between failures)是否超过了规定的时限,因故障而停机时间 MTTR (mean time to repairs)在一年中不应超过多少时间。
  6. 安装测试:在安装软件系统时,会有多种选择。安装测试就是为了检测在安装过程中是否有误、是否容易操作等。主要监测系统的每一个部分是否齐全,硬件的配置是否合理,安装中需要产生的文件和数据库是否已产生,其内容是否正确等。

1665745654173

确认测试主要用于验证软件的功能、性能和其他特性是否与用户需求一致。根据用户的参与程度,通常包括以下 4 种类型。

① 内部确认测试。内部确认测试主要由软件开发组织内部按照软件需求规格说明书进行测试。

② α 测试和 β 测试。对于通用产品型的软件开发而言,α 测试是指由用户在开发环境下进行测试,通过 α 测试以后的产品通常称为 α 版;β 测试是指由用户在实际使用环境下进行测试,通过 β 测试的产品通常称为 β 版。一般在通过 β 测试后,才能把产品发布或交付给用户。

③验收测试。验收测试是指针对软件需求规格说明书,在交付前以用户为主进行的测试。其测试对象为完整的、集成的计算机系统。验收测试的目的是,在真实的用户工作环境下,检验软件系统是否满足开发技术合同或软件需求规格说明书。验收测试的结论是用户确定是否接收该软件的主要依据。

系统测试的目的是在真实系统工作环境下,验证完整的软件配置项能否和系统正确连接,并满足系统 / 子系统设计文档和软件开发合同规定的要求。系统测试的主要内容包括功能测试、健壮性测试、性能测试、用户界面测试、安全性测试、安装与反安装测试等。其中性能测试包括负载测试、压力测试、可靠性测试和并发测试。

1665745982766

软件集成测试也称为组装测试、联合测试(对于子系统而言,则称为部件测试)。它将已通过单元测试的模块集成在一起,主要测试模块之间的协作性。从组装策略而言,可以分为一次性组装测试和增量式组装(包括自顶向下、自底向上及混合式)两种。集成测试计划通常是在软件概要设计阶段完成的,集成测试一般采用黑盒测试方法。

1665746605681

确认性测试也称为有效性测试,主要包括验证软件的功能、性能及其他特性是否与用户要求(需求)一致。确认测试计划通常是在需求分析阶段完成的。根据用户的参与程度,通常包括以下四种类型:内部确认测试(由软件开发组织内部按软件需求说明书进行测试)、Alpha 测试(由用户在开发环境下进行测试)、Beta 测试(由用户在实际使用环境下进行测试)和验收测试(针对软件需求说明书,在交付前以用户为主进行的测试)

1665746714761

测试可以分为动态测试与静态测试。动态测试是通过运行程序发现错误,包括黑盒测试(等价类划分、逻辑覆盖、基本路径、边界值分析法、错误推测法)与白盒测试(各种类型的覆盖测试)。静态测试是人工测试方式,包括桌前检查(桌面检查)、代码走查、代码审查

1665746870293

系统测试是将已经确认的软件、计算机硬件、外设和网络等其他因素结合在一起, 进行信息系统的各种集成测试和确认测试,其目的是通过与系统的需求相比较,发现所开发的系统与用户需求不符或矛盾的地方。系统测试是根据系统方案说明书来设计测试用例,常见的系统测试主要有恢复测试、安全性测试、压力测试、性能测试、可靠性测试、可用性测试、可维护性测试和安装测试

1665747039862

1665747130512

在系统交付使用后,改变系统的任何工作,都可以被称为维护。在系统运行过程中,软件需要维护的原因是多样的,根据维护的原因不同,可以将软件维护分为以下 4 种:

①正确性(改正性)维护。改正在系统开发阶段已发生而系统测试阶段尚未发现的错误。

②适应性维护。在使用过程中,外部环境(新的硬、软件配置)、数据环境(数据库、数据格式、数据输入 / 输出方式、数据存储介质)可能发生变化。为使软件适应这种变化,而去修改软件的过程就称为适应性维护。

③完善性维护。在软件的使用过程中,用户往往会对软件提出新的功能与性能要求。为了满足这些要求,需要修改或再开发软件,以扩充软件功能、增强软件性能、改进加工效率、提高软件的可维护性。这种情况下进行的维护活动称为完善性维护。

④预防性维护。这是指为了适应未来的软硬件环境的变化,应主动增加预防性的新的功能,以使应用系统适应各类变化而不被淘汰。

1665747489505

软件测试是为了发现错误而执行程序的过程。黑盒测试也称为功能测试,是根据规格说明所规定的功能来设计测试用例,它不考虑程序的内部结构和处理过程。常用的黑盒测试技术有等价类划分、边值分析、错误猜测和因果图等。

1665747509134

4+1 视图即:逻辑视图、开发视图、物理视图(部署视图)、进程视图、场景

1665747585844

可修改性(modifiability)是指能够快速地以较高的性能价格比对系统进行变更的能力。通常以某些具体的变更为基准,通过考察这些变更的代价衡量可修改性。

可修改性包含四个方面。
1. 可维护性(maintainability)。这主要体现在问题的修复上:在错误发生后修复软件系统。为可维护性做好准备的软件体系结构往往能做局部性的修改并能使对其他构件的负面影响最小化。
2. 可扩展性(extendibility)。这一点关注的是使用新特性来扩展软件系统,以及使用改进版本来替换构件并删除不需要或不必要

1665747680137

根据该工程各作业与紧前作业的衔接情况以及正常进度下所需的天数,可以绘制如下的进度计划网络图:

1665747793721

该工程的关键路径为 A-C-D,正常进度的总工期为 3+4+5=12 天,总费用(包括 12 天的间接费用)为 12X5+10+15+12+18=115 万元。 作业 A、B、C、D 赶工时,每天赶工需要分别增加费用 4、2、4、2 万元。而缩短总工期可以节省间接费用。如果要缩短总工期,必须先缩短关键路径上的作业时间。关键路径上最省钱赶工的作业是 D。 由于 A-B 路径需要 10 天,因此只能先尝试对作业 D 缩短 2 天,总工期就可以缩短 2 天,可以节省间接费用 2X5=10 万元,但赶工作业 D 增加了 4 万元,因此合计可以节省 6 万元。此时,总费用为 109 万元,总工程为 10 天,关键路径有两条:A-B 和 A-C-D。 然后尝试对作业 B 和作业 D 各缩短 1 天。关键路径不变。总工期减少 1 天,间接费用节省 5 万元,但赶工 B 和 D 各 1 天需要增加费用 4 万元,所以还能节省 1 万元。此时,总费用为 108 万元,总工期为 9 天。 再尝试对作业 A 缩短 2 天,节省间接费用 10 万元,但增加赶工费用 8 万元,还能节省 2 万元。此时,关键路径为 A-B 和 A-C-D,总工期为 1+6=7 天,总费用为 106 万元。 现在,作业 B 还能缩短 3 天,作业 C 还能缩短 2 天。总工期只能再缩短 2 天。作业 B 和 C 每缩短 1 天,即总工期每减少 1 天,间接费用节省 5 万元,而作业 B 和 C 的赶工将增加费用 6 万元,并不合算。 所以,该工程最低费用的进度计划网络图如下: 此时,总费用为 106 万元,总工期为 7 天。

因为作业是有天数的,所以将作业画在边上,而不是顶点上。

上面还没做