软件工程
面向对象设计原则
- 单一职责:设计目的单一的类
- 开闭原则;对扩展开放,对修改关闭
- 里氏替换:子类可以替代父类
- 依赖倒置:要依赖于抽象,而不是实现。要针对接口编程,不要针对实现编程
- 接口隔离:使用多个专门的接口好过使用单一的总接口
- 组合重用:要尽量使用组合而不是继承来达到重用的目的
- 迪米特法则:最少知识法则,一个对象应当对其他对象有尽可能少的了解(封装)
迪米特法则的应用准则:
- 在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。
- 在类的结构设计上,每一个类都应当尽量降低成员的访问权限。一个类不应当public自己的属性,而应当提供取值和赋值的方法让外界间接访问自己的属性。
- 在类的设计上,只要有可能,一个类应当设计成不变类。
- 在对其它对象的引用上,一个类对其它对象的引用应该降到最低。
耦合
耦合表示模块之间联系的紧密程度。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差。降低模块间的耦合度能减少模块间的影响,防止对某一模块修改所引起的牵一发动全身的水波效应,保证系统设计顺利进行。
紧密耦合表示模块之间联系非常强,松散耦合表示模块之间联系比较弱,非直接耦合则表示模块之间无任何直接联系。模块的耦合类型通常分为7种:
- 非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过上级模块的控制和调用来实现的。
- 数据耦合:一组模块借助参数表传递简单数据。
- 标记耦合:一组模块通过参数表传递记录等复杂信息(数据结构)。
- 控制耦合:模块之间传递的信息中包含用于控制模块内部逻辑的信息。
- 通信耦合:也叫外部耦合,一组模块共用一组输入信息,或它们的输出需要整合以形成完整数据,即共享输入或输出。
- 公共耦合:多个模块都访问同一个公共数据环境,公共的数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。
- 内容耦合:也叫内部耦合,一个模块直接访问另一个模块的内部数据;一个模块不通过正常入口转到另一个模块的内部;两个模块有一部分程序代码重叠;一个模块有多个入口等。
对于模块之间耦合的强度,主要依赖于一个模块对另一个模块的调用、一个模块向另一个模块传递的数据量、一个模块施加到另一个模块的控制的多少,以及模块之间接口的复杂程度。
内聚
软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分摸块的一个准则就是高内聚低耦合。
内聚度是指内部各元素之间联系的紧密程度,模块的内聚种类通常可分为7种,按其内聚度从低到高的次序依此为:
- 偶然内聚:巧合内聚,完成一组没有关系或松散关系的任务
- 逻辑内聚:完成逻辑上相关的一组任务
- 瞬时内聚:时间内聚,所包含的任务必须在同一时间间隔内执行
- 过程内聚:处理元素相关,而且必须按特定的次序执行
- 通信内聚:所有处理元素集中在一个数据结构的区域上
- 顺序内聚:处理元素相关,而且必须顺序执行
- 功能内聚:完成一个单一功能,各个部分协调工作,缺一不可
系统建模
包括四个模块:
- 用例建模:描述参与者和系统之间的主要交互;用例建模可以描述利益相关者所看到的系统行为
- 组件建模:确定系统的子系统、模块和组件结构,为子系统、模块分配需求和职责,每个组建元素作为一个自包含的单元,用于开发、部署和执行
- 服务建模:提供通用的应用程序,并将应用程序定义为一组抽象服务接口
- 性能建模:是对系统的性能进行度量,为每个组件确定性能指标。包括执行时间、资源使用、开发复杂性、维护复杂性等
静态分析
静态分析通过解析程序文本从而识别出程序语句的各个部分,审查可能的缺陷和异常之处,静态分析包括五个阶段:
- 控制流分析阶段找出并突出显示那些带有多重出口或入口的循环以及不可达到的代码段;
- 数据使用分析阶段突出程序中变量的使用情况;
- 接口分析阶段检查子程序和过程说明及它们使用的一致性;
- 信息流分析阶段找出输入变量和输出变量之间的依赖关系;
- 路径分析阶段找出程序中所有可能的路径并画在此路径中执行的语句
软件质量
软件质量是指反映软件系统或软件产品满足规定或隐含需求的能力的特征和特性全体。软件质量管理是指对软件开发过程进行的独立的检查活动,由质量保证、质量规划和质量控制三个主要活动构成。软件质量保证是指为保证软件系统或软件产品充分满足用户要求的质量而进行的有计划、有组织的活动,其目的是生产髙质量的软件。软件评审是软件质量保证的主要活动之一。
软件质量强调3个方面的内容:
- 软件需求:测试软件质量的基础
- 开发标准:定义一组用于指导软件开发方式的准则
- 期望需求:间接定义用户对某些特性的需求
软件设计
软件设计包括:
- 体系结构设计:也叫软件结构设计,定义软件系统各主要部件之间的关系;开发一个模块化的程序结构,并表示出模块间的控制关系
- 数据结构设计:将模型转换成数据结构的定义。好的数据设计将改善程序结构和模块划分,降低过程复杂性
- 接口设计:人机界面设计,软件内部,软件和操作系统间以及软件和人之间如何通信
- 过程设计:系统结构部件转换成软件的过程描述
另外一种分类:
- 外部设计:软件设计的开始阶段,主要是按系统需求说明来确定此系统的软件结构和对应于系统需求说明,设计出各个功能部分的功能和接口。
- 内部设计:软件工程中的概要设计阶段,按照外部设计中确立的系统软件结构,来细化此系统各个功能部件以及各个部件接口的设计,并详细给出各个功能部件详细的数据输入、输出设计。内部设计细化外部设计中的各种功能。
用户界面设计
用户界面设计的基本原则是从实践中总结出来的一些设计规则。Theo Maiidel在他的界面设计著作中提出3条黄金规则:
- 让用户拥有控制权:用户希望控制计算机,而不是被计算机控制,因此在设计人机界面时应遵循以下原则:交互模式的定义不能强迫用户进入不必要的或不希望的动作的方式、提供灵活的交互、允许用户交互可以被中断和撤销、当技能级別增长时可以使交互流水化并允许定制交互、使用户隔离内部技术细节。
- 减少用户的记忆负担:要求用户记住的东西越多,与系统交互时出错的可能也越大,因此好的用户界面设计不应加重用户的记忆负担。减少用户记忆负担的设计原则为:减少对短期记忆的要求、建立有意义的默认值、定义直觉性的捷径、界面的视觉布局应该基于真实世界的隐喻、以不断进展的方式提示信息。
- 保持界面一致:用户应该以一致的方式展示和获取信息,这意味着所有可视信息的组织遵循统一的设计标准,所有屏幕显示都遵守该标准。输入机制被约束到有限的集合内,在整个软件系统中被一致地使用,同时从任务到任务的导航机制也被一致地定义和实现。保持界面一致性的设计原则包括以下内容:允许用户将当前任务放在有意义的语境中、在应用系列内保持一致性、不要改变用户己经熟悉的用户交互模型。
软件重用
软件重用是指在两次或多次不同的软件开发过程中重复使用相同或相似软件元素的过程。
软件元素包括:程序代码、测试用例、设计文档、设计过程、需求分析文档甚至领域知识。
通常,可重用的元素也称作软构件,可重用的软构件越大,重用的粒度越大。使用软件重用技术可以减少软件开发活动中大量的重复性工作,提高软件生产率,降低开发成本,缩短开发周期。同时,由于软构件大都经过严格的质量认证,并在实际运行环境中得到校验,因此,重用软构件有助于改善软件质量。此外,大量使用软构件,软件的灵活性和标准化程度也可望得到提高。
按照重用活动是否跨越相似性较少的多个应用领域,分垂直式重用与水平式重用:
- 垂直式重用:纵向重用,局限于某一垂直领域的重用,如只在电力系统中用到的构件。指在一类具有较多公共性的应用领域之间进行软部件重用。纵向重用活动的主要关键点是域分析:根据应用领域的特征及相似性预测软部件的可重用性。
- 水平式重用:横向重用,指通用领域的重用。在不同应用领域都可重用的软件元素,如数据结构、分类算法和人机界面构建等。标准函数是一种典型的、原始的横向重用机制。
软件复用的4个过程
- 创建:界定和提供可复用资产,以满足复用者的需要
- 复用:利用可复用资产来生产应用软件产品
- 支持:全面支持可复用资产的获取、管理和维护工作
- 管理:执行计划、启动、资源、跟踪,并协调其他各个过程
主要阶段:构造/获取可复用的软件资产、管理可复用资产和使用可复用资产。
SDE
Software Development Environment,软件开发环境,是指支持软件的工程化开发和维护而使用的一组软件,由软件工具集和环境集成机制构成。前者用来支持软件开发的相关过程、活动和任务;后者为工具集成和软件开发、维护和管理提供统一的支持,它通常包括:
- 数据集成:提供存储或访问环境信息库的统一的数据接口规范;
- 控制集成:支持各开发活动之间的通信、切换、调度和协同工作;
- 界面集成:采用统一的界面形式,提供统一的操作方式;
SDE应支持多种集成机制:如平台集成、数据集成、界面集成、控制集成和过程集成。SDE应支持小组工作方式,并为其提供配置管理,环境的服务可用于支持各种软件开发活动,包括分析、设计、编程、调试和文档等。较完善的SDE通常具有多种功能,例如,软件开发的一致性与完整性维护,配置管理及版本控制,数据的多种表示形式及其在不同形式之间的自动转换,信息的自动检索与更新,项目控制和管理,以及对开发方法学的支持。SDE具有集成性、开放性、可裁减性、数据格式一致性、风格统一的用户界面等特性,因而能大幅度提高软件生产率。
SDE应支持多种集成机制,根据功能的不同,集成机制可以划分为三部分:
- 环境信息库:SDE的核心,用以存储与系统开发有关的信息,并支持信息的交流与共享。环境信息库中主要存储两类信息,一类是开发过程中产生的有关被开发系统的信息,如分析文档、设计文档和测试报告等;另一类是环境提供的支持信息,如文档模板、系统配置、过程模型和可复用构件等。
- 过程控制与消息服务器:是实现过程集成和控制集成的基础。过程集成时按照具体软件开发过程的要求进行工具的选择与组合,控制集成使各工具之间进行并行通信和协同工作。
- 环境用户界面:包括环境总界面和由它实行统一控制的各环境部件及工具的界面。统一的一致性的用户界面是SDE的重要特征,是充分发挥环境的优越性、高效地使用工具并减轻用户的学习负担的保证。
管理
软件工程管理集成过程管理和项目管理,包括以下 6 个方面:启动和范围定义、软件项目计划、软件项目实施、评审和评价、关闭、软件工程度量。
生命周期
根据传统的软件生命周期方法学,可以把软件生命周期划分为软件定义、软件开发、软件运行、软件维护。
软件产品从形成概念开始,经过开发、使用和维护,直到最后退役的全过程成为软件生存周期。一个完整的软件生存周期是以需求为出发点,从提出软件开发计划的那一刻开始,直到软件在实际应用中完全报废为止。软件生存周期的提出了是为了更好地管理、维护和升级软件,其中更大的意义在于管理软件开发的步骤和方法。
软件生存周期模型又称软件开发模型(Software Develop Model)或软件过程模型(Software Process Model),它是从某个特定角度提出的软件过程的简化描述。
软件工程中系统化的方法有时候也叫软件过程。所有软件过程都包含下表所示的4项基本活动:
- 软件描述:客户和工程师定义要生产的软件和对其操作的一些约束
- 软件开发:软件设计和编码实现
- 软件有效性验证:检查就是客户想要的
- 软件进化:随着不同的客户和变化的市场需求而修改
维护
软件维护工作包括多种类型:
- 改正性维护:也叫正确性维护,改正在系统运行(使用)阶段已发生而系统测试阶段尚未发现的错误。软件测试不可能发现系统中所有潜在的错误,程序在使用过程中还可能发生错误,诊断和更正这些错误的过程称为改正性维护
- 适应性维护:指使应用软件适应信息技术变化和管理需求变化而进行的修改。在使用过程中,外部环境(新的硬、软件配置)、数据环境(数据库、数据格式、数据输入/输出方式、数据存储介质)可能发生变化。为使软件适应这种变化,而去修改软件的过程就称为适应性维护
- 完善性维护:指扩充功能和改善性能而进行的修改。在软件的使用过程中,用户往往会对软件提出新的功能与性能要求。为了满足这些要求,需要修改或再开发软件,以扩充软件功能、增强软件性能、改进加工效率、提高软件的可维护性
- 预防性维护:为了适应未来的软硬件环境的变化(为了改进软件未来的可维护性或可靠性,或为了给未来的改进提供更好的基础而对软件进行修改),应主动增加预防性的新功能,以使应用系统适应各类变化而不被淘汰。目的是检测并更正软件产品中的潜在错误,防止它们成为实际错误
逆向工程
逆向工程与重构工程是目前预防性维护采用的主要技术。所谓软件的逆向工程就是分析已有的程序,寻求比源代码更高级的抽象表现形式。一般认为,凡是在软件生命周期内将软件某种形式的描述转换成更为抽象形式的活动都可称为逆向工程。
逆向工程导出的信息可分为如下4个抽象层次:
- 实现级:包括程序的抽象语法树、符号表、过程设计表示等信息
- 结构级:包括反映程序分量之间相互依赖关系的信息,例如调用图、结构图、数据结构等
- 功能级:包括反映程序段功能及程序段之间关系的信息,如数据和控制流模型
- 领域级:包括反映程序分量或程序与应用领域概念之间对应关系的信息,如实体关系模型
上述信息的抽象级别越高,它与代码的距离就越远,通过逆向工程恢复的难度亦越大,而自动工具支持的可能性相对变小,要求人参与判断和推理的工作增多。
应用系统构建中可以采用多种不同的技术,逆向工程就是分析已有的程序,寻求比源代码更高级的抽象表现形式,在软件生命周期内将软件某种形式的描述转换成更为抽象形式的活动;重构是指在同一抽象级别上转换系统描述形式;设计恢复是指借助工具从已有程序中抽象出有关数据设计、总体结构设计和过程设计的信息;再工程是在逆向工程所获信息的基础上修改或重构已有的系统,产生系统的一个新版本。
复杂度
软件源码复杂度度量方法主要有三种:
- 代码行方法:最简单,该方法认为,代码行越多,软件越容易产生漏洞
- Helstead方法:思路是根据程序中可执行代码行的操作符和操作数的数量来计算程序的复杂性。操作符和操作数的量越大,程序结构就越复杂
- McCabe方法:环路复杂度,用来定量度量程序的逻辑复杂度
McCabe
托马斯·麦克凯提出的一种基于程序控制流的复杂性度量方法,又称环路度量,循环复杂度(Cyclomatic Complexity),条件复杂度,圈复杂度。它认为程序的复杂性很大程度上取决于程序图的复杂性。单一的顺序结构最为简单,循环和选择所构成的环路越多,程序就越复杂。
McCabe度量法以图论为工具,先画出程序图,然后用该图的环路数作为程序复杂性的度量值。程序图是退化的程序流程图,即把程序流程图的每一个处理符号都退化成一个结点,原来连接不同处理符号的流线变成连接不同结点的有向弧,这样得到的有向图就叫做程序图。
根据图论,在一个强连通的有向图G中,环的个数V(G)
计算公式:
V(G) = m − n + 2
V(G)
是有向图G中环路数,m是图G中弧数,n是图G中结点数,p是图G中强连通分量个数。在一个程序中,从程序图的入口点总能到达图中任何一个结点,因此,程序总是连通的,但不是强连通的。为了使图成为强连通图,从图的出口点到入口点加一条用虚线表示的有向边,使图成为强连通图。这样就可以使用上式计算环路复杂性。
另有一种计算公式:环路复杂度 = 闭环个数 + 1
McCabe复杂度包括:圈复杂度、基本复杂度、模块设计复杂度、设计复杂度、集成复杂度、行数、规范化复杂度、全局数据复杂度、局部数据复杂度、病态数据复杂度。
实战
使用McCabe方法可以计算程序流程图的环形复杂度,下图的环形复杂度为()。
解析:闭环个数为3,故环路复杂度为4。
工具
软件系统工具的种类繁多,很难有统一的分类方法。通常可按软件过程活动将软件工具分为:
- 软件开发工具:对应软件开发过程的各种活动,包括需求分析工具、设计工具、编码与排错工具、测试工具
- 软件维护工具:辅助软件维护过程中的活动,辅助维护人员对软件代码及其文档进行各种维护活动,包括版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工程工具
- 软件管理工具:包括项目管理工具、配置管理工具
- 软件支持工具:包括软件评价工具
库
几种库:
- 开发库:用于保存开发人员当前正在开发的配置实体
- 受控库:也称主库,包含当前的基线加上对基线的变更
- 产品库:静态库,包含已经发布使用的各种基线的存档,被置于完全的配置管理之下
ITSS
信息技术服务标准,提出IT服务生命周期模型。
IT服务生命周期由5个阶段组成,简称PIOIS:
- Pianning&Design:规划设计,从客户业务战略出发,以需求为中心,参照ITSS对IT服务进行全面系统的战略规划和设计,为IT服务的部署实施做好准备,以确保提供满足客户需求的IT服务;
- Implementing:部署实施,在规划设计基础上,依据ITSS建立管理体系、部署专用工具及服务解决方案;
- Operation:服务运营,根据服务部署情况,依据ITSS,采用过程方法,全面管理基础设施、服务流程、人员和业务连续性,实现业务运营与IT服务运营融合;
- Improvement:持续改进,根据服务运营的实际情况,定期评审IT服务满足业务运营的情况,以及IT服务本身存在的缺陷,提出改进策略和方案,并对IT服务进行重新规划设计和部署实施,以提高IT服务质量;
- Supervision:监督管理,主要依据ITSS对IT服务服务质量进行评价,并列服务供方的服务过程、交付结果实施监督和绩效评估
分布式系统
分布式系统开发分为5个逻辑计算层:
- 表示层实现用户界面;
- 表示逻辑层包括为了生成数据表示而必须进行的处理任务,如输入数据编辑等;
- 应用逻辑层包括为支持实际业务应用和规则所需的应用逻辑和处理过程,如信用检查、数据计算和分析等。考题,业务数据的综合计算分析人物属于此层。
- 数据处理层包括存储和访问数据库中的数据所需的应用逻辑和命令,如查询语句和存储过程等;
- 数据层是数据库中实际存储的业务数据。