软件工程知识点整理
软件工程(Software Engineering)
玛格丽特·汉密尔顿是「软件工程」一词的创造者。软件工程是为了经济地获得可靠的、能在实际机器上高效运行的软件而建立和使用的良好工程原则。软件工程的三要素为方法、工具和过程。
软件工程是一门综合性交叉学科,涉及数学、计算机科学、管理科学和工程科学等,着重于建造软件系统,首要目标是生产高质量的软件产品;而计算机科学着重于原理和理论。
软件的定义见计算机科学常识整理的软件一节。软件开发历经如下时代和软件生产方式:个体手工的程序设计时代;作坊式小团体的程序系统时代;工程化的软件工程时代。
软件文档(Software Documentation)包括软件需求文档、设计文档、测试文档和用户手册等。
软件文档在软件工程中的作用如下:提高软件开发过程的能见度;提高软件开发效率;作为开发人员阶段工作成果和结束标志;记录开发过程的有关信息便于使用和维护;提供软件运行、维护和培训的相关资料;便于用户了解软件功能、性能。
软件危机(Software Crisis)指开发软件所需高成本和产品的低质量之间的尖锐矛盾,是计算机软件开发、使用与维护过程中遇到的一系列严重问题和难题,要点如下:不能符合用户的实际需求;开发的效率低;产品的质量差;开发成本和进度难以估算;可维护性差;开发文档资料不完整;价格昂贵。
软件开发管理困难复杂、开发技术和开发工具落后等是软件危机产生的原因。
人月(Man-Month)
软件开发需要软件工具、硬件工具和人,其中人是最基本的资源。人月指一个人在一个月内所能完成的工作量。
人月是危险和带有欺骗性的神话,因为它暗示人员数量和时间是可以相互替换的。人力和时间并不呈现线性关系,增加软件项目的人手所付出的代价有三个方面:任务重新分配造成的混乱和额外工作量、新人员的培训、额外的相互沟通。
向进度落后的项目追加人手,只会让进度更落后,这称为布鲁克斯法则(Brooks' Law)。
概念完整性(Conceptual Integrity)
概念完整性指对于一个领域,了解该领域的所有对象及它们的关系,即人的认识的完整性。概念完整性是系统设计中最重要的考虑因素。为了获得概念完整性,设计必须由一个人或者具有共识的小型团队来完成。如果系统必须保有概念上的整体性,那么就必须有人来控制这些概念,为此需要专制。
体系结构、设计实现、物理实现的许多工作可以并发进行,软件和硬件设计同样可以并行。
第二系统效应(The Second-system Effect)指就一个人所做过的设计而言,第二个系统往往存在过度设计的倾向。
计算机辅助软件工程(CASE; Computer Aided Software Engineering)
使用计算机及相关软件工具辅助软件开发、维护、管理等过程中各项活动的实施,以确保这些活动能高效率、高质量地进行。CASE已被证明能加快开发速度,提高生产率和企业利润,进而增强企业竞争力。
软件开发环境的集成机制有如下几种。
- 数据集成:统一的数据模式和数据接口规范;
- 界面集成:统一的界面风格;
- 控制集成:支持环境中各个工具或开发活动间的通信、切换、调度和协同工作;
- 过程集成:将多种开发方法、过程模型及其相关工具集成;
- 平台集成:在不同的硬件和系统软件之上构件用户界面一致的平台。
软件生存周期(SLC; Software Life Cycle)
即软件开发的路线图,又称软件过程(Software Process)。软件生存周期的划分如下。
软件规模、种类、开发方式和环境等都影响软件生存周期的划分,在划分软件周期时应当遵循的基本原则是从时间角度对软件的开发和维护这一复杂问题进行分解,各阶段的任务应尽可能相对独立,同一阶段任务的性质尽可能相同,从而降低开发复杂度。
随生存周期的推移,软件缺陷修复所需的费用越来越高。
能力成熟度模型(CMM; Capability Maturity Model)
CMM用于评价软件机构的软件过程能力成熟度。关键过程域(KPA; Key Process Area)指达到CMM等级所必须满足的项目。CMM成熟度框架等级及每个等级对应的KPA如下。
- 初始级(Initial):过程往往是混乱的,成功源于英雄主义;
- 可重复级(Repeatable):建立基本项目管理以跟踪成本、进度和功能,制定必要的过程纪律;
- 需求管理;
- 软件项目计划、跟踪和监督
- 软件分包合同管理;
- 软件质量保证和配置管理。
- 已定义级(Defined):将管理和工程活动文档化、标准化;
- 组织级过程焦点、定义;
- 集成软件管理;
- 软件产品工程;
- 组件协调;
- 同行评审;
- 培训大纲。
- 已管理级(Managed):对软件过程有定量的理解和控制,过程可预测;
- 定量过程管理;
- 软件质量管理。
- 优化级(Optimizing):过程的量化反馈和先进的新思想、新技术使过程持续改进。
- 缺陷预防;
- 技术更新管理;
- 过程更改管理。
软件过程模型(Software Process Model)
软件过程模型是将软件生存周期进行合理的整合后形成的开发方式。
瀑布模型(Waterfall Model)
瀑布模型将软件开发各阶段线性顺序联接,接受上一阶段的结果作为本阶段的输入,利用这一输入实施本阶段应完成的活动,生成相应文档,对本阶段的工作进行评审后将本阶段的结果输出,传递给下一阶段。
若错误由前一阶段引起,常常需要回到前一阶段,称为瀑布的倒流。
瀑布模型不灵活,要求需求在最初始阶段就要完整而明确,一般适用于功能、性能明确完整,无重大变化的软件系统的开发,如操作系统、编译系统、数据库管理系统等,应用有一定的局限性。
演化模型(Evolutionary Model)
原型(Prototype)是软件的一个早期可运行的版本,反映最终系统的重要特征。演化模型从构造初始原型出发,逐步演化为最终软件产品。
适用于对软件需求缺乏准确认识的情况,或项目组成员不能很好地交流或通信的情况,典型的演化模型如下。
- 增量模型:融合了瀑布模型的基本成分(即重复的利用)和演化模型的迭代特征;强调每一个增量都发布一个可运行的产品;能有计划地管理技术风险(如早期增量版本中避免采用尚未成熟的技术);
- 原型模型:快速构建原型,交付客户试用,收集反馈意见并改进原型;
- 螺旋模型:在瀑布模型和增量模型的基础上增加了风险分析活动,指引软件项目开发沿着螺线自内向外旋转,每旋转一圈,表示开发出一个更为完善的新软件版本。
喷泉模型(Fountain Model)
喷泉模型是支持面向对象开发的过程模型,此外的一般是面向过程的模型。开发活动迭代重复进行,开发活动间无间隙,不存在明显边界。
系统工程(System Engineering)
考虑完整的软硬件解决方案,而非单一软件。系统工程追求最优化,其任务如下。
- 识别用户的要求:简化的、压缩的需求分析;
- 可行性分析(Feasibility Analysis):用最小的代价确定该软件项目是否能够开发,是否值得去开发;
- 经济可行性:进行开发成本的估算以及了解取得效益的评估;
- 技术可行性:通常包括风险分析、资源分析和技术分析;
- 法律(社会)可行性:分析开发的项目是否存在任何侵犯、妨碍等责任问题,要开发项目目的运行方式在用户组织内是否可行,现有管理制度、人员素质、操作方式是否可行。
- 系统建模和模拟:建立硬软件系统模型、人机接口模型和数据模型等,建模是软件开发中实现映射的基本手段,系统物理模型通常可使用系统流程图描述;
- 成本估算和进度安排;
- 生成系统规格说明。
需求工程(RE; Requirement Engineering)
开发人员准确地理解用户的需求,进行细致的调查分析,将用户非形式的需求陈述转化成完整的需求定义,最终再转化至相应的需求规格说明书,即回答「系统必须做什么」,是软件工程中的关键阶段。需求工程可细分为如下阶段。
- 需求获取:与用户交流,对现有系统进行观察及对任务进行分析,捕获和修订用户的需求;
- 需求分析:分析需求间关系以检验需求的一致性、重叠和遗漏的情况;
- 系统建模:建立概念模型以对需求进行抽象描述,尽可能多地捕获现实世界的语义;
- 需求规约:需求分析的输出,即软件产品的概念模型,并对此制定合适的验收标准;
- 需求验证:检验系统是否能反应用户意愿;
- 需求管理:支持系统的需求演进,如需求变化和可跟踪问题。
需求的发现方式如下。
- 自悟:作为用户,提出问题,适用于当开发者无法与用户进行直接交流时;
- 交流:询问用户想要的功能,需要控制用户提出合理需求;
- 观察:观察用户执行现行的任务和过程或观察如何操作与期望系统有关的现有系统,了解运行环境,但用户可能抵触这一观察,且会让用户误以为开发者已经熟悉了业务;
- 小组会:举行客户和开发人员的联席会议,与客户代表共同开发需求;
- 提炼:可复用的技术文档,提取出未来可能会用到的信息,适用于已有部分需求文档的烂尾项目。
除功能需求外,还可能有如下几类非功能需求。
- 性能需求:并发访问数等;
- 质量属性:对非法操作的容错等;
- 对外接口:支持第三方插件等;
- 设计约束:运行平台等,与其他非功能需求不同,设计约束是必须予以满足的,且对项目规划、所需的附加成本和工作产生直接影响。
非功能需求必须依附于功能需求而存在。
设计工程(Design Engineering)
定义软件的实现细节以满足用户需求,即研究如何实现软件。设计工程的任务如下:数据/类设计;体系结构设计;接口设计;部件级设计。
软件的设计原则如下:抽象;逐步求精;模块化;信息隐藏;功能独立。
模块化设计(Modular Design)是软件设计原则之一,即把软件划分为较小的、相互独立的但又互相关联的部件,这一部件称之为模块(Module)。划分模块时,模块的作用范围(Scope of Effect)应在其控制范围(Scope of Control)之内。功能独立性全面指导模块的划分。
模块的功能独立性可以由两个指标衡量,即内聚度与耦合度。
内聚(Cohesion)度是模块内部各元素彼此结合紧密程度的度量。模块的内聚性由低至高可分为如下七种类型。
- 偶然内聚:又称巧合内聚,仅相同程序代码独立出来而建立的模块;
- 逻辑内聚:完成一组逻辑相关任务;
- 时间内聚:模块中的多个任务必须在一段时间内先后执行,而无明确的过程约束;
- 过程内聚:模块中的多个任务必须按指定过程执行;
- 通信内聚:模块中所有处理元素都集中在某个数据结构的一块区域中;
- 顺序内聚:完成必须顺序执行的多个功能;
- 功能内聚:模块中各部分都是为完成一项具体功能而协同工作,不可分割(模块完成单个功能)。
耦合(Coupling)度是模块间相对独立性的度量。模块间的耦合性由高至低可分为如下七种类型。
- 内容耦合:可以直接访问另一模块的内部数据或内部功能;
- 公共耦合:可与其他模块共同访问某些公共数据元素;
- 外部耦合:与其他模块遵循同样的外部约束(如通信协议、数据格式等);
- 控制耦合:与其他模块的交互参数包含控制信息,即能影响另一模块的执行逻辑;
- 标记耦合:模块间传递特定数据结构;
- 数据耦合:模块间仅传递简单数据;
- 非直接耦合:模块可相对独立工作。
良好的设计策略要求降低耦合度,提高内聚度。
概要设计(Overall Design)
又称总体设计,将需求分析得到的系统扩展用例图转换为软件结构和数据结构。
概要设计是详细设计的基础。
概要设计阶段的基本任务如下:设计软件系统结构;数据结构及数据库设计;编写概要设计文档;评审。
详细设计(Detailed Design)
设计每个模块实现算法,所需的内部结构等。
详细设计阶段的基本任务如下:为模块进行详细的算法设计;为模块内的数据结构进行设计;对数据库进行物理设计;代码设计、输入输出格式设计、人机交互设计等;编写详细设计文档;评审。
详细设计的描述方法见结构化程序设计。
人机交互界面(HCI; Human-Computer Interface)
在「软件工程」中,人机交互界面狭义地指软件的人性化操作界面。
人机交互界面应该具备如下特性。
- 可使用性:最关键的特性;
- 灵活性:用户可根据需要定制和修改界面;
- 可靠性:无故障使用;
- 可扩展性。
设计人机交互界面需要考虑如下因素:系统响应时间;用户求助机制;错误信息处理;命令交互方式。
人机交互界面设计的三条「黄金原则」总结如下:让用户拥有控制权;减少用户的记忆负担;保持界面一致。
容错(Fault Tolerance)
系统在部分组件发生故障时仍能正常运作的能力,容错的四种手段如下。
- 结构冗余:包括静态冗余、动态冗余和混合冗余;
- 信息冗余:为检测或纠正信息在运算或传输中的错误所外加的信息;
- 时间冗余:重复执行指令或程序来消除瞬时错误的影响;
- 冗余附加技术:实现上述冗余技术所需的资源和技术。
编码(Coding)
良好的编码原则如下:编写易于修改和维护的代码;编写易于测试的代码;编写详细的程序文档,即文档化;采用统一的标准和约定,降低程序的复杂性,即标准化;分离功能独立的代码块,形成新的模块,即模块化。
编码风格(Coding Style)即程序开发人员所编写源代码的书写风格。良好的编码风格能在一定程度上弥补语言存在的缺陷,而如果不注意风格就很难写出高质量的程序。尤其当多个程序员合作编写一个很大的程序时,需要强调良好而一致的编码风格,以便相互通讯,减少因不协调而引起的问题。
编码风格可根据花括号位置分为如下两类。
- Allmans:花括号独占一行;
- Kernighan:左花括号居于行尾。
软件测试(Software Testing)
软件测试是确保程序按期望运行的工序,即验证程序正常工作。软件测试的目的是发现软件的错误,力求设计最能暴露错误的测试方案。
早期的软件测试与软件调试概念混淆,且都由程序员完成。但从心理学的角度而言,由程序的编写者自己进行测试是不恰当的。现在,软件调试(Software Debugging)与软件测试有明显的差异,即软件调试的目的是定位软件错误并纠正错误。
测试用例(Test Case)是为了进行有效的测试而设计的输入数据和预期的输出结果数据。一个好的测试用例能够发现至今尚未发现的错误。穷举测试是不现实的。
软件测试的策略如下。
- 单元测试(Unit Testing):又称模块测试,着重对软件构件或模块进行测试,可并行进行,其中使用的桩模块(Test Stub)代替被测试的模块所调用的模块,而不是软件产品的组成的部分;
- 集成测试(Integration Testing):又称组装测试,将程序模块组装为软件系统后进行测试;
- 确认测试(Acceptance Testing):又称验收测试,检查软件功能和性能是否与需求规格说明书的指标相符,确认整个软件是用户所需的,一般运用黑盒测试方法,由专门测试人员和用户参与;
- Alpha版:粗糙、错误很多,通常只在公司内部测试,用户操作经由开发者指导;
- Beta版:软件接近完成,可能向公众发布以帮助发现问题,开发者通常不在现场。
- 系统测试(System Testing):软件通常受制于计算机系统的其他元素,需要测试是否能与计算机系统协调工作;
- 压力测试(Stress Testing):又称强度测试,需要在非正常数量、频率或容量的方式下执行;
- 性能测试(Performance Testing):测试运行性能,对实时系统和嵌入式系统尤为重要;
- 安全保密性测试(Security Testing)。
V模型(V-Model)展示软件开发各阶段与测试策略各阶段的对应关系,内容如下。
黑盒测试(Black-Box Testing)
黑盒测试不考虑内部结构或运作,只凭键入特定输入得到一定输出的方式来测试。黑盒测试有如下方法。
- 等价类划分(ECP; Equivalence Class Partitioning):等价类(Equivalence Class)即输入域的某个子集,同子集的输入能引发相同的情况,从等价类中选择的用例具有「代表性」,等价类分为有效等价类(Valid Equivalence Class)和无效等价类(Invalid Equivalence Class),分别验证程序是否实现了规格说明中规定的功能,以及是否实现了对不合理的非法输入处理的功能;
- 边界值分析(Boundary-Value Analysis):通常是等价类划分的一种补充,专门挑选位于输入或输出边界值附近的数据作为测试用例;
- 比较测试(Comparison Testing):又称背对背测试(Back-to-Back Testing),通常由两支开发队伍,根据需求规格说明开发两个软件版本,然后用相同的用例分别测试,适用于高可靠性要求的软件,如航空航天控制软件、核电厂控制软件等;
- 猜测(Guessing):根据直觉和经验推测存在的错误;
- 因果图(Cause-Effect Graph):分析输出条件对输入条件的依赖关系,是选取高效测试用例的方法。
白盒测试(White-Box Testing)
白盒测试又称玻璃盒测试(Glass-Box Testing),根据内部逻辑结构设计测试用例。条件(Condition)指程序中不可分解的逻辑运算式,判断(Decision)指由条件组成的逻辑运算式。白盒测试有如下方法。
- 逻辑覆盖测试(Logic Coverage Testing);
- 语句覆盖(Statement Coverage):每个可执行语句都至少执行一次;
- 条件覆盖(Condition Coverage):每个判断的每个条件的所有可能结果都至少出现一次;
- 判断覆盖(Decision Coverage):又称分支覆盖(Branch Coverage),每个进入点和每个结束点都至少执行一次,每个判断的分支都至少经过一次;
- 条件/判断覆盖(Condition/Decision Coverage):每个进入点和每个结束点都至少执行一次,每个判断的每个条件的所有可能结果都至少出现一次,每个判断的分支都至少经过一次;
- 修正的条件/判断覆盖(MC/DC; Modified Condition/Decision Coverage):每个进入点和每个结束点都至少执行一次,每个判断的每个条件的所有可能结果都至少出现一次,每个判断的分支都至少经过一次,而每一个条件都可以独立地影响判断的结果;
- 路径覆盖(Path Coverage):每条路径都至少经过一次。
- 基本路径测试(Basis Path Testing);
- 数据流测试(Data Flow Testing);
- 变异测试(Mutation Testing):将源程序注入错误,即变异为变体(Mutant),然后于变体上执行测试用例,验证测试用例是否可以发现注入的错误。
版本控制(Version Control)
版本控制追踪工程从诞生一直到定案的过程。
大型工程代码通常存储于一个中心服务器上,称为仓库(Repository)。开发者编辑代码,添加功能并测试完毕后,放回仓库的过程,称为提交(Commit)。代码的主(Master)版本,应该总是编译正常,且漏洞尽可能少。
软件缺陷预测(SDP; Software Defect Prediction)
软件缺陷预测是一种能够有效地挖掘软件中尚未被发现的潜在缺陷及其分布情况的技术。
根据是否与软件生命周期有关,缺陷预测可分为静态预测和动态预测,后者预测缺陷分布随软件生命周期的变化情况。缺陷预测的方法策略又可分为如下几类。
- 项目内缺陷预测(WPDP; Within-Project Defect Prediction):利用项目中足够多的已标记数据来训练一个稳定的分类模型,然后基于该模型来预测同一项目中新的模块或实例中的缺陷倾向性;
- 跨项目缺陷预测(CPDP; Cross-Project Defect Prediction):利用其他项目(即源项目)中已经搜集的数据集为目标项目构建缺陷预测模型;
- 异构缺陷预测(HDP; Heterogeneous Defect Prediction):源项目与目标项目特征异构。
通常缺陷预测模型的构建方法有如下两种:基于机器学习的方法;基于统计学的方法。
代码度量元(Code Metrics)是构建高质量缺陷预测模型的关键,因此代码度量元的设计是软件缺陷预测的核心问题。常见的代码度量元如下。
- 代码行数(LOC; Lines of Code):最早的代码度量元,过于简单而难以合理地度量软件系统的复杂性;
- Halstead:通过统计程序内操作符和操作数的数量来度量代码的阅读难度,其假设是代码的阅读难度越高,则含有缺陷的可能性也越高;
- McCabe:其假设是程序的控制流复杂度越高,则含有缺陷的可能性也越高;
- C&K:综合考虑面向对象程序中的继承、耦合性和内聚性等特征,是适用于面向对象程序的度量元。
在软件缺陷预测问题中,真正含有缺陷的模块是少数,缺陷服从帕累托原则(Pareto Principle),即80%的缺陷存在于20%的模块中。因此,类别不平衡问题是软件缺陷预测中普遍存在的问题。
即时(JIT; Just-in-Time)软件缺陷预测是指预测开发者每次提交的代码变更是否存在缺陷的技术,其中代码变更可分为缺陷变更和非缺陷变更。
在即时软件缺陷预测领域,主要是基于变更特征(如修改文件数量等)排序的方法,即对新提交的变更排序,对开发者审查任务进行调度,使开发者在审查一定量代码情况下找到更多缺陷,即工作量感知(Effor-Aware)即时缺陷预测。工作量感知指标是指当开发者根据预测模型的预测结果进行代码审查时,审查一定数量的代码(即工作量)所能检查到的缺陷数量或者比例。通常将代码审查工作量设置为所有变更修改代码总行的20%。
软件维护(Software Maintenance)
软件维护是软件生存周期中持续时长最长、所花费用最多的阶段。软件维护包括如下四项活动。
- 修正性维护:又称纠错性维护,诊断和改正用户使用软件时所发现的软件错误的过程;
- 适应性维护:与变化的环境适配而进行的修改;
- 完善性维护:满足用户提出的新功能或改进意见;
- 预防性维护:为未来的改进奠定更好的基础。
非结构化维护需要付出很大代价,而结构化维护减少精力的浪费并提高维护的总体质量。
可维护性(Maintainability)指理解、改正、调整和改进软件的难易程度,由软件的可理解性、可测试性、可修改性、可移植性和可重用性决定。文档是影响软件可维护性的决定因素。
软件维护有如下两类技术。
- 面向维护技术:在开发阶段用于减少错误、提高软件可维护性;
- 维护支援技术:在维护阶段用于提高维护效率和质量。
软件维护一般经过如下步骤:分析和理解程序;修改程序;重新验证程序。
软件维护的副作用即因修改软件而造成的错误,可分为如下三类:编码副作用;数据副作用;文档副作用。
结构化分析与设计(Structured Analysis and Design)
结构化分析(SA)、结构化设计(SD)和结构化程序设计(SP)构成了完整的结构化方法。
结构化程序设计(SP; Structured Programming)
结构化程序设计指程序的代码块仅通过顺序、选择和循环三种基本控制结构联结,即完全不使用跳转指令,且只有一个入口和一个出口,使用「自顶向下,逐步求精」的程序设计方法。结构化程序设计强调程序的易读性,最早由戴克斯特拉提出,他指出跳转指令是有害的,应当从高级语言中消除。
结构化程序设计可避免写出混杂代码的编程典范,改善计算机程序的清晰性。
部件执行过程的描述方式有如下几种。
- 图形表示法;
- 程序流程图(Flowchart):以框图表示步骤,使用箭头连接,直观清晰,独立于任何一种程序设计语言;
- N-S(Nassi-Shneiderman)图:又称盒图,符合结构化程序设计原则,可以表示程序的结构;
- PAD(Problem Analysis Diagram):由日本日立公司提出,是用结构化程序设计思想表现程序逻辑结构的图形工具,PAD图采用二维树型结构,是软件自动化生成的有力工具,还允许递归使用。
- 判定表:清晰地表达复杂条件的真值组合与动作间的对应关系;
- 设计性语言(PDL; Program Design Language):用于描述功能部件的算法设计和处理细节,是一种伪代码。
结构化分析(SA; Structured Analysis)
面向数据流的分析方法,根据分解与抽象的原则,按照系统中数据处理的流程建立系统的功能模型,从而完成需求分析工作。
数据流图(DFD; Data Flow Diagram)
用于对系统的功能建模,是结构化分析的工具。
DFD简明、易读,为后一阶段的设计、测试、评估提供有利条件,较适合于开发数据处理类型软件的需求分析;但DFD仅是静态模型,没有反应处理的顺序,因此不适合描述实时控制系统、人机交互界面系统等的需求。为了较完整的描述用户对系统的需求,DFD应与数据库中的E-R模型结合起来。
DFD的基本元素如下。
- 数据流(Data Flow):由一组固定成分的数据组成,代表数据的流动方向,用箭头表示;
- 加工(Process):输入数据流到输出数据流的变换,用圆圈表示;
- 文件(File):保存某些数据供以后使用,在各加工间建立合理关系,用双杠表示;
- 源(Source)或宿(Sink):软件系统外的人员或组织,用矩形表示。
为表达稍为复杂的实际问题,需要按照问题的层次结构进行逐步分解,并以分层DFD反映这种结构关系,否则DFD将及其庞大、复杂、难以绘制和理解。分层DFD的审查需要考虑一致性与完整性。
分层DFD的一致性检查包括如下方面:父图与子图的输入、输出数据流应当一致;逻辑上而言,加工的输出数据必须能从其输入数据产生,且无多余输入;子图中加工细节的局部文件不应出现于父图;加工的输入、输出数据流不得同名。
分层DFD的完整性检查包括如下方面:加工至少有一个输入数据流和一个输出数据流;整体而言,每个文件应至少有一个加工读取,有另一个加工写入;每个数据流和文件都必须命名,并与数据字典保持一致;每个基本加工都应有加工规约。
加工规约,又称加工小说明,描述加工逻辑等,最底层的叶加工必须在加工规约中予以定义。加工规约的描述方法有结构化语言、判定表和判定树等。
数据字典(DD; Data Dictionary)
手动建立或计算机辅助建立的,用于存储数据定义和属性的文档。
数据字典是用来定义数据流图中的各个成分的具体含义的。它以一种准确的、无二义性的说明方式为系统的分析、设计及维护提供了有关元素的一致的定义和详细的描述。
数据字典与数据流图密不可分,由如下数据条目组成:数据流;文件;数据项,即组成数据流和文件的数据;加工;源或宿。
结构化设计(SD; Structured Design)
面向数据流的设计方法,目的在于确定软件的结构。
模块结构图(MSD; Module Structure Diagram)
描述软件系统的体系结构,指出系统由哪些模块组成、模块间的调用关系以及模块调用时数据的传递方向,是结构化概要设计的工具。
用直线表示调用关系时,位于上方的模块调用位于下方的模块。
与MSD相关的概念如下。
- 深度;
- 宽度;
- 扇出(Fan Out):模块直接调用的模块数目;
- 扇入(Fan In):能直接调用该模块的数目,反映了该模块的复用(Reuse)程度。
良好的设计策略要求避免高扇出,力求高扇入。
DFD到MSD的映射可使用如下方法。
- 变换分析:确定输入、输出从而确定变换中心,所有的数据流图都可看作变换型数据流图,划分因人而异;
- 事务分析:确定事务中心,根据事务类型执行一个事务处理的功能。
MSD还需精化改进以提高复用程度,精化的要点如下:减少耦合度;避免高扇出;消除重复功能和管道模块,使模块大小适中;考虑全局。
IPO(Input-Process-Output)
结构化概要设计的工具,由IBM提出。IPO图无论如何设计,必须包含输入、处理和输出。
改进的HIPO(Hierarchical IPO)图既是需求分析方法,又是软件设计方法。
IDEF(ICAM Definition)
ICAM(Integrated Computer-Aided Manufacturing)即美国空军的集成计算机辅助制造工程。IDEF图由美国空军发明,是以结构化分析和设计为基础发展的一套系统分析和设计工具。
IDEF图使用框图表示「活动」,即系统功能,其周围的箭头有如下四种类型。
- 输入:位于左侧,实行或完成特定活动所需的资源;
- 输出:位于右侧,经由活动处理或修正后的产出;
- 控制:位于上方,活动的条件限制;
- 机制:位于下方,活动所需的工具,包括人员、设施、装备等。
面向对象分析与设计(Object-Oriented Analysis and Design)
面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)构成了完整的面向对象方法。
面向对象的四个基本特征是抽象、继承、封装和多态。不同于结构化分析与设计,OOA和OOD之间不存在明显鸿沟。
面向对象编程(OOP; Object-Oriented Programming)
面向对象编程使用对象作为基本单元,将数据和程序封装其中,以提高重用性、灵活性和扩展性。其核心是隐藏复杂度,选择性地公布功能。
Simula是第一个面向对象编程的编程语言。
统一建模语言(UML; Unified Modeling Language)
UML是用于说明、可视化和构建面向对象软件的开放方法,是面向对象分析和设计的工具。
UML是一种半形式化语言,与功能结构无关。
类图(Class Diagram)
类图展示类的静态结构,即类与类之间的相互联系,共有如下类型。
关系 | 说明 | 理解 |
---|---|---|
泛化(Generalization) | 继承的反方向 | B extends A |
实现(Realization) | 实现接口的功能 | A implements B |
依赖(Dependency) | 被依赖的对象作为工具 | A uses a B |
关联(Association) | 「强的」依赖关系 | A has a B |
聚合(Aggregate) | 「弱的」包含关系 | A owns a B |
组成(Composition) | 「强的」包含关系 | A is a part of B |
类成员的可见性有如下类型。
符号 | 类型 | 说明 |
---|---|---|
公共的(Public) | 类可见时此属性就可见 | |
受保护的(Protected) | 子类可见 | |
私有的(Private) | 只有类自身可见 | |
包内访问的(Packaged) | 同一包中的类可见 |
内部结构图(Composite Structure Diagram)
内部结构图展示类的分解。
用况图(Use Case Diagram)
用况图展示各类外部执行者与系统内用况的连接,是用户与系统交互的最简表示形式。用况图可以划分系统与外部实体的界限,是系统开发的起点。
- 用况(Use Case):系统所提供的一个功能;
- 执行者(Actor):使用这些用况的人或外部系统。
构件图(Component Diagram)
构件图展示系统中的构件,构件间通过接口的连接,以及构件间的依赖关系。
构件(Component)是是封装了可执行特定功能的单位。
- 请求接口(Required Interface):该构件请求其他供应者提供服务,用半圆表示;
- 供应接口(Provided Interface):为其他请求者提供服务,用小圆圈表示。
状态机图(State Machine Diagram)
状态机图展示该类的对象的所有可能状态,以及何种事件会导致状态的改变。
状态的改变称为迁移(Transition)。
活动图(Activity Diagram)
活动图展示完成一个操作所需的活动,是工作流(Workflow)的图形化表示。
- 动作:活动图的基本组成,用圆角矩形表示;
- 决策:即条件判定,用菱形表示;
- 并行:并发性活动的分离与汇合,用粗实线表示。
活动图可分为若干矩形区,即泳道(Swim Lane),可以清晰地表明活动位于的对象。
顺序图(Sequence Diagram)
顺序图展示对象间的交互行为,关注消息的顺序,即对象间消息发送和接收的顺序。
部署图(Deployment Diagram)
部署图展示处理器、设备和软件构件运行时的体系结构。
包图(Package Diagram)
包图展示包和包间的关系。
敏捷软件开发(Agile Software Development)
影响最广泛的敏捷软件开发方法如下。
- Scrum(得名于橄榄球比赛):规划纲要,冲刺(Sprint)循环,总结项目;
- 极限编程(XP; Extreme Programming):策划,设计,编码,测试;
- 看板(かんばん)方法:可视化工作流,限制在制品(WIP; Work In Process)数量,管理流量。