软件工程

📝 13 篇文章
📅 最新: 2024/12/19

软件工程复习 第十章

# 第十章 软件实现 ## 编程语言 在软件设计阶段,得到了实现目标系统的解决方案,并用模型图、伪代码等设计语言表述出来。编码的过程就是把软件设计阶段得到的解决方案转化为可以在计算机上运行的软件产品的过程。 选择合适的编程语言是编码过程的关键。可以说,编程语言是人与计算机交互的基本工具,它定义了计算机的一组语法规则,通过这些语法规则可以把人的意图、思想等转化为计算机可以理解的指令,进而让计算机帮助人类完成某些任务。软件开发人员使用编程语言来实现目标系统的功能。 ### 编程语言的发展与分类 - 机器语言 - 汇编语言 - 高级语言 - 超高级语言 ### 选择编程语言需要考虑的因素 - 待开发系统的应用领域,即项目的应用范围 - 用户的要求 - 将使用何种工具进行软件开发 - 软件开发人员的喜好和能力 - 软件的可移植性要求 - 算法和数据结构的复杂性 - 平台支持 ## 编程风格 编程风格是指源程序的书写习惯,比如变量的命名规则、代码的注释方法、缩进等。具有良好编程风格的源程序具有较强的可读性、可维护性,还能提高团队开发的效率。 良好的个人编程风格是优秀程序员素质的一部分,项目内部相对统一的编程风格也使得该项目的版本管理、代码评审等软件工程相关工作更容易实现。在大型软件开发项目中,为了控制软件开发的质量,保证软件开发的一致性,遵循一定的编程风格尤为重要。 ### 如何做到良好的编程风格 - 版权和版本声明应该在每个代码文件的开头声明代码的版权和版本,主要内容如下: - 版权信息 - 文件名称、标识符、摘要 - 当前版本号、作者/修改者、完成日期 - 版本历史信息。 - 在程序编写过程中应该注意代码的版式,使代码更加清晰易读。对空行、空格的使用及对代码缩进的控制与程序的视觉效果密切相关。编程人员基本积累了一些程序版式规则 - 在每个类声明之后、每个函数定义结束之后都要加空行 - 在一个函数体内,逻辑上密切相关的语句之间不加空行,其他地方应加空行分隔 - 一行代码只做一件事情,如只定义一个变量,或只写一条语句 - if、for、while、do等语句独占一行,执行语句不得紧跟其后,不论执行语句有多少都要加{} - 尽可能在定义变量的同时初始化该变量 - 关键字之后要留空格,函数名之后不要留空格,“,”之后要留空格 - 赋值操作符、比较操作符、算术操作符、逻辑操作符、位域操作符等二元操作符的前后应当加空格,一元操作符前后不加空格 - 程序的分界符“{”和“}”应独占一行并且位于同一列,同时与引用它们的语句左对齐 - 代码行最大长度宜控制在70~80个字符 - 长表达式要在低优先级操作符处拆分成新行,操作符放在新行之首 - 注释注释阐述了程序的细节,是软件开发人员之间以及开发人员和用户之间交流的重要途径。做好注释工作有利于日后的软件维护。注释也需要遵循一定的规则,比如注释需要提供哪些方面的信息、注释的格式、注释的位置等。 - 注释的分类 - 序言注释位于模块的起始部分,说明模块的详细信息,如模块的用途、模块的参数描述、模块的返回值描述、模块内捕获的异常类型、实现该模块的软件开发人员及实现时间、对该模块做过修改的开发人员及修改日期等 - 行内注释位于模块内部,用于解释较难理解、逻辑性强或比较重要的代码,提高代码的可理解性。 - 注释的作用: - ①版本、版权声明 - ②函数接口说明 - ③重要的代码行或段落提示。 - 使用注释的基本规则 - 注释是对代码的“提示”,而不是文档,注释的花样要尽量少 - 注释应当准确、易懂,防止注释有二义性 - 注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方 - 当代码比较长,特别是有多重嵌套时,应当在一些段落的结束处加注释,以便于阅读。 - 命名规则 - 按照标识符的实际意义命名,使其名称具有直观性,能够体现标识符的语义。这样可以帮助开发人员理解和记忆标识符 - 标识符的长度应当符合“最小长度与最大信息量”原则 - 命名规则尽量与采用的操作系统或开发工具的风格一致,如缩写的使用、字母大小写的选择、对常量和变量命名的区分等 - 变量名不要过于相似,这样容易引起误解 - 在定义变量时,最好注释其含义和用途 - 程序中不要出现仅靠大小写区分的相似的标识符 - 尽量避免名称中出现数字编号,除非逻辑上的确需要编号 - 数据说明 - 在数据说明时应该遵循一定的次序 - 当在同一语句中说明相同数据类型的多个变量时,变量一般按照字母顺序排列 - 对于复杂数据结构的说明,为了容易理解,需要添加必要的注释 - 语句构造 - 不要为了节省空间而把多条语句写在一行 - 合理利用缩进来体现语句的不同层次结构 - 在含有多个条件语句的算术表达式或逻辑表达式中使用括号来清晰地表达运算顺序 - 将经常使用并且具有一定独立功能的代码封装为一个函数或公共过程 - 避免使用goto语句 - 避免使用多层嵌套语句 - 避免使用复杂的判定条件。 ## 面向对象实现 面向对象实现主要是指把面向对象设计的结果翻译成用某种程序语言书写的面向对象程序。 采用面向对象方法开发软件的基本目的和主要优点是通过重用提高软件的生产率。因此,应该优先选用能够最完善、最准确地表达问题域语义的面向对象语言。

软件工程复习 第一章

# 第一章 软件与软件工程 ## 软件 软件包括程序、程序的处理对象——数据,以及与程序开发、维护和使用有关的图文资料(文档) - 特点 - (1)软件是一种逻辑实体,而不是具体的物理实体,因而它具有抽象性。 - (2)软件没有明显的制造过程 - (3)在软件的运行和使用期间,不会出现硬件中出现的机械磨损、老化问题,然而它存在退化问题 - (4)计算机的开发与运行对计算机系统有着不同程度的依赖性。 - (5)软件开发至今尚未完全摆脱人工的开发方式。 - (6)软件本身是复杂的。 - (7)软件成本相当昂贵。 - (8)相当多的软件工作涉及社会因素。 - 分类 - ![](../../../../assets/default.png) ## 软件危机 软件危机是指计算机软件在开发和维护过程中遇到的一系列严重问题 - 表现 - (1)开发出来的软件产品不能满足用户的需求 - (2)相比越来越廉价的硬件,软件代价过高。 - (3)软件质量难以得到保证,且难以发挥硬件潜能。 - (4)难以准确估计软件开发、维护的费用以及开发周期 - (5)难以控制开发风险,开发速度赶不上市场变化。 - (6)软件产品修改维护困难,集成遗留系统更困难。 - (7)软件文档不完备,并且存在文档内容与软件产品不符的情况。 - 出现的原因 - (1)忽视软件开发前期的需求分析。 - (2)开发过程缺乏统一的、规范化的方法论的指导。 - (3)文档资料不齐全或不准确。 - (4)忽视与用户之间、开发组成员之间的交流。 - (5)忽视测试的重要性。 - (6)不重视维护或由于上述原因造成维护工作困难。 - (7)从事软件开发的专业人员对这个产业认识不充分,缺乏经验 - (8)没有完善的质量保证体系 - 启示:使我们更加深刻地认识到软件的特性以及软件产品开发的内在规律。 - (1)软件产品是复杂的人造系统,具有复杂性、不可见性和易变性,难以处理。 - (2)个人或小组在开发小型软件时使用到的非常有效的编程技术和过程,在开发大型、复杂系统时难以发挥同样的作用。 - (3)从本质上讲,软件开发的创造性成分很大,发挥的余地也很大,很接近于艺术。它介于艺术与工程之间,并逐步向工程一段漂移,但很难发展到完全的工程。 - (4)计算机和软件技术的快速发展,提高了用户对软件的期望,促进了软件产品的演化,为软件产品提出了新的、更多的需求,难以在可接受的开发进度内保证软件的质量。 - (5)几乎所有的软件项目都是新的,而且是不断变化的。项目需求在开发过程中会发生变化,而且很多原来预想不到的问题会出现,适当调整设计和实现手段是不可避免的。 - (6)“人月神化”现象——生产力与人数并不成正比。 ## 软件工程 1968年,在北大西洋公约组织举行的一次学术会议上,将其定义为“为了经济地获得可靠的和能在实际机器上高效运行的软件,而建立和使用的健全的工程规则”。 IEEE(Institute of Electrical and Electronics Engineers,电气和电子工程师协会)对软件工程的定义为: (1)将系统化、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。 (2)对(1)中所述方法的研究。 过程、方法和工具是软件工程的3个要素 - 软件工程研究的内容 - (1)软件开发技术。主要研究软件开发方法、软件开发过程、软件开发工具和环境。 - (2)软件开发过程管理。主要研究软件工程经济学和软件管理学。 - 目标和原则 - (1)达到要求的软件功能。 - (2)取得较好的软件性能。 - (3)开发出高质量的软件。 - (4)付出较低的开发成本。 - (5)需要较低的维护费用。 - (6)能按时完成开发工作,及时交付使用。 - 7条基本原则 - 用分阶段的生命周期计划严格管理 - 坚持进行阶段评审 - 实行严格的产品控制 - 采用现代程序设计技术 - 软件工程结果应能清楚地审查 - 开发小组的人员应该少而精 - 承认不断改进软件工程实践的必要性 - 15个知识领域 - 软件需求 - 软件设计 - 软件构建 - 软件测试 - 软件维护 - 软件配置管理 - 软件工程管理 - 软件工程过程 - 软件工程模型和方法 - 软件质量 - 软件工程职业实践 - 软件工程经济学 - 计算基础 - 数学基础 - 工程基础 ## 软件开发方法 - 结构化方法 - 面向数据结构方法 - 面向对象方法 - 形式化方法 ## 软件工程工具 - (1)按照功能划分:功能是对软件进行分类最常用的标准,按照功能划分,软件工程工具可分为可视化建模工具、程序开发工具、自动化测试工具、文档编辑工具、配置管理工具、项目管理工具等。 - (2)按照支持的过程划分:软件工程工具可分为设计工具、编程工具、维护工具等 - (3)按照支持的范围划分:软件工程工具可以分为窄支持、较宽支持和一般支持工具。窄支持工具支持软件工程过程中的特定任务,一般将称之为工具;较宽支持工具支持特定的过程阶段,一般由多个工具集合而成,称之为工作台;一般支持工具支持覆盖软件过程的全部或大部分阶段,包含多个不同的工作台,称之为环境。

软件工程复习 第十一章

# 第十一章 软件测试 **软件测试**是发现软件中错误和缺陷的主要手段。为了保证软件产品的质量,软件开发人员通过软件测试发现产品中存在的问题,并及时修改 **软件缺陷**是指软件产品中存在的问题,具体表现为用户所需的功能没有实现,无法满足用户的需求。 在软件开发过程的任何阶段都可能引入缺陷。缺陷被引入的阶段越早,在软件开发后期修复这些缺陷造成的成本损失就越大。 **软件测试工作应该贯穿于整个开发过程。** - 原则 - 完全测试是不可能的 - 测试中存在风险 - 软件测试只能表明缺陷存在,而不能证明软件产品已经没有缺陷 - 软件产品中潜在的错误数与已发现的错误数成正比 - 让不同的测试人员参与到测试工作中 - 让开发小组和测试小组分立,开发工作和测试工作不能由同一部分人来完成 - 尽早并不断地进行测试,使测试工作贯穿于整个软件开发的过程中 - 在设计测试用例时,应包括输入数据和预期的输出结果两个部分,并且输入数据不仅包括合法的情况,还应该包括非法的输入情况 - 要集中测试容易出错或错误较多的模块 - 应该长期保留所有的测试用例 - 软件测试模型 - 要素 - 测试的时间 - 测试的步骤 - 如何计划测试 - 不同阶段的测试中应该关注哪些测试对象 - 测试过程中应该考虑哪些问题 - 测试需要达到的目标等。 - 模型 - V - W - H - 按照质量因素划分的软件测试 - 功能测试。,检验最终的软件产品是否实现了需求规格说明书中的所有功能需求 - 可靠性测试。关注于程序输出结果的准确性 - 可用性测试。用来衡量处理服务请求时,应用程序的可用频率 - 性能测试 - 安全性测试 - 配置测试。考察软件系统是否能在多种硬件平台上正常运行 - 兼容性测试.主要关注软件的运行平台和应用系统的版本、标准和规范、数据的共享性 - 安装测试 - 文档测试 - 软件国际化测试和本地化测试 - α测试和β测试。它们都属于验收测试的范畴,是在系统测试之后,产品发布之前进行的测试过程的最后一个阶段。 ## 测试用例 为达到最佳的测试效果或高效地揭露隐藏的错误而精心设计并执行的少量测试数据,称为测试用例。 我们不可能进行穷举测试,为了节省时间和资源,提高测试效率,必须从数量极大的可用测试数据中精心挑选出具有代表性或特殊性的测试数据来进行测试。 测试用例=测试数据+预期测试结果( +测试环境) 测试结果=测试数据+期望结果+实际结果 <mark>一个好的测试用例是在于它能发现至今未发现的错误。</mark> ## 软件测试方法 ### 静态审查 - 自查 - 会审 - 走查 ### 动态审查 #### 黑盒测试 - 定义 - 在黑盒测试中,测试人员把被测试的软件系统看成是一个黑盒子,不需要关心盒子的内部结构和内部特性,只关注软件产品的输入数据和输出结果,从而检查软件产品是否符合它的功能说明。 - 等价类划分法 - 把被测对象的输入域划分为有限个等价区段——“等价类”,以有针对性的等价类少量测试,代替漫无边际的、数量较大的“穷尽”测试或随机测试。 - 分类 - 有效等价类是指对程序的规格说明是有意义的、由合理的输入数据构成的集合 - 无效等价类是指对程序的规格说明是无意义的、由不合理的输入数据构成的集合 - 原则 - 如果输入条件规定了取值范围或个数,则可确定一个有效等价类和两个无效等价类 - 如果输入条件规定了输入值的集合或是规定了“必须如何”的条件,则可确定一个有效等价类和一个无效等价类 - 如果输入条件是布尔表达式,则可以分为一个有效等价类和一个无效等价类 - 如果输入条件是一组值,且程序对不同的值有不同的处理方式,则每个允许的输入值对应一个有效等价类,所有不允许的输入值的集合为一个无效等价类 - 如果规定了输入数据必须遵循的规则,则可以划分出一个有效的等价类(符合规则)和若干无效的等价类(从不同的角度违反规则) - 如已划分的等价类各元素在程序中的处理方式不同,则应将此等价类进一步划分成更小的等价类 - 边界值分析法 - 定义 - 经验表明,处理边界情况时程序最容易发生错误 - 边界类型:下标、数据结构、循环、选择等的边界附近 - 通常选用等价类边界值作为边界值测试的数据 - 一般边界值分析法作为等价类划分法的补充与细化。 - 原则 - 以输入条件的边界的值作为测试用例 - 若规定了值的数量的边界作为测试用例 - 针对每个输出条件 - 输入或输出范围是有序的集合,应注意选取有序集的第一个和最后一个元素作为测试用例 - 分析规格说明,找出其他的可能边界条件 - 错误推测法 - 错误推测法在很大程度上靠直觉和经验进行。它的基本想法是列举出程序中可能有的错误和容易发生错误的特殊情况,并且根据它们选择测试方案。 - 因果图法 - 定义 - 等价类划分法和边界值分析法都主要考虑输入条件,而没有考虑输入条件的各种组合以及各个输入条件之间的相互制约关系。因此,必须考虑描述多种条件的组合,相应地产生多个动作的形式来考虑设计测试用例。这就需要利用因果图法。 - 因果图法是一种黑盒测试方法,它从用自然语言书写的程序规格说明书中寻找因果关系,即利用输入条件与输出和程序状态的改变,由因果图产生判定表。它能够帮助人们按照一定的步骤高效地选择测试用例,还能指出程序规格说明书中存在的问题。 - 使用 - 用C表示原因,E表示结果 - 各节点表示状态 - 取值0表示某状态不出现,取值1表示某状态出现 - 四种关系符号 - ![](../../../../assets/default.png) - 表示约束的符号 - ![](../../../../assets/default.png) - E约束(互斥):表示a和b两个原因不会同时成立,最多有一个可以成立 - I约束(包含):表示a和b两个原因至少有一个必须成立 - O约束(唯一):表示a和b两个条件必须有且仅有一个成立 - R约束(要求):表示a出现时,b也必须出现。 - M约束(强制)表示a是1时,b必须为0。 - 步骤 - 分析程序规格说明书的描述中,哪些是原因,哪些是结果 - 分析程序规格说明书中描述的语义内容,并将其表示成连接各个原因与各个结果的因果图 - 有些原因和结果的组合情况是不可能出现的,为表明这些特定的情况,在因果图上使用若干特殊的符号标明约束条件 - 把因果图转化为决策表 - 为决策表中每一列表示的情况设计测试用例 - 决策表法 - 定义 - 在一些数据处理问题中,某些操作是否实施依赖于多个逻辑条件的取值。在由这些逻辑条件取值的组合构成的多种情况下,分别执行不同的操作。处理这类问题的一个非常有力的工具就是决策表 - 决策表(也称判定表)是分析和表达多逻辑条件下执行不同操作的情况的工具,可以比较明确地表达复杂的逻辑关系和多种条件组合的情况 - 组成 - 条件桩:列出问题的所有条件 - 条件项:列出所列条件下的取值,以及在所有可能情况下的真假值 - 动作桩:列出问题规定可能采取的动作 - 动作项:列出在条件项的各种取值情况下应采取的动作 - 在简化并得到最终决策表后,只要选择适当的输入,满足决策表每一列的输入条件,即可生成测试用例。 - 场景法 - 定义 - 现在很多软件都是用事件触发来控制流程,事件触发时的情形变形成场景,而同一事件不同的触发顺序和处理结果就形成了事件流。这种在软件设计中的思想也可以应用到软件测试中,可生动地描绘出事件触发时的情形,有利于测试者执行测试用例,也更容易理解和执行测试用例。 - 组成 - 基本流:采用黑直线表示,是经过用例的最简单路径,表示无任何差错,程序从开始执行到结束 - 采用不同颜色表示,一个备选流可以从基本流开始,在某个特定条件下执行,然后重新加入基本流中,也可以起源于另一个备选流,或终止用例,不再加入基本流中。 - 步骤 - 根据规格说明,描述出程序的基本流和各个备选流 - 根据基本流和各个备选流生成不同的场景 - 对每一个场景生成相应的测试用例 - 复审生成的所有测试用例,去掉多余的测试用例,确定每一个测试用例的测试数据。 - 选择 - 在任何情况下都必须选择边界值分析方法。经验表明用这种方法设计出的测试用例发现程序错误的能力最强 - 必要时用等价类划分法补充-些测试用例 - 用错误推测法再追加一些测试用例 - 如果程序的功能说明中含有输入条件的组合情况,则可选用因果图法和决策表法 #### 白盒测试 白盒测试有时也被称为玻璃盒测试,它关注软件产品的内部细节和逻辑结构,即把被测的程序看成是一个透明的盒子。 白盒测试利用构建层设计的一部分而描述控制结果来生成测试用例。白盒测试需要清楚了解系统内部结构和工作原理。 - 逻辑覆盖法 - 逻辑覆盖法以程序内在的逻辑结构为基础,根据程序的流程图设计测试用例 - 测试步骤 - 选择逻辑覆盖标准 - 按照覆盖标准列出所有情况 - 选择确定测试用例 - 验证分析运行结果与预期结果 - 语句覆盖:指选择足够的测试用例,使被测语句的每个语句至少执行一次 - 判定覆盖:指选择足够的测试用例,使每个判定的所有可能结果至少出现一次。 - 条件覆盖:指选择足够的测试用例,使判定中的每个条件的所有可能结果至少出现一次 - 判定/条件覆盖:指选择足够的测试用例,使判定中的每个条件的所有可能结果至少出现一次,并且每个判定中条件结果的所有可能组合也至少出现一次。 - 条件组合覆盖:指选择足够的测试用例,使每个判定中条件结果的所有可能组合至少出现一次。 - 路径覆盖:指选择足够的测试用例,使流程图中的每条路径至少经过一次。 - 基本路径法 - 基本路径法是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行的路径集合,从而设计测试用例的方法。**使用基本路径法设计出的测试用例要保证在测试中程序的每条可执行语句至少执行一次。** - 步骤 - 画出控制流图 - 计算环路复杂度 - 导出测试数据 - 准备测试用例 - 圈复杂度的计算 - 给定流图G的圈复杂度=流图中边的数量,-流图中结点的数量 - 给定流图G的圈复杂度=流图G中判定结点的数量+1 - 白盒方法的选择 - 白盒测试还有静态质量度量、域测试、Z路径覆盖等方法 - 选择方法的几条经验 - 在测试中,可采取先静态再动态的组合方式,先进行代码检查和静态结构分析,再进行覆盖测试 - 将静态分析的结果作为引导,通过代码检查和动态测试的方式进一步确认静态分析的结果 - 覆盖测试是白盒测试的重点,一般可使用基本路径法达到语句覆盖标准,对于软件的重点模块,应使用多种覆盖标准衡量测试的覆盖率 - 不同测试阶段的测试重点不同,在单元测试阶段,以代码检查、覆盖测试为主,在集成测试阶段,需要增加静态结构分析等,在系统测试阶段,应根据黑盒测试的结果,采用相应的白盒测试方法。 - 白盒与黑盒的比较 - | 白盒测试 | 黑盒测试 | | --- | --- | | 考察程序逻辑结构 | 不涉及程序结构 | | 用程序结构信息生成测试用例 | 用软件规格说明书生成测试用例 | | 主要适用于单元测试和集成测试 | 可适用于从单元测试到系统验收测试 | | 测试所有逻辑路径 | 某些代码段得不到测试 | #### 灰盒测试 灰盒测试是介于白盒测试和黑盒测试之间的测试方法,它关注输出对于输入的正确性,也关注内部表现,但是不像白盒测试那样详细、完整,只是通过一些表征性的现象、事件、标志来判断内部的运行状态。有时候输出是正确的,但是程序内部已经是错误的,这种情况非常多,如果每次都通过白盒测试来操作,效率会很低,因此可采取灰盒测试这种方法。 灰盒测试结合了白盒测试和黑盒测试的要素,考虑了用户端、特定的系统知识和操作环境。它在系统组件的协同性环境中评价应用软件的设计。可以认为,集成测试就是一类灰盒测试。 ## 测试的步骤 ### 单元测试 在进行单元测试时,被测试的单元本身不是独立的程序,需要为其开发驱动模块和桩模块。 **驱动模块**是用来模拟待测试模块的上级模块。驱动模块在集成测试中接受测试数据,将相关的数据传送给待测模块,启动待测模块,并打印出相应的结果 **桩模块**也称为存根程序,用以模拟待测模块工作过程中调用的模块。 桩模块由待测模块调用,它们一般只进行很少的数据处理,例如打印入口和返回,以便于检验**待测模块与下级模块**的接口。 ### 集成测试 - 组装测试也称集成测试,是在单元测试的基础上,将所有模块按照软件设计要求组装成执行子系统、功能子系统直至应用系统并进行测试的过程。 - 测试内容:主要是模块间的结构和通信,发现软件设计阶段产生的错误 - 测试方法:黑盒测试 - 注意问题 - 接口数据丢失:连接各模块时,穿越模块接口的数据是否会丢失 - 模块功能干扰:一个模块的功能是否对其他模块的功能产生不利影响。 - 组合成功:各个子功能组合起来,能否达到预期的父功能。 - 整体数据结构:全局数据结构是否有问题 - 误差积累:单个模块的误差是否会累积、放大 - 影响数据库:单个模块的错误是否会导致数据库错误 - ~~非增量组装测试方式~~ - 一次组装,然后测试 - 不使用 - 增量组装测试方式 - 增量式集成测试中单元的集成是逐步实现的,集成测试也是逐步完成的 - 一边测试一边组装 - 自顶向下增量式集成测试 - 这种组装方式是将模块按系统程序结构,沿控制层次自项向下进行组装。 - 这种方式在测试过程中较早地验证了主要的控制点和判断点。在一个功能划分合理的程序结构中,判断常出现在较高的层次,因而能较早地遇到。如果主要控制有问题,尽早发现能够大大减少以后的返工。 - 优点:能够尽早发现系统主控方面的问题,驱动真实,上层测试充分。 - 缺点:需要设计大量桩模块、进行大里回归测试,测试用例设计麻烦。 - 自底向上增量式集成测试 - 这种组装方式从程序结构的最底层模块开始组装和测试。 - 由于模块是由底向.上进行组装的,对于一个给定层次的模块,它的子模块(包括子模块的所有下属模块)已经组装并测试完成,以不再要桩模块。在模块的测试过程中需要从子模块得到的信息可以直接得到。 - 基本增殖步骤 - 编写驱动模块,把最底层的模块组合成子功能模块族。 - 用实际模块替换驱动模块,把子功能族组合起来形成更大的功能族。 - 为子系统编写驱动模块,进行新的测试过程。 - 重复步骤②、③,直到完成所有的模块组装测试。 - 优点:桩模块真实,驱动模块和测试用例容易编写;能够尽早查出底层涉及较复杂的算法和实际的I/0模块中的错误。 缺点:系统结构建立晚,系统协调、功能接口问题发现的晚。 - 深度优先与宽度优先 - 无论是自顶向下还是由底向上的方式,都可以选择深度优先或者宽度优先增量方式 - 混合方式(实际使用) ### 确认测试 - 确进一步验证软件的有效性,即验证软件的功能、性能及其他特性是否与用户的要求一致。 - 测试依据:需求规格说明书 - 测试人员:专门测试部门、专业用户、典型用户、专家 - 有效性测试:制定测试计划,运用黑盒法验证软件特性是否与需求符合。 - 软件配置复查:软件配置指软件工程过程中所产生的所有信息项一一文档、报告、程序、表格、数据。随着软件工程过程的进展,软件配置项(SCI software Configuration Item)快速增加和变化,应复查SCI是否齐全。 - 确认测试结果 - 在全部确认测试的测试用例运行完后,所有的测试结果可以分为两类: - 测试结果与预期的结果相符-一这说明软件的这部分功能或性能特征与需求说明书相符合,从而这部分程序可以接受。 - 测试结果与预期的结果不符一-这说明软件的这部分功能或性能特征与需求说明书不一致,因此需要开列一张软件各项缺陷表或软件问题报告,通过与用户的交流,解决所发现的缺陷和错误。 - 测试类型 - 功能测试:根据需求规格说明书和测试需求列表,验证产品的功能是否符合需求规格 - 性能测试:用来测试软件系统在实际的集成系统中的运行性能 - 安装测试:用来确保软件在正常情况和异常情况的不同条件下都不丢失数据或者功能,具体测试活动包括首次安装、升级、完整安装、自定义安装、卸载等 - 可用性测试:检验其是否达到可用性标准 - 压力测试:不是在常规条件下运行手动或自动测试,而是长时间或超大负荷地运行测试软件来测试被测系统的性能、可靠性、稳定性等 - 容量测试:目的是通过测试预先分析出反映软件系统应用特征的某项指标的极限值(如最大并发用户数、数据库记录数等),系统在该极限值下没有出现任何软件故障或还能保持主要功能正常运行 - 安全性测试:目的是验证系统的保护机制是否能够在实际的环境中抵御非法入侵、恶意攻击等非法行为 - 健壮性测试:指在故障存在的情况下,软件还能正常运行的能力 - 图形用户界面测试:包含两方面内容,一是界面实现与界面设计是否吻合,二是界面功能是否正确 - 文档测试:文档包括开发文档、管理文档和用户文档3种 ### 验收测试 验收测试是在系统测试之后进行的测试,目的是验证新建系统产品是否能够满足用户的需要,产品通过验收测试工作才能最终结束。具体说来,验收测试就是根据各自需求说明书的标准,利用工具进行的一项检查工作,其中包括对进程的验收、进程质量是否达到需求说明书的要求,以及是否符合工程的设计要求等,验收测试可分为前阶段验收和竣工验收两个阶段。 验收测试是依据软件开发商和用户之间的合同、软件需求说明书以及相关行业标准、国家标准、法律法规等的要求对软件的功能、性能、可靠性、易用性、可维护性、可移植性等特性进行严格的测试,验证软件的功能、性能及其他特性是否与用户需求一致。 α测试:是用户在开发环境下的测试,或者是开发公司组织内部人员模拟各类用户行为,对即将面市的软件产品进行的测试,它是由开发人员或测试人员进行的测试。在α测试中,主要是确认使用的功能和任务,测试的内容由用户需求说明书决定。α测试是试图发现软件产品的错误的测试,它的关键在于尽可能逼真地模拟实际运行环境和用户对软件产品的操作,并尽最大努力涵盖所有可能的用户操作方式。 β测试:β测试由最终用户实施,通常开发(或其他非最终用户)组织对其的管理很少或不管理。β测试是所有验收测试策略中最主观的:测试员负责创建自己的环境、选择数据,并决定要研究的功能、特性或任务,采用的方法完全由测试员决定。 ### 回归测试 回归测试是指软件系统被修改或扩充后重新进行的测试,回归测试是为了保证软件修改后,没有引入新的错误而重复进行的测试 ## 面向对象的软件测试 在基于面向对象思想的软件开发中,由于面向对象的软件工程方法与传统的软件工程方法有诸多不同,所以传统的软件测试模型对面向对象的软件系统已经不再适用。 在面向对象的软件开发中,人们已经抛弃了传统的测试模型。针对面向对象的开发模型中的面向对象分析(OOA)、面向对象设计(OOD)、面向对象实现(OOP)3个阶段 ### 面向对象分析的测试 结构化需求分析把目标系统看成是一个由若干功能模块组成的集合,而面向对象需求分析以现实世界中的概念为模型结构。前者关注系统的行为,即功能结构,后者更关注于系统的逻辑结构。对面向对象需求分析的测试,要考虑以下方面: - 对认定的对象或类的测试 - 对定义的属性和操作的测试 - 对类之间层次关系的测试 - 对对象之间交互行为的测试 - 对系统逻辑模型的测试等 ### 面向对象设计的测试 与传统的软件工程方法不同的是,面向对象分析和面向对象设计之间并没有严格的界限。实际上,面向对象设计是对面向对象分析结果的进一步细化、纠正和完善。对面向对象设计的测试涉及了面向对象分析的测试内容,但是会更加关注对类及其类之间关系的测试和对类库支持情况的测试。 ### 面向对象实现的测试 面向对象的程序具有封装、继承和多态的特性。测试多态的特性时要尤为注意,因为它使得同一段代码的行为复杂化,测试时需要考虑不同的执行情况和行为。由于系统功能的实现分布在类中,所以本阶段的测试中还要重点评判类是否实现了要求的功能。 ### 面向对象的单元测试 面向对象的单元测试以类或对象为单位。由于类包含一组不同的操作,并且某些特殊的操作可能被多个类共享,因此单元测试不能孤立地测试某个操作,而是将操作作为类的一部分。 ### 面向对象的集成测试 面向对象的集成测试采用基于线程或者基于使用的测试方法。基于线程的测试是指把回应系统外界输入的一组相关的类集成起来,对线程进行集成并测试。基于使用的测试方法按照类对服务器的依赖以及对其他类的依赖程度,把类划分为独立类和依赖类。 独立类是指那些几乎不使用服务器的类。在进行基于使用的测试时,先测试独立类。 依赖类是使用独立类的类,即它们对独立类存在某种程度的依赖。 在测试完独立类后,就可以测试依赖类了。依赖类可能还划分为多个层次,测试时按照逐层向下的顺序,直到测试完整个系统。 ### 面向对象的系统测试及验收测试 在系统测试的过程中,软件开发人员要尽量搭建与用户的实际使用环境相同的平台,检测和评估目标系统是否能作为一个整体,满足用户在性能、功能、安全性、可靠性等各个方面的要求。面向对象的系统测试要以面向对象需求分析的结果为依据,验证需求分析中描述的对象模型、交互模型等各种分析模型。 ## 软件调试 调试(也称为纠错)是在测试发现错误之后排除错误的过程。 虽然调试可以而且应该是一个有序的过程,但是在很大程度上它仍然是一项技巧。软件工程师在评估测试结果时,往往仅面对软件问题的症状,也就是说,错误的外部表现和它的内在原因之间可能并没有明显的联系。调试就是把症状和原因联系起来的尚未被人很好理解的智力过程。 - 强行排错 - 适合于结构比较简单的程序。是使用较多,效率较低的方法。 - 在程序中插入打印语句 - 将内存和寄存器的内容打印或显示出来,然后从中找出错误的原因 - 屏蔽部分程序 - 把不需要执行的语句段加上注释符号,使其不再运行 - 在不需要执行的语句段前加上判断值为假的if语句,使其不再运行 - 调试完成后再恢复 - 借助于调试工具 - 回溯排错 - 演绎排错

软件工程复习 第三章

# 第三章 可行性研究与软件开发计划 ## 项目立项 任何一个完整的软件工程项目都是从项目立项开始的。 - 项目立项包括项目发起、项目论证、项目审核和项目立项4个过程 - 在发起一个项目时,<mark>项目发起</mark>人或单位为寻求他人的支持,要以书面材料的形式递交给项目的支持者和领导,使其明白项目的必要性和可行性。 <mark>项目论证</mark>过程,也就是可行性研究过程。可行性研究就是指在项目进行开发之前,根据项目发起文件和实际情况,对该项目是否能在特定的资源、时间等制约条件下完成做出评估,并且确定它是否值得去开发。 项目经过可行性研究并且认为可行后,还需要报告主管领导或单位,以获得<mark>项目</mark>的进一步<mark>审核</mark>,并得到他们的支持。 项目通过可行性研究和主管部门的批准后,将其列入项目计划的过程,叫做<mark>项目立项</mark>。 ## 可行性研究的任务 可行性研究需要从多个方面进行评估,主要包括:战略可行性、操作可行性、计划可行性、技术可行性、社会可行性、市场可行性、经济可行性和风险可行性等。 - (1)战略可行性研究主要从整体的角度考虑项目是否可行,如提出的系统对组织目标具有怎样的贡献、新系统对目前的部门和组织结构有何影响、系统将以何种方式影响人力水平和现存雇员的技术、它对组织整个人员开发策略有何影响,等等。 - (2)操作可行性研究主要考虑系统是否能够真正解决问题;系统一旦安装后,是否有足够的人力资源来运行系统;用户对新系统具有抵触情绪是否可能使操作不可行;人员的可行性等问题。 - (3)计划可行性研究主要估计项目完成所需的时间并评估项目的时间是否足够。 - (4)技术可行性研究主要考虑项目使用技术的成熟程度;与竞争者的技术相比,所采用技术的优势及缺陷;技术转换成本;技术发展趋势及所采用技术的发展前景;技术选择的制约条件等。 - (5)社会可行性研究主要考虑项目是否满足所有项目涉及者的利益;是否满足法律或合同的要求等。 - (6)市场可行性研究主要包括研究市场发展历史与发展趋势,说明本产品处于市场的什么发展阶段;本产品和同类产品的价格分析;统计当前市场的总额、竞争对手所占的份额,分析本产品能占多少份额;分析产品消费群体的特征、消费方式以及影响市场的因素;分析竞争对手的市场状况;分析竞争对手在研发、销售、资金、品牌等方面的实力;分析自己的实力等。 - (7)经济可行性研究主要是研究系统开发和运行需要的成本与得到的效益,分析成本效益。 - (8)风险可行性研究主要是考虑项目在实施过程中可能遇到的各种风险因素,以及每种风险因素可能出现的概率和出现后的影响程度。 ## 技术可行性 技术可行性主要研究待开发系统的功能、性能和限制条件,确定现有技术能否实现有关的解决方案,在现有的资源条件下实现新系统的技术风险有多大。这里的资源条件是指已有的或可以得到的软硬件资源、现有开发项目人员的技术水平和已有的工作基础。 在评估技术可行性时,需要考虑以下情况:了解当前最先进的技术,分析相关技术的发展是否支持新系统;确定资源的有效性,如新系统的软硬件资源是否具备,开发项目的人员在技术和时间上是否可行等;分析项目开发的技术风险,即能在给定的资源和时间等条件下,设计并实现系统的功能和性能等。 <mark>技术可行性研究往往是系统开发过程中难度最大的工作,是可行性研究的关键。</mark> ## 操作可行性 - 操作可行性是对开发系统在一个给定的工作环境中能否运行或运行好坏程度的衡量。操作可行性研究决定在当前的政治意识形态、法律法规、社会道德、民族意识以及系统运行的组织机构或人员等环境下,系统的操作是否可行。 - 操作可行性往往最容易被忽视或被低估,或者认为它一定是可行的。 ## 经济可行性 成本-效益分析是可行性研究的重要内容,它用于评估基于项目的经济合理性,给出项目开发的成本论证,并将估算的成本与预期的利润进行对比。 一般说来,基于项目的成本由4个部分组成:购置并安装软硬件及有关设备的费用,项目开发费用,软硬件系统安装、运行和维护费用,人员的培训费用。在项目的分析和设计阶段只能得到上述费用的预算,即估算成本。在项目开发完毕并将系统交付用户运行后,上述费用的统计结果就是实际成本。 项目开发效益包括经济效益和社会效益两部分。 - 经济效益是指所使用系统为用户增加的收入,可以通过直接的或统计的方法估算。 - 社会效益只能用定性的方法估算。 - 成本估算 - 代码行技术 - 代码行技术是比较简单的定量估算方法,它将开发每个软件功能的成本和实现这个功能需要使用的源代码行数联系起来。通常根据经验和历史数据估算实现一个功能所需的源代码行数。一旦估算出源代码行数后,用每行代码的平均成本乘以行数即可确定软件的成本。每行代码的平均成本主要取决于软件的复杂程度和薪资水平。 - 任务分解技术 - 首先将开发项目分解为若干相对独立的任务,再分别估算每个任务单独开发的成本,最后累加起来就可得出开发项目的总成本。 - 如果项目比较复杂,如由若干子系统组成,则可以将若干子系统再按开发阶段进一步划分成更小的任务。 - ![](../../../../assets/default.png) - 成本——效益分析 - 分析 - 开发成本:用代码行技术或任务分解技术进行估算。 - 运行费用:取决于系统操作的费用(操作员人数、工作时间和消耗物资等),以及维护费用。 - 系统的经济效益:为使用新系统而增加的收入加上使用新系统可以节省的运行费用。 - 四个考虑方面 - 货币的时间价值 - 投资回收期:累计的经济效益等于最初投资所需要的时间,也就是达到估计开发总成本加_上运行维护费用所需要的时间。 - 纯收入=累计经济效益(折合成现在值)一投资额 - 投资回收率=年经营净现金流量或年均经营净现金流量/原始投资额 - 货币的时间价值 - 通常使用利率的形式表示货币的时间价值。假设年利率为i,如果现在存入P元,则n年后可以得到的价值为: $$ F=P(1+i)^n $$             F就是P元在n年后的价值。反之,如果n年后能收入F元,那么这些钱的现在价值就是: $$ P=\frac{F}{(1+i)^n} $$ - 投资回报期 - 投资回收期是衡量项目价值的常用方法。投资回收期就是使累计的经济效益等于最初投资需要的时间。很明显,投资回收期越短,获得利润的速度就越快,该项目就越值得开发。 - 纯收入 - 纯收入是衡量项目价值的另一项经济指标。纯收入就是在软件生命周期中软件系统的累计经济效益(折合成现在值)与投资之差。 ## 可行性研究步骤 - 步骤 - 明确系统的目标在这一步,可行性分析人员要访问相关人员,阅读分析可以掌握的材料,确认用户需要解决问题的实质,进而明确系统的目标以及为了达到这些目标系统所需的各种资源。 - 分析研究现行系统现行系统是新系统重要的信息来源。新系统应该完成现行系统的基本功能,并在此基础上对现行系统中存在的问题进行改善或修复。可以从3个方面分析现有系统:系统组织结构定义、系统处理流程分析和系统数据流分析。 - 设计新系统的高层逻辑模型这一步从较高层次设想新系统的逻辑模型,概括地描述开发人员对新系统的理解和设想。 - 获得并比较可行的方案开发人员可根据新系统的高层逻辑模型提出实现此模型的不同方案。在设计方案的过程中要从技术、经济等角度考虑各方案的可行性,然后从多个方案中选择出最合适的方案。 - 撰写可行性研究报告可行性研究的最后一步就是撰写可行性研究报告。此报告包括项目简介、可行性分析过程和结论等内容。 - 结论 - (1)可以按计划进行软件项目的开发。 - (2)需要解决某些存在的问题(如资金短缺、设备陈旧和开发人员短缺等)或者需要对现有的解决方案进行一些调整或改善后才能进行软件项目开发。 - (3)一旦待开发的软件项目不具有可行性,就立即停止该软件项目。 ## 制定开发计划 - 项目概述。说明项目的各项主要工作;说明软件的功能和性能;为完成项目应具备的条件;甲方和乙方应承担的工作、完成期限和其他限制条件;应交付软件的名称,所使用的开发语言及存储形式;应交付的文档等。 - 实施计划。说明任务的划分,各项任务的责任人;说明项目开发进度,按阶段应完成的任务,用图表说明每项任务的开始时间和完成时间;说明项目的预算,各阶段的费用支出预算等。 - 人员组织及分工。说明开发该项目所需人员的类型、组成结构和数量等。 - 交付期限。说明项目应交付的日期等。

软件工程复习 第二章

# 第二章 软件工程 ## 软件过程 软件的诞生和生命周期是一个过程,我们总体上称这个过程为软件过程 ## 软件生命周期 软件产品的生命周期是指从设计该产品的构想开始,到软件需求的确定、软件设计、软件实现、产品测试与验收、投入使用以及产品版本的不断更新,到最终该产品被市场淘汰的全过程。 - 生命周期的划分原则 - 各阶段的任务应尽可能相对独立; - 同一阶段各项任务的性质尽可能相同。 - 划分生命周期的优点 - 有利于软件开发工程的组织和管理 - 降低了整个软件开发过程的困难程度 - 对每个阶段都可选用最优的管理方法 - 保证软件质量、提高生产效率. - 划分 - 软件定义 - 问题的定义与可行性研究 - 需求分析 - 软件开发 - 软件设计 - 程序编码 - 软件测试 - 软件维护 ## 软件过程模型 人们通过建立抽象的软件开发模型(也称软件过程模型或软件生命周期模型),把软件生命周期中的各个活动或步骤安排到一个框架中,将软件开发的全过程清晰、直观地表达出来 软件开发模型的内在特征有以下4点: - (1)软件开发模型描述了主要的开发阶段 - (2)软件开发模型定义了每个阶段要完成的主要任务和活动 - (3)软件开发模型规范了每个阶段的输入和输出 - (4)软件开发模型提供了一个框架,把必要的活动映射到这个框架中 ### 瀑布模型 - ![](../../../../assets/default.png) - 优点 - 过程模型简单,执行容易 - 缺点 - 无法适应变更。 - 适用情况 - (1)在软件开发的过程中,需求不发生或很少发生变化,并且开发人员可以一次性获取到全部需求 - (2)软件开发人员具有丰富的经验,对软件应用领域很熟悉。 - (3)软件项目的风险较低。瀑布模型不具有完善的风险控制机制。 - 变体 - v模型 - ![](../../../../assets/default.png) ### 快速原型模型 快速原型的基本思想是快速建立一个能反映用户主要需求的原型系统,让用户在计算机上试用它,通过实践来了解目标系统的概貌。 - ![](../../../../assets/default.png) - 优点 - 不带反馈环 - 适用情况 - (1)已有产品或产品的原型(样品),只需客户化的工程项目。 - (2)简单而熟悉的行业或领域。 - (3)有快速原型开发工具。 - (4)进行产品移植或升级。 ### 增量模型 增量模型是把待开发的软件系统模块化,将每个模块作为一个增量组件,从而分批次地分析、设计、编码和测试这些增量组件 - ![](../../../../assets/default.png) - 优点 - (1)将待开发的软件系统模块化,可以分批次提交软件产品,使用户可以及时了解软件项目的进展。 - (2)以组件为单位进行开发降低了软件开发的风险。一个开发周期内的错误不会影响到整个软件系统。 - (3)开发顺序灵活。开发人员可以对构件的实现顺序进行优先级排序,先完成需求稳定的核心组件。当组件的优先级发生变化时,还能及时调整实现顺序。 - 缺点 - 要求待开发的软件系统可以被模块化。 - 适用情况 - (1)软件产品可以分批次地交付。 - (2)待开发的软件系统能够被模块化。 - (3)软件开发人员对应用领域不熟悉,难以一次性地开发系统。 - (4)项目管理人员把握全局的水平较高。 ### 螺旋模型 螺旋模型是一种用于开发风险较大的大型软件项目的开发模型。该模型将瀑布模型与快速原型模型结合起来,并且加入了这两种模型忽略了的风险分析。 ![](../../../../assets/default.png) - 优点 - 将风险分析扩展到各个阶段中,大幅度降低了软件开发的风险。 - 缺点 - 控制和管理较为复杂 - 可操作性不强 - 对项目管理人员的要求较高。 ### 喷泉模型 在分析阶段,定义类和对象之间的关系,建立对象-关系和对象-行为模型。在设计阶段,从实现的角度对分析阶段模型进行修改或扩展。在编码阶段,使用面向对象的编程语言和方法实现设计模型。在面向对象的方法中,分析模型和设计模型采用相同的符号标示体系,各阶段之间没有明显的界限,而且常常重复、迭代地进行。 ![](../../../../assets/default.png) - 适用情况 - 喷泉模型主要用于面向对象的软件项目 - 软件的某个部分通常被重复多次 - 相关对象在每次迭代中随之加入渐进的软件成分。 ### 基于组件的开发模型 基于组件的开发模型使用现有的组件以及系统框架进行产品开发,由于现有组件大多已经历实际应用的反复检验,因此其可靠性相对新研发组件高出很多。 ![](../../../../assets/default.png) - 优点 - 极大地提高了产品开发效率 - 质量也得到了提高 ### 统一软件开发过程模型 统一软件开发过程(Rational Unified Process,RUP)模型是基于UML(统一建模语言)的一种面向对象软件开发模型。采用迭代和增量递进的开发策略,并以用例驱动为特点,集中了多个软件开发模型的优点。RUP模型是迭代模型的一种。 ![](../../../../assets/default.png) ### 敏捷过程与极限编程 敏捷方法是一种轻量级的软件工程方法,相对于传统的软件工程方法,它更强调软件开发过程中各种变化的必然性,通过团队成员之间充分的交流与沟通以及合理的机制来有效地响应变化。 - 四个价值观 - 个体与交互高于过程和工具 - 可运行软件高于详尽的文档 - 与客户协作高于合同(契约)谈判 - 对变更及时响应高于遵循计划 - 12条原则 - (1)首先要做的是通过尽早和持续交付有价值的软件来让客户满意。 - (2)需求变更可以发生在整个软件的开发过程中,即使在开发后期,我们也欢迎客户对于需求的变更。敏捷过程利用变更为客户创造竞争优势。 - (3)经常交付可工作的软件。交付的时间间隔越短越好,最好2~3周一次。 - (4)在整个的软件开发周期中,业务人员和开发人员应该天天在一起工作。 - (5)围绕受激励的个人构建项目,给他们提供所需的环境和支持,并且信任他们能够完成工作。 - (6)在团队的内部,最有效果和效率的信息传递方法是面对面交谈。 - (7)可工作的软件是进度的首要度量标准。 - (8)敏捷过程提倡可持续的开发速度。责任人、开发人员和用户应该能够保持一种长期稳定的开发速度。 - (9)不断地关注优秀的技能和好的设计会增强敏捷能力。 - (10)尽量使工作简单化。 - (11)好的架构、需求和设计来源于自组织团队。 - (12)每隔一定时间,团队应该反省如何才能有效地工作,并相应调整自己的行为。 - 实践方式 - 极限编程(eXtreme Programming,XP) - 自适应软件开发(Adaptive Software Development,ASD) - 动态系统开发方法(Dynamic System Development Method,DSDM) - ScrumCrystal和特征驱动开发(Feature Driven Development,FDD) - 极限编程 - 极限编程是一种实践性较强的规范化的软件开发方法,它强调用户需求和团队工作。 - 适用情况 - 软件需求模糊且容易改变 - 开发团队少于10人 - 开发地点集中 - ![](../../../../assets/default.png) - ![](../../../../assets/default.png) ### 选择软件开发模型 - (1)符合软件自身的特性,如规模、成本和复杂性等 - (2)满足软件开发进度的要求 - (3)对软件开发的风险进行预防和控制 - (4)具有计算机辅助工具的支持。 - (5)与用户和软件开发人员的知识和技能相匹配 - (6)有利于软件开发的管理和控制

软件工程复习 第四章

# 第四章 结构化分析 ## 需求分析 - 作用 - 为了开发出真正满足用户需要的软件产品,明确了解用户需求是关键。 - 需求分析就是要回答“系统必须做什么” - 在需求中会存在大量的错误,这些错误若未及时发现和更正,就会造成软件开发费用增加、软件质量降低,严重时,会造成软件开发失败 - 需求分析是非常重要的过程,它完成的好坏直接影响后续软件开发的质量。 - 方面 - **确定系统的运行环境要求系统运行时的环境要求包括** - 硬件环境要求,如对计算机的CPU、内存、存储器、输入/输出方式 - 通信接口和外围设备等的要求 - 软件环境要求,如操作系统、数据库管理系统和编程语言等的要求。 - **确定系统的功能性需求和非功能性需求** - 功能需求是软件系统最基本的需求表述,包括对系统应该提供的服务,如何对输入做出反应以及系统在特定条件下的行为描述。 - 非功能性需求包括对系统提出的性能需求、可靠性和可用性需求、系统安全以及系统对开发过程、时间、资源等方面的约束和标准等。 - 进行有效的需求分析 - 原则 - 需求分析是一个过程,它应该贯穿于系统的整个生命周期中,而不是仅仅属于软件生命周期早期的一项工作。 - 需求分析应该是一个迭代的过程。通常情况下,需求是随着项目的深入而不断变化的。 - 为了方便评审和后续的设计,需求的表述应该具体、清晰,并且是可测量的、可实现的。最好能够对需求进行适当的量化 - 两个任务 - 需求分析的建模阶段,即在充分了解需求的基础上,建立起系统的分析模型。 - 需求分析的描述阶段,就是把需求文档化,用软件需求规格说明书的方式把需求表达出来。 - 软件需求规格说明书 - 软件需求规格说明书是需求分析阶段的输出,它全面、清晰地描述了用户需求,因此是开发人员进行后续软件设计的重要依据。软件需求规格说明书应该具有清晰性、无二义性、一致性和准确性等特点。同时,它还需通过严格的需求验证、反复修改的过程才能最终确定。 - 步骤 - **需求获取** - 观察 - 体验 - 问卷调查 - 访谈 - 单据分析 - 报表分析 - 需求调研会 - 分析建模 - 获取需求后,下一步就应该对开发的系统建立分析模型了。模型就是为了理解事物而对事物做出的一种抽象,通常由一组符号和组织这些符号的规则组成。对待开发系统建立各种角度的模型有助于人们更好地理解问题 - 需求描述 - 需求描述就是指编制需求分析阶段的文档。一般情况下,复杂的软件系统在需求阶段会产生3个文档:**系统定义文档(用户需求报告)、系统需求文档(系统需求规格说明书)、软件需求文档(软件需求规格说明书)**。而对简单的软件系统而言,需求阶段只需要输出<mark>软件需求文档</mark>就可以了。 - 需求验证 - 需求分析阶段的工作成果是后续软件开发的重要基础,为了提高软件开发的质量,降低软件开发的成本,必须对需求的正确性进行严格的验证,确保需求的一致性、完整性、现实性、有效性,确保设计与实现过程中的需求可回溯性,并进行需求变更管理 - 需求管理 - 为了更好地进行需求分析并记录需求结果,需要进行需求管理。 - 需求管理是一种用于查找、记录、组织和跟踪系统需求变更的系统化方法。可用于: - (1)获取、组织和记录系统需求。 - (2)使客户和项目团队在系统变更需求上达成并保持一致。 - 有效需求管理的关键在于维护需求的阐述足够明确、每种需求类型适用的属性,以及与其他需求和其他项目工件之间的可追踪性。 - 需求管理实际上是项目管理的一部分,它涉及以下3个主要问题 - (1)识别、分类、组织需求,并为需求建立文档。 - (2)需求变化,即带有建立对需求不可避免的变化是如何提出、如何协商、如何验证以及如何形成文档的过程。 - (3)需求的可跟踪性,即带有维护需求之间以及与系统的其他制品之间依赖关系的过程。 - 需求分析的常用方法 - 功能分解方法 - 功能分解方法是将一个系统看成是由若干功能模块组成的,每个功能又可分解为若干子功能及接口,子功能再继续分解,即功能、子功能和功能接口为功能分解方法的3个要素。功能分解方法采用自顶向下、逐步求精的理念。 - 结构化分析方法 - 结构化分析方法是一种从问题空间到某种表示的映射方法,其逻辑模型由数据流图和数据词典构成并表示。它是一种面向数据流的需求分析方法 - 信息建模方法 - 模型是用某种媒介对相同媒介或其他媒介中的一些事物进行模拟表现的形式。从一个建模角度出发,模型就是要抓住事物最重要的方面而简化或忽略其他方面。简而言之,模型就是对现实的简化。建立模型的过程称为建模。 - 建模可以帮助理解正在开发的系统,这是需要建模的一个基本理由,并且,人对复杂问题的理解能力是有限的。建模可以帮助开发者缩小问题的范围,每次着重研究一个方面,进而对整个系统产生更加深刻的理解。可以明确地说,越大、越复杂的系统,建模就越重要。 - 面向对象的分析方法 - 面向对象的分析方法的关键是识别问题域内的对象,分析它们之间的关系,并建立3类模型。 - 它们分别是 - 描述系统静态结构的对象模型 - 描述系统控制结构的动态模型 - 描述系统计算结构的功能模型 - 其中,对象模型是最基本、最核心、最重要的。面向对象主要考虑类或对象、结构与连接、继承和封装、消息通信,只表示面向对象分析中几项最重要的特征。类的对象是对问题域中事物的完整映射,包括事物的数据特征(即属性)和行为特征(即服务) ## 结构化分析概述 一种考虑数据和处理的需求分析方法被称为结构化分析(Structured Analysis,SA)方法,它是20世纪70年代由Yourdon Constaintine及DeMarco等人提出和发展,并得到广泛应用的。它基于“分解”和“抽象”的基本思想,逐步建立目标系统的逻辑模型,进而描绘出满足用户要求的软件系统。 结构化分析的具体步骤如下。 - 建立当前系统的“具体模型”。 - 抽象出当前系统的逻辑模型。 - 建立目标系统的逻辑模型。 - 为了完整地描述目标系统,还需要考虑人机界面和其他一些问题。 ## 结构化分析方法 ![](../../../../assets/default.png) - 此模型的核心是“数据字典”,它描述软件使用或产生的所有数据对象。 - 围绕这个核心有3种图 - “数据流图”指出当数据在软件系统中移动时怎样变换,以及描绘变换数据流的功能和子功能,用于功能建模 - “实体-关系图”(E-R图)描绘数据对象之间的关系,用于数据建模 - “状态转换图”指明作为外部事件结果的系统行为,用于行为建模。 - 结构化分析方法必须遵守下述准则。 - (1)必须定义软件应完成的功能,这条准则要求建立功能模型。 - (2)必须理解和表示问题的信息域,根据这条准则建立数据模型。 - (3)必须表示作为外部事件结果的软件行为,这条准则要求建立行为模型。 - (4)必须对描述功能、信息和行为的模型进行分解,用层次的方式展示细节。 - (5)分析过程应该从要素信息移向实现细节。 - 不同的模型往往表述系统需求的某一方面,而模型之间又相互关联,相互补充。 ### 功能建模 功能建模的思想就是用抽象模型的概念,按照软件内部数据传递和变换的关系,自顶向下逐层分解,直到找到满足功能要求的可实现的软件为止。<mark>功能模型用数据流图来描述。</mark> 数据流图(简称DFD图)就是采用图形方式来表达系统的逻辑功能、数据在系统内部的逻辑流向和逻辑变换过程,是结构化系统分析方法的主要表达工具及用于表示软件模型的一种图示方法。 - 数据流图 - 4种符号 - (1)外部实体:表示数据的源点或终点,它是系统之外的实体,可以是人、物或者其他系统。 - (2)数据流:表示数据流的流动方向。数据流可以从加工流向加工、从加工流向文件、从文件流向加工。 - (3)数据变换:表示对数据进行加工或处理,比如对数据的算法分析和科学计算。 - (4)数据存储:表示输入或输出文件。这些文件可以是计算机系统中的外部或者内部文件,也可以是表、账单等。 - Yourdon表示法 - (1)矩形表示数据的外部实体。 - (2)圆形泡泡表示变换数据的处理逻辑。 - (3)两条平行线表示数据的存储。 - (4)箭头表示数据流。 - 环境图 - 环境图也称为系统顶层数据流图(或0层数据流图),它仅包括一个数据处理过程,也就是要开发的目标系统。 - 环境图的作用是确定系统在其环境中的位置,通过确定系统的输入和输出与外部实体的关系确定其边界。 - 根据结构化需求分析采用的“自顶向下,由外到内,逐层分解”的思想,开发人员要先画出系统顶层的数据流图,然后再逐层画出低层的数据流图。顶层的数据流图要定义系统范围,并描述系统与外界的数据联系,它是对系统架构的高度概括和抽象。底层的数据流图是对系统某个部分的精细描述。 - 遵守的原则 - (1)第0层的数据流图应将软件描述为一个泡泡。 - (2)主要的输入和输出应该仔细标记。 - (3)通过分离在下一层表示的候选处理过程、数据对象和数据存储,开始求精过程。 - (4)应使用有意义的名称标记所有的箭头和泡泡。 - (5)当从一个层转移到另一个层时要保持信息流的连续性。 - (6)一次精化一个泡泡。 - 数据流图的分层 - 对于稍微复杂一些的实际问题,在数据流图上常常出现十几个甚至几十.个加工,这样的数据流图看起来不直观,不易理解,分层的数据流图能很好地解决这一问题。 - 按照系统的层次结构进行逐步分解,并以分层的数据流图反映这种结构关系,能清楚地表达和容易理解整个系统。 - 原则 - 数据守恒与数据封闭原则 - 所谓数据守恒是指加工的输入输出数据流是否匹配,即每一-个加工既有输入数据流又有输出数据流。或者说一个加工至少有一 个输入数据流,一个输出数据流。 - 分解加工的原则 - 自然性:概念上合理、清晰; - 均匀性:理想的分解是将一个问题分解成大小均匀的几个部分; - 分解度:每个加工每次分解一般不超过7士2个子加工;分解到基本加工为止。 - 子图与父图的“平衡” - 父图中某个加工的输入输出数据流应该同相应的子图的输入输出相同(或相对应),分层数据流图的这种特点称为子图与父图“平衡” - 合理使用文件 - 当文件作为某些加工之间的交界面时,文件必须画出来,一旦文件作为数据流图中的一个独立成份画出来了,那么同其他成份之间的联系也应同时表达出来。 ### 数据建模 - 数据模型中包含3种相互关联的信息 - 数据对象 - 数据对象是对软件必须理解的复合信息的抽象。数据对象可以是外部实体、事物、行为、事件、角色、单位、地点或结构等。总之,可以由一组属性来定义的实体都可以被认为是数据对象 - 数据对象的属性 - 属性定义了数据对象的性质 - 必须把一个或多个属性定义为“标识符”,也就是说,当人们希望找到数据对象的一个实例时,用标识符属性作为“关键字”(通常简称为“键”) - 数据对象彼此间相互连接的关系 - 客观世界中的事物彼此间往往是有联系的 - 数据对象彼此之间相互连接的方式称为联系,也称为关系 - 关系用菱形表示,并用无向边分别与有关实体连接起来,以此描述实体之间的关系 - 关联数量的表示 - ![](../../../../assets/default.png) - 关系本身也可能有属性, - 关系属性的表示 - 在表示关系的无向边上再加一个菱形框,并在菱形框中标明关系的名字,关系的属性同样用椭圆形或圆角矩形表示,并用无向边将关系与其属性连接起来。 ### 行为建模 状态转化图 - 状态转换图是一种描述系统对内部或外部事件响应的行为模型。它描述系统状态和事件,事件引发系统在状态间的转换,而不是描述系统中数据的流动。这种模型尤其适合用来描述实时系统,因为这类系统多是由外部环境的激励而驱动的。 - 优点 - 状态之间的关系能够直观地捕捉到 - 由于状态转换图的单纯性,能够机械地分析许多情况,可以很容易地建立分析工具。 - 状态转换图能够很方便地对应状态转换表等其他描述工具 - 并不是所有的系统都需要画状态转换图,有时系统中的某些数据对象在不同状态下会呈现不同的行为方式,此时应分析数据对象的状态,画出状态转换图,才可正确认识数据对象的行为,并定义其行为。对这些行为规则较复杂的数据对象需要进行如下分析。 - 找出数据对象的所有状态 - 分析在不同的状态下,数据对象的行为规则是否不同,若无不同,则可将其合并成一种状态 - 分析从一种状态可以转换成哪几种状态,是数据对象的什么行为导致这种状态的转换。 - 状态 - 状态是任何可以被观察到的系统行为模式,一个状态代表系统的一种行为模式 - 在状态转换图中定义的状态主要有 - 初态(即初始状态) - 终态(即最终状态) - 中间状态 - **一张状态图中只能有一个初态,而终态可以没有,也可以有多个** - 状态中的活动表的语法格式如下 - 事件名(参数表)/动作 - 表达式其中,“事件名”可以是任何事件的名称。 - 事件 - 事件是在某个特定时刻发生的事情,它是对引起系统做动作或(和)从一个状态转换到另一个状态的外界事件的抽象。 - 状态变迁通常是由事件触发的,在这种情况下,应在表示状态转换的箭头线上标出触发转换的事件表达式。 - 事件表达式的语法如下 - `事件说明[守卫条件]/动作表达式` - 其中,事件说明的语法为:`事件名(参数表)` - 守卫条件是一个布尔表达式。如果同时使用事件说明和守卫条件,则当且仅当事件发生且布尔表达式为真时,状态转换才发生。如果只有守卫条件没有事件说明,则只要守卫条件为真,状态转换就发生。 - 动作表达式是一个过程表达式,当状态转换开始时执行该表达式。 ### 数据字典 - 数据字典是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合。 - 数据字典可以把不同的需求文档和分析模型紧密结合在一-起,如果所有的开发人员在数据字典上取得一致意见, 那么就可以缓和集成性问题。为了避免冗余和不一致性,应该在项目中创建一个独立的数据字典,而并不是在每个需求出现的地方定义每一个数据项。 - 六类条目 - 数据项 - 数据结构 - 数据流 - 数据存储 - 加工逻辑 - 外部实体 ### 加工规格说明 - 过程设计语言 - 过程设计语言(Procedure Design Language,PDL),也称为伪代码,在某些情况下,在加工规格说明中会用到。但一般说来,最好将用PDL来描述加工规格说明的工作推迟到过程设计阶段进行比较好。 - 判定表 - 在某些数据处理中,某个数据处理(即加工)的执行可能需要依赖于多个逻辑条件的取值,此时可用判定表。判定表能够清晰地表示复杂的条件组合与应做的动作之间的对应关系。 - 判定树 - 判定树是判定表的变种,也能清晰地表示复杂的条件组合与应做的动作之间的对应关系。判定树也是用来表述加工规格说明的一种工具。判定树的优点在于,它的形式简单到不需要任何说明,一眼就可以看出其含义,因此易于掌握和使用 ## 结构化分析的图形工具 - 层次方框图 - 层次方框图由树形结构的一系列多层次的矩形组成,用来描述数据的层次结构。 - 方框之间的关系是组成关系,而不是调用关系。 - Warnier图 - 与层次方框图相似,也用树形结构来描绘数据结构,但提供了更详细的描绘手段 - 能指出某一类数据或某一数据元素重复出现的次数,并能指明某一特定数据在某一类数据中是否是有条件地出现。 - IPO图 - IPO图是输入-处理-输出(Input-Process-Output)图的简称。 - 能够方便地描绘输入数据、对数据的处理和输出数据之间的关系。

软件工程复习 第五章

# 第五章 结构化设计 - 目标 - 回答系统应该“怎么做”这个问题。 - 意义 - 软件设计在软件开发过程中处于核心地位,它是保证质量的关键步骤。 - 设计为我们提供了可以用于质量评估的软件表示、 - 设计是我们能够将用户需求准确地转化为软件产品或系统的唯一方法 - 软件设计是所有软件工程活动和随后的软件支持活动的基础。 - 软件设计是一个迭代的过程,通过设计过程,需求被变换为用于构建软件的“蓝图”。 - 良好设计演化的三个特征 - 设计必须实现所有包含在分析模型中的明确需求,而且必须满足用户期望的所有隐含需求。 - 对于程序员、测试人员和维护人员而言,设计必须是可读的、可理解的指南。 - 设计必须提供软件的全貌,从实现的角度说明数据域、功能域和行为域。 - 以上每一个特征实际上都是设计过程应该达到的目标。 - 原则 - 模块化 - 模块是数据说明、可执行语句等程序对象的集合,是构成程序的基本构件,可以被单独命名并通过名字来访问。在面向过程的设计中,过程、函数、子程序、宏都可以作为模块;在面向对象的设计中,对象是模块,对象中的方法也是模块。 - 模块化就是把系统或程序划分为独立命名并且可以独立访问的模块,每个模块完成一个特定的子功能。模块集成起来可以构成-一个整体,完成特定的功能,进而满足用户需求。 - 模块的公共属性: - 接口:指模块的输入、输出。 - 功能:指模块的逻辑功能。 - 状态:指模块的运行环境,即模块的调用和被调用关系 - 逻辑:描述内部如何实现要求的功能及所需的数据。 ### 内聚的分类 内聚的种类由紧到松(越紧越好)依次为: 1. **功能内聚**:指模块内的所有元素共同作用完成一个功能,缺一不可。 2. **顺序内聚**:指一个模块中的各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素的输出就是下一个功能元素的输入。 3. **通信内聚**:指模块内所有处理元素都在同一个数据结构上。 4. **过程内聚**:指一个模块完成多个任务,这些任务必须按指定的过程执行。 5. **瞬时内聚**:把需要同时执行的任务或动作组合在一起(如初始化模块)。 6. **逻辑内聚**:模块完成逻辑上相关的一组任务。 7. **偶然内聚**:指一个模块内的各处理元素之间没有任何联系或有松散的联系。 ### 耦合的分类 耦合的种类从高到低(越低越好)依次为: 1. **内容耦合**:一个模块直接使用另一个模块的内部数据,或通过非正常入口转入另一个模块内部时,这种耦合关系就是内容耦合。 2. **公共耦合**:指一组模块访问一个公共数据环境,如全局数据结构。 3. **外部耦合**:指一组模块访问一个公共变量,这里指基本数据类型而不是数据结构(或者说对象)。 4. **控制耦合**:指一个模块调用另一个模块时,传递的是控制变量,被调用模块通过该控制变量的值选择执行模块内某一功能。那么也就是说,被调用的模块应具有多个功能。 5. **标记耦合**:耦合模块之间以数据结构传递(比如在 java 程序中,传递的就是一个对象)。 6. **数据耦合**:耦合模块之间有调用关系,传递的是简单数据类型的值(比如在 java 程序中,传递的就是一个基本数据类型的值)。 7. **无直接耦合**:指两个模块之间没有直接的关系,它们分别从属于不同模块的控制与调用,它们之间不传递任何信息。

软件工程复习 第六章

# 面向对象方法与UML ## 面向对象的软件工程方法 - 基本观点 - 客观世界是由对象组成的,任何客观的事物或实体都是对象,复杂的对象可以由简单的对象组成。 - 具有相同数据和相同操作的对象可以归并为一个类,对象是对象类的一个实例。 - 类可以派生出子类,子类继承父类的全部特性(数据和操作) ,又可以有自己的新特性。子类父类形成类的层次结构。 - 对象之间通过消息传递相互联系。类具有封装性,其数据和操作等对外界是不可见的,外界只能通过消息请求进行某些操作,提供所需要的服务。 - 基本概念 - 面向对象:按人们认识客观世界的系统思维方式,采用基于对象的概念建立模型,模拟客观世界分析、设计、实现软件的办法。通过面向对象的理念使计算机软件系统能与现实世界中的系统一一对应。 - 对象:即指现实世界中各种各样的实体。它可以指具体的事物,也可以指抽象的事物。在面向对象概念中我们把对象的内部状态称为属性,把运动规律称为方法或事件。 - 类:类是具有相似内部状态和运动规律的实体的集合。对于一个具体的类,它有许多具体的个体,我们就管这些个体叫作“对象”。类的内部状态是指类集合中对象的共同状态;类的运动规律是指类集合中对象的共同运动规律。 - 消息:消息是指对象间相互联系和相互作用的方式。一个消息主要由5部分组成:发送消息的对象、接收消息的对象、消息传递办法、消息内容、反馈。 - 包:现实世界中不同对象间的相互联系和相互作用构成了各种不同的系统,不同系统间的相互联系和相互作用构成了更庞大的系统,进而构成了整个世界。在面向对象概念中把这些系统称为包 - 接口:在系统间相互作用时为了蕴藏系统内部的具体实现,系统通过设立接口界面类或对象来与其他系统进行交互;让其他系统只看到这个接口界面类或对象,这个类在面向对象中称为接口类。 - 类的特性 - 抽象:类的定义中明确指出类是一组具有内部状态和运动规律对象的抽象,抽象是一种从一般的观点看待事物的方法,它要求我们集中于事物的本质特征,而非具体细节或具体实现。 - ②继承:继承是类不同抽象级别之间的关系。在计算机软件开发中采用继承性,提供了类的规范的等级结构;通过类的继承关系,使公共的特性能够共享,提高了软件的重用性 - ③封装:对象间的相互联系和相互作用过程主要通过消息机制得以实现。对象之间并不需要过多地了解对方内部的具体状态或运动规律。面向对象的类是封装良好的模块,类定义将其说明与实现显式地分开,其内部实现按其具体定义的作用域提供保护。类是封装的最基本单位。封装防止了程序相互依赖而带来的变动影响。在类中定义的接收对方消息的方法称为类的接口。 - 多态:多态是指同名的方法可在不同的类中具有不同的运动规律。在父类演绎为子类时,类的运动规律也同样可以演绎,演绎使子类的同名运动规律或运动形式更具体,甚至子类可以有不同于父类的运动规律或运动形式。不同的子类可以演绎出不同的运动规律 - 重载:重载指类的同名方法在给其传递不同的参数时可以有不同的运动规律。在对象间相互作用时,即使接收消息对象采用相同的接收办法,但消息内容的详细程度不同,接收消息对象内部的运动规律也可能不同。 - 特征 - 把数据和操作封装在一起,形成对象。对象是构成软件系统的基本构件 - 把特征相似的对象抽象为类 - 类之间可以存在继承或被继承的关系,形成软件系统的层次结构 - 对象之间通过发送消息进行通信 - 将对象的私有信息封装起来。外界不能直接访问对象的内部信息,而必须是发送相应的消息后,通过有限的接口来访问。 - 优势 - 符合人类的思维习惯 - 稳定性好 - 可复用性好 - 可维护性好 - 实施步骤 - 面向对象分析:从问题陈述入手,分析和构造所关心的现实世界问题域的模型,并用相应的符号系统表示。 - 确定问题域,包括定义论域、选择论域、根据需要细化和增加论域 - 区分类和对象,包括定义对象、定义类、命名 - 区分整体对象以及组成部分,确定类的关系以及结构 - 定义属性,包括确定属性、安排属性 - 定义服务,包括确定对象状态、确定所需服务、确定消息联结 - 确定附加的系统约束 - 面向对象设计 - 应用面向对象分析,改善和完善用其他方法得到的系统分析结果 - 设计交互过程和用户接口 - 设计任务管理,根据前一步骤确定是否需要多重任务,确定并发性,确定以何种方式驱动任务,设计子系统以及任务之间的协调与通信方式,确定优先级 - 设计全局资源,确定边界条件,确定任务或子系统的软、硬件分配 - 面向对象实现:使用面向对象语言实现面向对象的设计相对比较容易。用非面向对象语言实现面向对象的设计时,特别需要注意和保留程序的面向对象结构 - 面向对象测试:对面向对象实现的程序进行测试,包括模型测试、类测试、交互测试、系统(子系统)测试、验收测试等 ## 统一建模语言(Unify Modeling Language) 统一建模语言(Unified Modeling Language,UML)是一种通用的可视化建模语言,可以用来描述、可视化、构造和文档化软件密集型系统的各种工件。它是由信息系统和面向对象领域的3位著名的方法学家GradyBooch、James Rumbaugh和Ivar Jacobson提出的。它记录了与被构建系统有关的决策和理解,可用于对系统的理解、设计、浏览、配置、维护以及控制系统的信息。这种建模语言已经得到了广泛的支持和应用,并且已被ISO组织发布为国际标准。 - UML是一种标准的图形化建模语言,它是面向对象分析与设计的一种标准表示 - 它不是一种可视化的程序设计语言,而是一种可视化的建模语言 - 它不是工具或知识库的规格说明,而是一种建模语言规格说明,是一种表示的标准 - 它不是过程,也不是方法,但允许任何一种过程和方法使用它。 - 特点 - 统一标准 - 面向对象 - 可视化,表达能力强大 - 独立于过程 - 容易掌握使用 - 与编程语言的关系 - 应用范围 - UML以面向对象的方式来描述系统。UML最广泛的应用是对软件系统进行建模,但它同样适用于许多非软件系统领域的系统。从理论上来说,任何具有静态结构和动态行为的系统都可以使用UML建模。当UML应用于大多数软件系统的开发过程时,它从需求分析阶段到系统完成后的测试阶段都能起到重要作用。 - 组成 - UIL符号为开发者或开发工具使用这些图形符号和文本语法为系统建模提供了标准 - 这些图形符号和文字所表达的是应用级的模型,在语义上它是U0元模型的实例 - UIL模型由事物、关系和图组成 - [UML概述_w3cschool](https://www.w3cschool.cn/uml_tutorial/uml_tutorial-c1gf28pd.html) ## 静态建模机制 任何建模语言都以静态建模机制为基础,UML也不例外。<mark>UML的静态建模机制包括用例图、类图、对象图、包图等。</mark> ### 用例图 用例图是从用户的角度描述系统的功能,由用例(Use Case)、参与者(Actor)以及它们的关系连线组成。 用例的特征用例是从用户角度描述系统的行为,它将系统的一个功能描述成一系列的事件,这些事件最终对操作者产生有价值的观测结果。参与者(也称为操作者或执行者)是与系统交互的外部实体,可能是使用者,也可能是与系统交互的外部系统、基础设备等。用例是一个类,它代表一类功能而不是使用该功能的某一具体实例。 - 包含关系 - 如果系统用例较多,不同的用例之间存在共同行为,可以将这些共同行为提取出来,单独组成一个用例。当其他用例使用这个用例时,它们就构成了包含关系。 - 扩展关系 - 在用例的执行过程中,可能出现一些异常行为,也可能会在不同的分支行为中选择执行,这时可将异常行为与可选分支抽象成一个单独的扩展用例,这样扩展用例与主用例之间就构成了扩展关系。一个用例常常有多个扩展用例。 - 泛化关系 - 用例之间的泛化关系描述用例的一般与特殊关系,不同的子用例代表了父用例的不同实现。 ### 类图和对象图 类图使用类和对象描述系统的结构,展示了系统中类的静态结构,即类与类之间的相互关系。类之间有多种联系方式,如关联(相互连接)、依赖(一个类依赖于或使用另一个类)、泛化(一个类是另一个类的特殊情况)。一个系统有多幅类图,一个类也可以出现在几幅类图中。 对象图是类图的实例,它展示了系统在某一时刻的快照。对象图使用与类图相同的符号,只是在对象名下面加上下画线。 ### 包图 包是一种对元素进行分组的机制。如果系统非常复杂,常常包含大量的模型,为了便于理解以及将模型独立出来用于复用,对这些元素进行分组组织,从而作为一个个集合进行整体命名和处理。 ## 动态建模机制 系统中的对象在执行期间的不同时间点如何通信以及通信的结果如何,就是系统的动态行为,也就是说,对象通过通信相互协作的方式以及系统中的对象在系统生命期中改变状态的方式,是系统的动态行为。<mark>UML的动态建模机制包括顺序图、协作图、状态图和活动图。</mark> ### 顺序图 顺序图描述了一组对象的交互方式,它表示完成某项行为的对象和这些对象之间传递消息的时间顺序。顺序图由对象(参与者的实例也是对象)、生命线、控制焦点、消息等组成。生命线是一条垂直的虚线,表示对象的存在时间;控制焦点是一个细长的矩形,表示对象执行一个操作经历的时间段;消息是作用于控制焦点上的一条水平带箭头的实现,表示消息的传递。 - 绘制顺序图的步骤如下 - 列出启动该用例的参与者 - 列出启动用例时参与者使用的边界对象 - 列出管理该用例的控制对象 - 根据用例描述的所有流程,按时间顺序列出分析对象之间进行消息传递的序列 - 绘制顺序图需要注意以下问题。 - 如果用例的事件流包含基本流和若干备选流,则应当对基本流和备选流分别绘制顺序图 - 如果备选流比较简单,可以合并到基本流中 - 如果事件流比较复杂,可以在时间方向上将其分成多个顺序图 - 实体对象一般不会访问边界对象和控制对象。 ### 协作图 协作图显示多个对象及它们之间的关系,对象间的箭头显示消息的流向。消息上也可以附带标签,表示消息的其他信息,如发送顺序、显示条件、迭代和返回值等。开发人员熟识消息标签的语法之后,就可以读懂对象之间的通信,并跟踪标准执行流程和消息交换顺序。但是,如果不知道消息的发送顺序,就不能使用协作图来表示对象关系。图6-21为某个系统的“登录”交互过程的简要协作图。 ### 状态图 状态图由状态机扩展而来,用来描述对象对外部对象响应的历史状态序列,即描述对象所有可能的状态,以及哪些事件将导致状态改变。状态图包括对象在各个不同状态间的跳转以及这些跳转的外部触发事件,即从状态到状态的控制流。状态图侧重于描述某个对象的动态行为,是对象的生命周期模型。并不是所有的类都需要画状态图,只有明确意义的状态、在不同状态下行为有所不同的类,才需要画状态图。状态图在4.3.3节中已经介绍,这里不再赘述。 ### 活动图 活动图是展示整个计算步骤的控制流(及其操作数)的节点和流的图。执行的步骤可以是并发的或顺序的。 ## 描述物理架构的机制 系统架构分为逻辑架构和物理架构两大类。逻辑架构完整地描述系统的功能,把功能分配到系统的各个部分,详细说明它们是如何工作的。物理架构详细描述系统的软件和硬件,描述软件和硬件的分解。在UML中,用于描述逻辑架构的图有:用例图、类图、对象图、状态图、活动图、协作图和顺序图;<mark>用于描述物理架构的图有:构件图、部署图。</mark> ### 构件图 构件图根据系统的代码构件显示系统代码的物理结构。 ### 部署图

软件工程复习 第八章

# 第八章 软件体系结构 体系结构是研究系统各部分组成及相互关系的技术学科。它包括以下几个部分: - 软件的组成元素(组件) - 这些(组件)元素的外部可见特性 - 这些元素(组件)之间的相互关系。 ## 体系结构模式 ### 分层模式 将软件系统按照抽象级别逐层递增或递减的顺序划分为若干层次,每层由一-些抽象级别相同的构件组成。 每层的构件仅为其上的层次提供服务,并且它们仅使用其下层提供的服务。 一般而言, 顶层直接面向用户提供软件系统的交互界面,底层则负责提供基础性、公共性的技术服务,比较接近于硬件计算环境、操作系统或数据库管理系统。 - 层次之间的连接有两种形态: - 高层构件向低层构件发出服务请求,低层构件在计算完成后向请求者发送服务应答。 - 低层构件主动探测或被动获知计算环境的变化事件后通知高层构件。 - 优势 - 松耦合。通过软件层次的划分和层间接口的规整,有效降低耦合度,系统各构件之间依赖关系的局部化。 - 可替换性。一个层次可被替换。 - 可复用性。具有良好定义的抽象级别和对外服务接口。 - 劣势 - 高层功能需要逐层调用下层服务,返回值、报错信息又需逐层上传,耗时 - 若低层服务还完成了最初的服务请求者不需要的冗余功能,性能损耗更严重。 ### 管道过滤器模式 将软件系统的功能实现为一-系列的处理步骤,每个步骤封装在一个过滤器构件中,相邻过滤器之间由管道连接。一个过滤器的输入数据借助管道流向后续过滤器,作为其输入数据。 输入由数据源提供,它通过管道与过滤器相连。最终输出由源自某个过滤器的管道流向数据汇。数据源和汇通常为数据库、文件、其他软件系统和物理设备。 采用管道过滤器模式,可以通过升级、更换部分过滤器构件以及处理步骤的充足来实现软件系统的扩展和进化。此模式适合于采用批处理方式的软件系统,不适合与交互式、事件驱动的系统 ### 黑板模式 - 将软件系统划分为黑板、知识源和控制器3类构件 - 黑板负责保存问题求解过程中的状态数据,并提供这些数据的读写服务 - 知识源负责根据黑板中存储的问题求解状态评价其自身的可应用性,进行部分问题求解工作,并将此工作的结果数据写入黑板 - 控制器负责监视黑板中不断更新的状态数据,安排知识源的活动 - 适合于没有确定的求解方法的复杂问题 - 优势: - 知识源和控制器可灵活更换、升级。 - 知识源之间没有交互,知识源与控制器和黑板之间均通过接口交互,知识源可复用性好。 - 知识源的求解动作是探索性的,允许失败和试错。 - 劣势 - 问题求解性能较低,有时甚至无法预测求解时间。 - 不能确保得到最优解。 - 问题求解路径不确定,造成软件测试较为困难。 - 知识源和控制器两种构件的开发相当困难。 ### 分布式体系结构 - 优势 - 资源共享。分布式系统允许硬件、软件等资源共享使用 - 经济性。 - 性能与可扩展性。 - 固有分布性。 - 健壮性。 - 多处理机体系结构 - 分布式系统的一个最简单的模型是多处理器系统,系统由许多进程组成,这些进程可以在不同的处理器上并行运行,可以极大地提高系统的性能。 - 由于大型实时系统对响应时间要求较高,这种模型在大型实时系统中比较常见。大型实时系统需要实时采集信息,并利用采集到的信息进行决策,然后发送信号给执行机构。虽然,信息采集、决策制定和执行控制这些进程可以在同一台处理器上统一 调度执行,但使用多处理器能够提高系统性能。 - 客户/服务器模式 - 客户机/服务器( client/server , C/S )体系结构是基于资源不对等且为实现共享而提出来的,由服务器、客户机和网络三部分组成。 - 在C/S体系结构中,客户机可以通过远程调用来获取服务器提供的服务,因此,客户机必须知道可用的服务器的名字及它们所提供的服务,而服务器不需要知道客户机的身份,也不需要知道有多少台服务器在运行。 - 瘦客户机模型 - 在瘦客户机模型中,数据管理部分和应用逻辑都在服务器上执行,客户机只负责表示部分。 - 瘦客户机模型的主要缺点: - 它将繁重的处理负荷都放在了服务器和网络上,服务器负责所有的计算,这将增加客户机和服务器之间的网络流量。 - 目前个人计算机所具有的处理能力在瘦客户机模型中用不上。 - 胖客户机模型 - 在这种模型中,服务器只负责对数据的管理。客户机_上的软件实现应用逻辑和与系统用户的交互。 - 胖客户机模型能够利用客户机的处理能力,比瘦客户机模型在分布处理上更有效。 - 缺点: - 开发成本较高 - 用户界面风格不一,使用繁杂,不利于推广使用 - 软件移植困难 - 软件维护和升级困难 - 三层C/S体系 - 为了解决以上问题,三层C/S体系结构应运而生。三层C/S体系结构中增加了应用服务器。可以将整个应用逻辑驻留在应用服务器上,而只有表示层存在于客户机上。 - B/S体系 - 浏览器/服务器( browser/server , B/S )风格是三层体系结构的一种实现方式,其具体结构为浏览器/Web服务器/数据库服务器。B/S体系结构如下图所示。 - B/S体系结构主要是利用不断成熟的WWW浏览器技术,结合浏览器的多种脚本语言,用通用浏览器就实现了原来需要复杂的专用软件才能实现的强大功能,并节约了开发成本。从某种程度上来说, B/S结构是一种全新的软件体系结构。 - B/S体系结构具有以下优点: - 基于B/S体系结构的软件,系统安装、修改和维护全在服务器端解决。 - B/S体系结构还提供了异种机、异种网、异种应用服务的联机、联网和统一服务的最现实的开放性基础。 -

软考复习之设计模式

# 设计模式 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 ## 设计模式的六大原则 **1、开闭原则(Open Close Principle)** 开闭原则的意思是:**对扩展开放,对修改关闭**。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 **2、里氏代换原则(Liskov Substitution Principle)** 里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。 **3、依赖倒转原则(Dependence Inversion Principle)** 这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。 **4、接口隔离原则(Interface Segregation Principle)** 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。 **5、迪米特法则,又称最少知道原则(Demeter Principle)** 最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。 **6、合成复用原则(Composite Reuse Principle)** 合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。 ## 分类 共有23种设计模式分为3大类 - 创建型模式 - 工厂模式(Factory Pattern) - 抽象工厂模式(Abstract Factory Pattern) - 单例模式(Singleton Pattern) - 建造者模式(Builder Pattern) - 原型模式(Prototype Pattern) - 结构型模式 - 适配器模式(Adapter Pattern) - 桥接模式(Bridge Pattern) - 过滤器模式(Filter、Criteria Pattern) - 组合模式(Composite Pattern) - 装饰器模式(Decorator Pattern) - 外观模式(Facade Pattern) - 享元模式(Flyweight Pattern) - 代理模式(Proxy Pattern) - 行为型模式 - 责任链模式(Chain of Responsibility Pattern) - 命令模式(Command Pattern) - 解释器模式(Interpreter Pattern) - 迭代器模式(Iterator Pattern) - 中介者模式(Mediator Pattern) - 备忘录模式(Memento Pattern) - 观察者模式(Observer Pattern) - 状态模式(State Pattern) - 空对象模式(Null Object Pattern) - 策略模式(Strategy Pattern) - 模板模式(Template Pattern) - 访问者模式(Visitor Pattern) ![](cp/img1.jpg) ## 详细信息 [设计模式 | 菜鸟教程 (runoob.com)](https://www.runoob.com/design-pattern/design-pattern-tutorial.html)

软考复习之软件需求

# 软件需求 软件需求是 (1)用户解决问题或达到目标所需条件或权能(Capability)。 (2)系统或系统部件要满足合同、标准、规范或其它正式规定文档所需具有的条件或权能。 (3)一种反映上面(1)或(2)所述条件或权能的文档说明。 它包括功能性需求及非功能性需求,非功能性需求对设计和实现提出了限制,比如性能要求,质量标准,或者设计限制。 ## 类型 - 业务需求(Business Requirments):组织或者客户高层次的目标,从宏观上描述开发系统的必要性、意义和目标,具有以业务为想到、可度量、合理、可行的特点。BR的核心部分是业务建模,对当前企业当前业务流程进行评估,并对新开发系统的业务处理流程进行展望。 - 用户需求(User Requirements):用户要求系统必须要完成的任务,即用户要系统做什么,产生什么业务价值。 - 系统需求(System Requirments):整个系统的顶级需求,由系统分析人员对UR进行分析、提炼、整理,从而生成指导开发的、更准确地软件需求。完整的表达了软件项目的预期特征,为接下来的软件设计和测试提供了依据和基础。 - 功能需求(Functional Requirements):规定开发人员必须在产品中要实现的软件功能 ### 非功能性需求 - 产品必须遵从的规范、标准和合约 - 外部界面的具体细节 - 性能需求 - 设计或实现的约束条件及质量属性 ## 过程标准 清楚(Clear)、完整(Complete)、一致(Consistent)、可测试(Testable)。 此外还有其他的概念,如可跟踪的、可修改的等等