软件工程是指应用计算机科学、数学及管理科学等原理,以工程化的原则和方法来解决软件问题的工程,其目的是提高软件生成率、提高软件质量、降低软件成本。
一、需求分析
软件需求是指用户对新系统在功能、行为、性能、设计约束等方面的期望。
1.1 软件需求层次
软件的需求主要分为三个层次,从低到高依次是系统需求、用户需求和业务需求
1.1.1 系统需求
系统需求主要是从系统角度来说明软件需求,包括功能需求、非功能需求和设计约束
- 功能需求:规定开发人员必须在系统中实现的软件功能,满足业务需要
- 非功能需求:系统必须具备的除功能需求外的特性,其中包括软件质量属性
- 性能需求:响应时间、吞吐量、资源利用率等
- 安全性、可靠性、可维护性与易用性等等
- 设计约束:系统的限制条件或补充说明,如系统必须采用国产数据库系统
1.1.2 用户需求
用户需求指用户要求系统必须能完成的任务或功能
1.1.3 业务需求
业务需求是客户对相同高层次的目标要求,通过业务需求可以确定项目范围和视图,来自于项目投资人
1.2 需求分析与定义
1.2.1 质量功能部署
质量功能部署(Quality Function Deployment, QFD)是将用户要求转化成软件需求的技术,目的是最大限度的提升用户的满意度。QFD将软件需求分成三类,分别是常规需求、期望需求和意外需求
- 常规需求:用户认为系统应该做到的功能或性能,实现越多用户越满意
- 期望需求:用户不能正确描述想要得到的功能需求,想当然认为系统应具备的功能或性能
- 意外需求:用户要求范围外的功能或性能,实现这些需求用户会更高兴,但不实现也不影响其购买的决策
二、对象和类
2.1 面向对象的基本概念
- 对象:由数据及其操作所构成的封装体,是构成系统的基本单位
- 类:类和对象的关系为,对象是类的实例,类是对象的模板
- 抽象:通过特定的实例抽取共同特征以后形成概念的过程。比如对象是现实中某个实体的抽象,类是一组对象的抽象
- 封装:将相关概念组成一个单元模块,并通过一个名称来引用它。只能通过对象对外提供的接口进行调用
- 继承:表示类之间层次关系,这种关系使得某类对象可以继承另外一类对象的特征
- 多态:使得在多个类可以定义同一个操作或属性名,并在每个类中可以有不同的实现
- 接口:描述对操作规范的说明
- 消息:体现对象间的交互,通过它向目标对象发送操作请求
- 组件:表示软件系统中可替换的、物理的组成部分
- 复用:指将已有的软件及其有效成分用于构造新的软件或系统。组件技术是软件复用实现的关键
- 模式:描述了一个不断重复发生的问题,以及该问题的解决方案。包括特定环境、问题和解决方案三个组成部分。
2.2 类之间的关系
类与类之间有不同的关系,主要有这六类:
- 关联(Association):关联提供了不同类对象之间的结构关系,关联系统的是对象实例之间的关系,不表示两个类之间的关系
- 依赖(Dependency):两个类A和B,如果B的变化可能引起A的变化,则称类A依赖于类B
- 泛化(Generalization):泛化描述一般事物与该事物中的特殊种类之间的关系,也就是父类与子类之间的关系。而继承关系是泛化关系的反面,可以这样说,子类继承了父类,父类是子类的泛化。
- 聚合(Aggregation):表示类之间的整体与部分的关系,部分可能同时属于多个"整体","部分"与"整体"的生命周期可以不相同
- 组合(Composition):表示类之间的整体与部分的关系,但不可分
- 实现(Realization):一个类或多个类可以实现一个接口,而每个类分别实现接口中的操作
三、统一建模语言UML
UML(Unified Modeling Language) 是一种定义良好、易于表达、功能强大而且普遍使用的建模语言,它融入软件工程领域的新思想、新方法和新技术,作用域不限于支持面向对象分析(Object-Oriented Analysis,OOA)和面向对象设计(Object-Oriented Design,OOD),支持从需求分析开始的软件开发全过程。
UML 独立于软件开发过程,它不是程序设计语言,是一种可视化的建模语言。
3.1 UML中的关系
UML 用关系把事物结合在一起,主要有以下四种关系(也就是类与类之间的6种关系):
- 依赖(dependency):两个事物之间的语义关系,其中一个事物发生变化会影响另一个事物的语义
关联(association):描述一组对象之间连接的结构关系
- 聚合(Aggregation):两个对象是整体与部分,可以分割
- 组合(Composition):两个对象是整体与部分,但是无法分割
泛化(generalization):一般化和特殊化的关系,描述特殊元素的对象可替换一般元素的对象
实现(Realization):一个类或多个类实现一个接口,其中的每个类分别实现接口的操作
3.2 UML视图
UML 由视图(View)、图(Diagram)、模型元素(Model Element)和通用机制(General Mechanism)等几个部分组成:
- 视图:是表达系统的某一方面的特征的UML建模元素的子集,由多个图组成,是在某个抽象层上对系统的抽象表示
- 图:是模型元素集的图形表示,通常是由弧(关系)和顶点(其他模型元素)相互连接构成的
- 模型元素:代表面向对象中的类、对象、消息和关系等概念,是构成图的最基本的常用概念
- 通用机制:用于表示其他信息,比如注释、模型元素的语义等。
而视图则是从不同视角为系统构架建模,形成系统的不同视图,主要有这样五类视图:
- 用例视图(Use Case View):强调从用户角度看到的或需要的系统功能,是被称为参与者的外部用户所能观察到的系统功能的模型图
- 逻辑视图(Logical View):展现系统的静态或结构组成及特征,也叫做结构模型视图或静态视图
- 并发视图(Concurrent View):体现系统的动态或行为特征,也叫做模型视图或动态视图
- 组件视图(Component View):体现系统实现的结构和行为特征,也叫做实现模型视图
- 部署视图(Deployment View):体现系统实现环境的结构和行为特征,也叫做物理视图或环境模型视图
视图主要有图类组成,下面来看看具体的UML图
3.3 UML图
UML图总共有14种,如下所示:
类图:描述系统中类的静态结构
对象图:是类图的实例
用例图:从用户角度描述系统功能,系统与外部系统及用户之间的交互
组件图:描述组件与组件之间关系,主要包括组件、接口和关系。像这种:
配置图:描述环境元素的配置,并把实现系统的元素映射到配置上,显示系统中软件和硬件的物理架构,类似于这种:
状态图:描述一个状态机,它由状态、转移、事件和活动组成。类似于下面这种:
时序图:按照时间顺序描述系统元素之间的交互
协作图(通信图):按照时间和空间顺序描述系统元素间的交互和他们之间的关系
活动图:描述系统元素的活动,活动图主要用来表示活动次序,状态图主要用来表示状态
组合结构图:描述结构化类的内部结构,包括结构化类与系统其余部分的交互点,如下图:
包图:描述由模型本身分解而成的组织单元,以及它们之间的依赖关系,如下图所示:
定时图:是一种交互图,强调消息跨越不同对象或参与者的实际时间,而不仅仅知识关心消息的相对顺序
制品图:描述计算机一个系统的物理结构
交互概览图:活动图和顺序图的混合
四、软件架构设计
软件架构不仅指定了系统的组织结构和拓扑结构,并且显示了系统需求和构件之间的对应关系,提供了一些设计决策的基本原理。
4.1 软件架构风格
软件架构风格是描述某一特定应用领域中系统组织方式的惯用模式(idiomatic paradigm),核心问题是达到架构级的软件复用。Garlan 和Shaw对通用软件架构风格进行了以下分类:
4.1.1 数据流风格
数据流风格顾名思义,所有的数据是按照流的形式在执行过程中前进,不存在结构的反复与重构。主要包括批处理序列和管道-过滤器两种具体的架构风格。
批处理序列:每一步处理都是顺序且独立执行的,如下图所示:
管道-过滤器:过滤器负责对数据进行处理和计算(所有的矩形),管道则是过滤器之间数据流动的通道(所有的黑色箭头),其结构如下图所示:
4.1.2 调用/返回风格
调用返回就是指在系统中采用了调用和返回的机制。包括面向对象风格、主程序/子程序,层次结构三种:
主程序/子程序风格:这种风格是结构化开发时期的经典架构风格,比如
main
方法调用子函数就是这种架构风格面向对象风格:这种风格建立在数据抽象和面向对象的基础上,对象是通过函数和过程的调用来交互
层次结构风格:层次结构中每一层提供一个抽象功能,作为上层通信的基础
4.1.3 独立构件风格
独立构件风格主要强调系统中的每个构件都是相对独立的个体,它们之间不通信,以降低耦合度,提升灵活度。主要包括进程通讯和事件系统子风格
- 进程通讯架构风格:构件是独立的过程,连接件是消息传递。
- 事件系统风格:构件不直接调用一个过程,而是触发或广播一个或多个事件。
4.1.4 虚拟机风格
人为构建一个运行环境,在这个环境之上,可以解析与运行自定义的一些语言,这样可以增加架构的灵活性。主要包括解释器和规则为中心的两种架构风格。
- 解释器:具有解释器风格的软件中含有一个虚拟机,可以仿真硬件执行过程和一些关键应用。
- 规则为中心:基于规则的系统包括规则集、规则解释器、规则选择器及工作内存
4.1.5 仓库风格
仓库风格中有两种不同的构件:中央数据结构说明当前状态,独立构件在中央数据存储上执行,仓库与外构件间的相互作用在系统中会有大的变化。仓库风格主要包括数据库系统、超文本系统和黑板风格。
数据库系统:也就是常见的数据库系统设计
超文本系统:早期的静态网页
黑板系统:解决复杂的非结构化问题,能在求解过程中综合运用不同知识源,使得问题的表达、组织和求解变得容易。
4.2 软件设计
软件设计主要解决软件如何做的问题,合理的软件设计方案既可以保证系统的质量,也可以提高开发效率。从方法上来讲,软件设计分为结构化设计与面向对象设计。
4.2.1 结构化设计
结构化设计(Structure Design)是一种面向数据流的方法,是一个自顶向下、逐步求精和模块化的过程。其基本思想是将软件设计成由相对独立且具有单一功能的模块组成的结构,主要分为概要设计和详细设计两个阶段
- 概要设计:又叫做总体结构设计,主要任务是将系统的功能需求分配给软件模块,确定每个模块的功能和调用关系,形成软件的模块结构图、即系统结构图
- 详细设计:为每个具体任务选择适当的技术手段和处理方法
遵循原则:高内聚,低耦合
4.2.2 面向对象设计
主要任务是对类和对象进行设计,包括类的属性、方法,以及类与类之间的关系。通常遵循这六大原则:
详细可以看这篇文章:设计模式学习笔记(一)设计模式六大原则 - 归斯君 - 博客园 (cnblogs.com)
4.2.3 设计模式
设计模式是前人经验的总结,它使得人们可以方便地复用成功的软件设计。详情可以看我的系列文章:
设计模式学习笔记(二)工厂模式、模板模式和策略模式的混合使用 - 归斯君 - 博客园 (cnblogs.com)
五、软件工程的过程管理
软件过程是软件生命周期中的一系列相关活动,即用于开发和维护软件及相关产品的一系列活动。软件产品的质量取决于软件过程。而在软件过程管理方面,最著名的是能力成熟度模型集成(Capability Maturity Model Integration, CMMI),它融合各种模型,形成了组织范围内过程改进的单一集成模型,其主要目的是消除不同模型之间的不一致和重复,降低基于模型进行改进的成本。
CMMI 主要有连续式和阶段式两种表示法结构:
5.1 连续式表示法
连续式表示法则是相对于单个CMMI过程域,使用能力等级来描述组织过程状态的特征。主要有过程管理、项目管理、工程和支持四个过程组。称为过程能力等级
过程能力 | 过程域 |
---|---|
过程管理 | 组织级过程焦点、组织级过程定义、组织级培训、组织级过程性能、组织级改革与实施【三个过程改革培训】 |
项目管理 | 项目计划、项目监督与控制、供应商合同管理、集成项目管理、风险管理、集成化的团队、定量项目管理【四个项目团队管合同风险】 |
工程 | 需求管理、需求开发、技术解决方案、产品继承、验证、确认【两个需求技术,集成认(确认)证(验证)】 |
支持 | 配置管理、度量和分析、过程和产品质量保证、决策分析和解决方案、组织级集成环境、因果分析和解决方案【制(配置)度(度量)保证决策,环境决定因果】 |
5.2 阶段式表示法
阶段式表示法是相对于CMMI模型整体,使用成熟度级别来描述组织过程总体状态的特征。主要有初始级、可管理级、已定义级、量化管理级和优化管理级五个成熟度级别。称为组织成熟度等级
成熟度 | 过程域 |
---|---|
可管理级 | 需求管理、项目计划、配置管理、项目监督与控制、供应商合同管理、度量和分析、过程和产品质量保证 |
已定义级 | 需求开发、技术解决方案、产品集成、验证、确认、组织级过程焦点、组织级过程定义、组织级培训、集成项目管理、风险管理、集成化的团队、决策分析和解决方案 |
量化管理级 | 组织级过程性能、定量项目管理 |
优化管理级 | 组织级改革与实施、因果分析和解决方案 |
六、软件测试及其管理
6.1 测试的方法
软件测试方法包括静态测试和动态测试。静态测试主要采用人工检测和计算机辅助静态分析的手段对程序进行检测;动态测试是指在计算机上实际运行程序进行软件测试。
6.1.1 静态测试
静态测试主要包括对文档和对代码的静态测试:
- 对文档的静态测试:主要以检查单的形式进行
- 对代码的静态测试:主要有桌前检查(Desk Checking)、代码走查和代码审查
6.1.2 动态测试
动态测试主要包括白盒和黑盒测试:
白盒测试:也称为结构测试,主要用于软件单元测试。将程序看成是一个透明的白盒,测试人员清楚程序的结构和算法。测试方法主要有:
- 控制流测试
- 数据流测试
- 程序变异测试
其中静态测试的方法也可以实现白盒测试,属于白盒测试的范畴
黑盒测试:又叫做功能测试,主要用于集成测试、确认测试和系统测试中。黑盒是将程序看成是一个不透明的黑盒,测试人员不清楚程序内部的结构和算法。只检查程序功能是否按照SRS的要求正常使用,程序是否能适当地接收输入数据并产生正确的输出信息。
6.2 测试的类型
测试可以分为单元测试、集成测试、确认测试、系统测试、配置项测试和回归测试等类别
6.2.1 单元测试
也叫做模块测试,测试的对象是可独立编译或汇编的程序模块。
6.2.2 集成测试
目的检查模块之间,以及模块和已集成的软件之间的接口关系,并验证已集成的软件是否符合设计要求。
6.2.3 确认测试
用于验证软件的功能、性能和其他特性是否与用户需求一致。根据用户的参与程度可以包括:
- 内部确认测试:主要由软件开发组织内部按照SRS进行测试
- Alpha测试和Beta测试:Alpha测试指用户在开发环境下测试,Beta指用户在实际使用环境下进行测试
- 验收测试:指针对SRS,在交付前以用户为主进行的测试,其测试对象是完整的、集成的计算机系统。
6.2.4 系统测试
系统测试的对象是完整的、集成的计算机系统,系统测试的目的是在真实系统工作环境下,验证完整的软件配置项能否和系统正确连接,并满足系统/子系统设计文档和软件开发合同规定的要求。
6.2.5 配置项测试
配置项测试的对象是软件配置项,配置项测试的目的是检验软件配置项与SRS的一致性。软件配置项测试就是开发已经完成,准备提供给客户的产品,可能是执行代码,也可能是产品文档。
6.2.6 回归测试
回归测试的目的是测试软件变更之后,变更部分的正确性和对变更需求的符合性,以及软件原有的、正确的功能、性能和其他规定的要求的不损害性。
综合来说,测试的顺序应该是单元测试->集成测试->配置项测试->系统测试->确认测试->回归测试
6.3 软件调试
软件测试的标志是发现错误,而软件调试则是根据错误迹象确定错误的原因和位置,并加以改正。
七、软件集成技术
主要介绍软件层次的集成技术—企业应用集成(Enterprise Application Integration, EAI),企业应用集成技术可以消除信息孤岛,将多个企业信息系统连接起来,形成一个整体。EAI 主要包括表示集成、数据集成、控制集成和业务流程集成。
7.1 表示集成
表示集成也叫做界面集成,它是比较原始和最浅层次的继承。该方法把用户界面作为公共的集成点,把原有零散的系统界面集中在一个新的界面中。
同时表示集成也是黑盒集成,无须了解程序与数据库的内部构造。它是集成多个系统到一个集成点中。
7.2 数据集成
数据集成是白盒集成,必须首先对数据进行标识并编成目录,另外还要确定元数据模型,保证数据在数据库系统中分布和共享。如分布式数据库提供连接的数据库访问中间件技术(数据中间件)
7.3 控制集成
控制集成也叫做功能集成或者应用集成,是在业务逻辑层上对应用系统进行集成。控制集成的集成点存于程序代码中,集成处可能只需要简单使用公开的API(应用程序编程接口)就可以访问。控制集成是黑盒集成。比如企业应用于微信公众号、小程序集成
7.4 业务流程集成
也叫做过程集成,这种集成超越了数据和系统,它由一系列基于标准的、统一数据格式的工作流组成。它不仅要提供底层应用支撑系统之间的互联,同时要实现存在于企业内部的应用之间,本企业和其他合作伙伴之间的端到端的业务流程的管理。比如企业-银联-银行资金业务及流程集成。