软件工程
软件开发方法
软件开发方法分类
结构化法
- 用户至上
- 严格区分工作阶段,每阶段有任务与成果
- 强调系统开发过程的整体性与全局性
- 系统开发过程工程化,文档资料标准化
- 自顶向下,逐级分解(求精)
面向过程,不能灵活变动
原型法
- 适用于需求不明确的开发
- 包括抛弃型原型和进化型原型
用于需求分析阶段
面向对象方法
- 更好的复用性
- 关键在于建立一个全面、合理、统一的模型
- 分析、设计、实现三个阶段,界限不明确
面向服务方法
- SO 方法有三个主要抽象级别:操作、服务、业务流程
- SOAD 分为三个层次:基础设计蹭(底层服务构件)、应用结构层(服务之间的接口和服务级协定)和业务组织层(业务员流程建模和服务流程编排)
- 服务建模:分为服务发现、服务规约和服务实现三个阶段
软件开发模型
瀑布模型(SDLC)
适合与需求明确的项目
演化模型
增量模型
螺旋模型
适合与大型系统,引入了风险分析
原型模型
- 抛弃型原型(快速原型模型)
- 进化型模型
喷泉模型
面向对象模型
V 模型
强调测试贯穿与始终的模型(测试尽早做、提前做)
迭代模型/迭代开发方法
快速应用开发(RAD)
快速应用开发(Rapid Application Development,RAD)是一种比传统生存周期法快得多的开发方法,它强调极端的开发周期。RAD 模型是瀑布模型的一个高速变种,通过使用基于构件的开发方法获得快速开发。如果需求理解得很好,且约束了项目范围,利用这种,模型可以很快地开发出功能完善的信息系统
RAD 的软件流程
RAD 的局限:
- 并非所有应用都适合 RAD。RAD 对模块化要求比较高,如果有哪一项功能不能被模块化,那么 RAD 所需要的构建就会有问题;如果高性能是一个指标,且该指标必须通过调整接口使其适应系统构件才能获得,则 RAD 也有可能不能奏效
- 开发者和客户必须在很短的时间完成一系列的需求分析,任何一方配合不当,都会导致 RAD 项目失败
- RAD 只能用于管理信息系统的开发,不适合技术风险很高的情况(例如,一个新项目需要采用很多新技术,或新系统与现有系统有较高的互操作性时,就不适合使用 RAD)
构建组装模型/基于构件的开发方法(CBSD)
- 构件库是快的核心
- 优点:快、节省成本、可靠性高
- 逻辑构建模型用功能包描述系统的抽象设计,用接口描述各个服务集合,以及功能之间如何交互以满足用户需求,它作为系统的设计蓝图以保证系统提供适当的功能
- 物理构建模型用技术设施产品、硬件分布和拓扑结构、以及用于绑定的网络和通信协议描述系统的物理设计,这种架构用于了解系统的性能、吞吐率等许多非功能性属性
统一过程/统一过程开发(UP/RUP)
用例驱动,以架构为中心,迭代和增量
阶段:
- 初始阶段
- 确定项目范围和边界
- 识别系统的关键用例
- 展示系统的候选架构
- 估计项目费用和时间
- 评估项目风险
- 细化阶段
- 分析系统问题领域
- 建立软件架构基础
- 淘汰最高风险元素
- 构建阶段
- 开发剩余的构件
- 构建组装与测试
- 交付阶段
- 进行测试
- 制作发布版本
- 用户文档定稿
- 确认新系统
- 培训、调整产品
敏捷开发方法
- 敏捷开发方法是"适应性"(Adaptive)而非"预设性"(Predictive)
- 敏捷开发方法是"面向人"(people oriented)而非"面向过程"(process oriented)
小步快跑模式,适合小型项目开发
4 大价值观;5 大原则;12 大最佳实践
开发方法:
XP(Extreme Programming, 极限编程)在一些
对费用控制严格的公司中使用
,已经被证实是非常有效
的水晶方法:
用最少纪律约束仍能成功的方法
开放式源码:指
程序开发人员在地域上分布很广
SCRUM:
明确定义了可重复的方法过程
,2-4 周一个冲刺(发布一个可用版本)FDD(Feature Driven Development, 功用驱动开发方法):开发人员分为两类:
首席程序员和类程序员
ASD(Adaptive Software Development, ASD 方法):其核心是三个非线性的、重叠的开发阶段:
猜测、合作与学习
模型驱动的开发方法
基于架构的开发方法
原型模型的演化
软件开发环境
软件开发环境(Software Development Environment,SDE)是支持软件产品开发的软件系统。它由软件工具集和环境集成机制构成,前者用来支持软件开发的相关过程、活动和任务年;后者为工具集成和软件开发、维护和管理提供统一的支持,它通常包括数据集成、控制集成和界面集成
- 数据集成机制提供了存储或访问环境信息库的统一的数据接口规范
- 界面集成机制采用统一的界面形式,提供统一的操作方式
- 控制集成机制支持各开发活动之间的通信、切换、调度和协同工作
软件开发环境应支持多种集成机制,根据功能不同,集成机制可以划分为环境信息库、过程控制与消息服务器、环境用户界面三个部分
- 环境信息库:是软件开发的核心,用以存储与系统开发有关的信息,并支持信息的交流与共享。环境信息库中主要存储两类信息:一类是开发过程中产生的有关被开发系统的信息(例如分析文档、设计文档和测试报告等);另一类是环境提供的支持信息(如文本模板、系统配置、过程模型和可复用构建等)
- 过程控制与消息服务器:是实现过程集成和控制集成的基础。过程集成时按照具体软件开发过程的要求进行工具的选择与组合,控制集成使各工具之间进行通信和协同工作
- 环境用户界面:包括环境总界面和由它实行统一控制的个环境不见及工具的界面。统一的、具有一致性的用户界面是软件开发的重要特征,是充分发挥环境的优越性、高效的使用工具并减轻用户的学习负担的保证
逆向工程
所谓软件的逆向工程就是分析已有的程序,需求比源代码更高级的抽象表现形式。一般认为,凡是在软件生命周期内将软件某种形式的描述转换成更为抽象形式的活动都可称为逆向工程
与之相关的概念
- 重组(restructuring):指在统一抽象级别上转换系统描述形式
- 设计恢复(design recovery):指借助工具从已有程序中抽象出有关数据设计、总体结构设计和过程设计的信息(不一定是原设计)
- 重构/再工程(re-engineering):也称修复和改造工程,它是在逆向工程所获取信息的基础上修改或重构已有的系统,产生系统的一个新版本
- 实现级:包括程序的
抽象语法树
、符号表
、过程
的设计表示 - 结构级:包括反映
程序分量之间相互依赖关系
的信息,例如调用图、结构图、程序和数据结构 - 功能级:包括反映
程序段功能及程序段
之间关系的信息,例如数据和控制流模型 - 领域级:包括反映程序分量或程序诸如实体与
应用领域概念之间的对应关系
的信息,例如实体关系模型
净室软件工程
- 净室即无尘室、洁净室,也就是一个受控污染级别的环境
- 使用盒结构规约(或形式化方法)进行分析和设计建模,并且强调将正确性验证,而不是测试,作为发现和消除错误的主要机制
- 使用统计的测试来获取认证被交付的软件的可靠性所必须的出错率信息
需求工程
概述:
- 软件需求是指用户对系统在功能、行为、性能、设计约束等方面的期望
- 软件需求是指用户解决问题或达到目标所需的条件或能力,是系统或系统部件要满足合同、标准、规范或其他正式规定文档所需具有的条件或能力,以及反映这些条件或能力的文档说明
- 需求开发偏向技术维度
- 需求定义产出 SRS(需求规格说明书)
- 需求验证产出 需求的基线(文档)
需求开发
需求获取
从技术角度分类:
- 业务需求 → 层级较高的需求
- 用户需求
- 系统需求 → 计算机化
对系统需求
进一步细分:
- 功能需求
- 性能需求:例子:加载速度、响应速度
- 设计约束:例子:客户提出要用 xx 数据库、xx 系统
从项目管理
角度分类:
- 基本需求:用户明确提出来的
- 期望需求:隐含需求,对客户来说不需要提出就应该有的
- 兴奋需求:(镀金)客户没有提出但系统提供
需求获取的方法
- 收集资料
- 联合讨论会
- 用户访谈
- 书面调查
- 现场观摩
- 参加业务实践
- 阅读历史文档
- 抽样调查(节省成本,以小概全)
需求分析
结构分析(SA):
- 数据字典:数据元素、数据结构、数据流、数据存储、加工逻辑、外部实体
- 功能模型
- 数据流图(DFD):数据流、加工、数据存储、外部实体
- 数据模型
- E-R 图:实体、联系
- 行为模型
- 状态转换图:状态(初态、终态)、事件
面向对象分析(OOA):
修相关概念:对象(对象、属性、名称(id))、类(实体类、边界类、控制类)、抽象、封装、继承与泛化、多态、接口(只有方法的定义,没有方法实现)、消息、组件、模式和复用
- 实体类:映射需求中的每个实体,实体类保存需要存储在永久存储体中的信息
- 控制类:用于控制用力工作的类,一般由动宾结构的短语转化来的名词
- 边界类:用于封装在用例内、外流动的信息回数据流。边界类位于系统于外界的交界处,包括所有窗体、报表、打印机和扫描仪等硬件接口,以及其他系统的接口
需求定义
- 用结构化和自然语言编写文本型文档
- 建立图形化模型
- 编写形式化规格说明书
产出 SRS(需求规格说明书)
严格定义法:
- 所有需求都能够被预先定义
- 开发人员与用户只 i 按能够准确而清晰地交流
- 采用图形/文字可以充分体现最终系统
原型法:
- 并非所有需求都能够在开发前被准确地说明
- 项目参加者之间通常都存在交流上的困难
- 需要实际的、可供用户参考的系统模型
- 有合适的系统开发环境
- 反复是完全需要和值得提倡的,需求一旦确定,就应遵从严格的方法
需求验证
需求验证 → 需求评审/需求测试 → 正式评审/非正式评审
需求管理
定义需求基线
需求跟踪
- 下游工作产品:代码模块、测试用例
- 黄色是需求矩阵
变更控制
变更流程
工作状态变化
UML
- 构造块
- 事物
- 结构事物:
最静态的部分
,包括:类、接口、协作、用例、活动类、构件和节点 - 行为事物:代表时间和空间上的
动作
,包括:消息、动作次序、连接 - 分组事物:看成一个盒子,如:包、构件
- 注释事物:UML 模型的
解释部分
。描述、说明和标注模型的元素
- 结构事物:
- 关系
- 图
- 事物
- 规则
- 范围:给一个名字以特定含义的语境
- 可见性:怎样使用或看见名字
- 完整性:事物如何正确、一致地相互联系
- 执行:运行或模拟动态模型的含义是什么
- 公共机制
- 规格说明:事物语义的细节描述,它是模型真正的核心
- 修饰:通过修饰来表达更多的信息
- 公共分类:类属于对象、接口以实现
- 扩展机制:允许添加新的规则
4+1 视图
- 1: 这个 1 跟其他 4 个都有联系
- 用例视图(use-case view): 需求分析模型 —— 最终用户
- 4
- 逻辑视图(logical view): 表现为:类与对象(系统的功能) —— 系统分析、设计人员
- 实现视图(implementation view): 表现为:物理代码文件和组件 —— 程序员
- 进程视图(process view): 表现为:线程、进程、
并发
—— 系统集成人员 - 部署视图(deployment view): 表现为:软件到硬件的映射 —— 系统和网络工程师
逻辑视图 → 实现试图/进程试图 → 部署试图
UML 图
静态图(结构图)
- 类图:一组类、接口、协作和它们之间的关系
- 对象图:一组对象及它们之间的关系
- 构件图:一个封装的类和它的接口
- 部署图:
软硬件之间的映射
- 制品图:系统的物理结构
- 包图:表示软件体系结构,由模型本身分解而成的组织单元,以及它们之间的依赖关系
- 组合机构图
动态图(行为图)
用例图:系统与外部参与者的交互
顺序图:强调按时间顺序
通信图(协作图)
- 状态图:状态转换变迁
活动图:类似程序流程图,并行行为
- 定时图:强调实际时间
- 交互概览图
用例模型(用例图)
用例图描述一组用例、参与者及它们之间的关系
- 用户角度描述系统功能;
- 参与者是外部触发因素(包括用户、组织、外部系统、时间);
- 用例是功能单元
用例建模的流程:
- 识别参与者(必须)
- 合并需求获得用例(必须)
- 细化用例描述(必须)
- 用例名称
- 简要说明
- 事件流
- 非功能性需求
- 前置条件
- 后置条件
- 扩展点
- 优先级
- 调整用例模型(可选)
- 包含关系(使用关系):当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示。提取出来公共的用例称为抽象用例,把原始用例称为基本用例或基础用例。
基础用例 ——<<include>>--> 抽象用例
- 扩展关系:一个用例明显混合了两种或两种以上的不同场景,即根据情况可能发生多种分支,应使用扩展关系。分为一个基本用例和一个或多个扩展用例。
基础用例 <——<<extend>>—— 扩展用例
- 泛化关系:当多个用例共同拥有一种类似的结构和行为的社会,可以将它们的共性抽象成父用例,其他用例作为泛化关系中的子用例。
子用例 ————▷ 父用例
- 包含关系(使用关系):当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示。提取出来公共的用例称为抽象用例,把原始用例称为基本用例或基础用例。
- 包含关系与泛化关系的区别在于是否存在父子关系
- 包含关系与扩展关系都可以称为依赖关系
分析模型(类图)
- 定义概念类
- 识别类之间的关系
- 为类添加职责
- 建立交互图
类图(class diagram):类图描述一组类、接口、协作和它们之间的关系
对象图(object diagram):对象图描述一组对象及它们之间的关系。对象图描述了在类图中所建立的事物实例的静态快照
- 类名,方法名,属性名
- 多重度
1
:表示一个集合中的一个对象对应的另一个集合中的一个对象0..*
:表示一个集合中的一个对象对应另一个集合中的 0 个或多个对象(可以不对应)1..*
:表示一个集合中的一个对象对应另一个集合中的 1 个或多个对象(至少对应一个)*
:表示一个集合中的一个对象对用另一个集合中的多个对象
- 关系
- 依赖关系:一个事物发生变化影响另一个事物
- 关联关系:描述了一组链,链是对象之间的连接
- 聚合关系:整体与部分的生命周期
不同
- 组合关系:整体与部分的生命周期
相同
- 聚合关系:整体与部分的生命周期
- 泛化关系:特殊(子类)/一般(父类)关系
- 实现关系:接口与类之间的关系
顺序图(时序图)
顺序图(sequence diagram, 序列图)是一种交互图,他强调对象之间消息发送的顺序,同属显示对象之间的交互
活动图
活动图(activity diagram)将进程或其他计算结构展示为计算内部一步步的控制流和数据流。活动图专注于系统的动态视图。它对系统的功能建模和业务流程建模特别重要,并强调对象间的控制流程
活动图与程序流程图类似,但
活动图支持并发
而程序流程图不支持泳道式活动图如下
状态图
状态图(state diagram)描述一个状态机,它由状态、转移、事件和活动组成。状态图给出了对象的动态视图。它对于接口、类或协作的行为建模尤为重要,而且它强调事件导致的对象行为,这非常有助于反应式系统建模
通信图(协作图)
通信图(communication diagram)也是一种交互图,它强调收发消息的对象或参与者的组织结构。顺序图和通信图表达了类似的基本概念,但它们所强调的概念不同,顺序图强调的是时序,通信图强调的是对象之间的组织结构(关系)
COM(component object model)
COM 是微软公司于 1993 年提出的一种组件技术,它是一种平台无关、语言中立、位置透明、支持网络的中间件技术
COM 不支持任何形式的实现继承
COM 支持两种形式的对象组装:包含(Containment)和聚集(Aggregation)
包含是一个对象拥有指向另一个对象的唯一引用。外部对象只是把请求转发给内部对象,所谓转发就是调用内部对象的方法。包含能重用于内含于其他构件的实现,是完全透明的。如果包含的层次较深,或者被转发的方法本身相对简单,包含会存在性能上的问题
因此,COM 定义第二种重用类型,聚集。聚集直接把内部对象接口引用传给外部对象的客户,而不是再转发请求。保持透明性是很重要的,因为外部对象的客户无法辨别哪个特定接口是从内部对象聚集而来的
软件系统建模
虚线上部分其实就是逆向工程,虚线下面是正向工程
建模方法:
- 结构化建模方法
一种以过程为中心的技术,可用于分析一个现有的系统以及定义新系统的业务需求。结构化建模方法所绘制的模型称为数据流图(DFD)。对于流程较为稳定的系统可以考虑结构化建模 - 信息工程建模方法(或数据库建模方法)
一种以数据为中心,但过程敏感的技术,它强调在分析和研究过程需求之前,首先学研究和分析数据需求。信息工程建模方法所创建的模型被称为实体联系图(ERD)。主要用于数据建模 - 面向对象建模方法
将"数据"和"过程"集成到被称为"对象"的结构中,消除了数据个过程的认为分离现象。面向对象建模方法所创建的模型被称为对象模型。随着面向对象技术的不断发展和应用,形成了面向对象的建模标准,即统一建模语言(UML)。UML 定义了几种不同类型的模型图,这些模型图以对象的形式共建一个信息系统回应用系统。目前比较常用的建模方法
软件设计
在软件开发中,外部设计又称为概要设计,其主要职能是设计各个部分的功能、接口、相互如何关联。内部设计又称为详细设计,其主要职能是设计具体一个模块的实现
软件设计包括以下四个活动
- 架构设计:定义软件系统各主要部件之间的关系
- 数据设计:将模型转换成数据结构的定义。好的数据设计将改善程序结构和模块划分,降低过程复杂性
- 接口设计(人机界面设计):软件内部,软件和操作系统间以及软件和人之间如何通行
- 过程设计:系统结构部件穿换成软件的过程描述。确定软件各个组成部分内的算法及内部数据结构,并选定某种过程的表达形式来描述各种算法
界面设计
人机界面设计
置于用户控制之下
- 以不强迫用户进入不必要的或不希望的动作的方式来定义交互方式
- 提供灵活的交互
- 允许用户交互可以被中断和撤销
- 当技能级别增加时可以使交互流水化并允许定制交互
- 使用户隔离内部技术细节
- 设计应允许用户和出现在屏幕上的丢向直接交互
减少用户的记忆负担
- 减少对短期记忆的要求
- 建立有意义的缺省
- 定义直觉性的捷径
- 界面的视觉布局应该基于真实的世界隐喻
- 以不断进展的方式解释信息
保持界面的一致性
- 允许用户将当前任务放入有意义的语境
- 在应用系统内保持一致
- 如过去的交互模型已建立起了用户期望,除非迫不得已的理由,不要改变它
结构化设计
基本步骤
- 概要设计:将软件需求转化为数据结构和软件系统结构 → 对应集成测试
- 详细设计:过程设计,通过对结构细化,得到软件详细数据结构和算法
基本思想
- 抽象化
- 自顶而下,逐步求精
- 信息隐蔽
- 模块独立(高内聚,低耦合)
内聚类型
从上至下,内聚程度递减
内聚类型 | 描述 |
---|---|
功能内聚 | 完成一个单一功能,各个部分协协同工作,缺一不可 |
顺序内聚 | 处理元素相关,而且必须顺序执行 |
通信内聚 | 所有处理元素集中在一个数据结构的区域上 |
过程内聚 | 处理元素相关,而且必须按特定的次序执行 |
瞬时内聚(时间内聚) | 所包含的任务必须在同一时间间隔内执行 |
逻辑内聚 | 完成逻辑上相关的一组任务 |
偶然内聚(巧合内聚) | 完成一组没有关系或松散关系的任务 |
耦合类型
从上至下,耦合程度递增
耦合类型 | 描述 |
---|---|
非直接耦合 | 两个模块之间没有直接联系,它们之间的联系完全是通过主模块的控制和调用来实现的 |
数据耦合 | 一组模块借助参数表传递简单数据 |
标记耦合 | 一组模块用过参数表传递记录信息(数据结构) |
控制耦合 | 模块之间传递的信息中包含用于控制模块内部逻辑的信息 |
外部耦合 | 一组模块都访问同一全局简单变量,而且不是通过参数表传递该全局变量的信息 |
公共耦合 | 多个模块都访问同一个公共数据环境 |
内部耦合 | 一个模块直接访问另一个模块的内部数据;一个模块不通过正常入口转到另一个模块的内部;两个模块有一部分代码重叠;一个模块有多个入口 |
基本设计原则
- 保持模块的大小适中
- 尽可能减少调用的深度(一般不超过 7 层)
- 多扇入,少扇出
- 单入口,单出口
- 模块的作用域应该在模块之内
- 功能应该是可预测的
面向对象设计
基本过程
包图表示架构图;交互图表示用例实现;完整、精确的类图;其他(状态图、活动图)
设计原则
- 单一职责原则:设计目的单一的类
- 开放-封闭原则:对扩展开放,对修改关闭
- 里氏替换原则:子类可以替换父类
- 依赖倒置原则:要依赖于抽象,而不是具体实现;增对接口编程,不要针对实现编程
- 接口隔离原则:使用多个专门的接口比使用单一的总接口要好
- 组合重用原则:要尽量使用组合,而不是继承关系达到重用目的
- 迪米特原则(最少知道法则):一个对象应当对其他对象有尽可能少的了解
设计模式的概念
架构模式
:软件设计中的高层决策,例如 C/S 结构就属于架构模式,架构模式反映了开发软件系统过程中所作的基本设计决策设计模式
:主要关注软件系统的设计,与具体的实现语言无关惯用法
:是最低层的模式,关注软件系统的设计与实现,实现时通过某种特定的程序设计语言来描述构件与构件之间的关系。每种编程语言都有它自己特定的模式,即语言的惯用法。例如引用-计数就是 C++语言中的一种惯用法
模式是解决一类问题的解决方案
设计模式的分类
- 创建型模式:创建对象
- 工厂方法模式
- 抽象工厂模式
- 原型模式
- 单例模式
- 构造器模式
- 结构型模式:更大的结构
适配器模式
桥接模式
组合模式
装饰模式
- 外观模式
- 享元模式
- 代理模式
- 行为型模式:交互职责分配
职责链模式
命令模式
- 解释器模式
- 迭代器模式
中介者模式
- 备忘录模式
观察者模式
状态模式
策略模式
- 模板方法模式
- 访问者模式
有下划线的表示既可以是类模式,也可以是对象模式;无下划线的表示只是对象模式
创建型模式
设计模式名称 | 简要说明 | 速记关键字 |
---|---|---|
Factory Method 工厂方法模式 | 定义一个创建对象的接口,但由子类决定需要实例化哪一个类。工厂方法使得子类实例化的过程推迟 | 动态产生对象 |
Abstract Factory 抽象工厂模式 | 提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类 | 生产成系列的对象 |
Builder 构造器模式 | 将一个复杂类的表示与其构造相分离,使得相同的构造过程能够得到不同的表示 | 复杂对象构造 |
Prototype 原型模式 | 用原型实例指定创建对象的类型,并且通过拷贝这个原型来创建新的对象 | 克隆对象 |
Singleton 单例模式 | 保证一个类只有一个实例,并提供一个访问它的全局访问点 | 单实例 |
结构型模式
设计模式名称 | 简要说明 | 速记关键字 |
---|---|---|
Adapter 适配器模式 | 将一个类的接口转换成用户希望得到的另一种接口。它使原本不相容的接口得以协同工作 | 转换 接口 |
Bridge 桥接模式 | 将类的抽象部分和它的实现部分分离开来,使他们可以独立地变化 | 继承树拆分 |
Composite 组合模式 | 将对象组合成树形结构以表示"整体-部分"的层次结构,使得用户对单个对象和组合对象的使用具有一致性 | 树形目录结构 |
Decorator 装饰模式 | 动态地给一个对象添加一些额外的职责。它提供了用子类扩展功能的一个灵活的替代,比派生一个子类更加灵活 | 动态附加职责 |
Facade 外观模式 | 顶一个高层的接口,为子系统中的一组接口提供一个一致的外观,从而简化该子系统的使用 | 对外统一接口 |
Flyweight 享元模式 | 提供支持大量细粒度对象共享的有效方法 | 汉字编码 |
Proxy 代理模式 | 为其他对象提供一种代理以控制这个对象的访问 | 快捷方式 |
行为型模式
设计模式名称 | 简要说明 | 速记关键字 |
---|---|---|
Chain of Responsibility 职责链模式 | 通过给多个对象请求的集会,减少亲求的发送者与接收者之间的耦合。将接收对象链接起来,在链中传递请求,直到有一个对象处理这个请求 | 传递职责 |
Command 命令模式 | 将一个请求封装成一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作 | 日志记录,可撤销 |
Interpreter 解释器模式 | 给定一种语言,定义它的文法表示,并定义一个解释器。该解释器用来根据文法表示来解释语言中的句子 | 虚拟机的机制 |
Iterator 迭代器模式 | 提供一种方法来顺序访问一个聚合对象中的各个元素,而不需要暴露该对象的呢不表示 | 数据集 |
Mediator 中介者模式 | 用一个中介对象来封装一系列的对象交互。它使各对象不需要显式地相互调用,从而达到低耦合,还可以独立地改变对象间的交互 | 不直接引用 |
Memento 备忘录模式 | 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的张状态 | 游戏存档 |
Observer 观察者模式 | 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新 | 联动 |
State 状态模式 | 允许一个对象在其内部状态改变时改变它的行为 | 状态变成类 |
Strategy 策略模式 | 定义一系列算法,把它们一个个封装起来,并且使它们之间可以互相替换,从而让算法可以独立于使用它们的用户而变化 | 多方案切换 |
Template Method 模板方法模式 | 定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤 | 框架 |
Visitor 访问者模式 | 表示一个作用于某对象结构中的各元素的操作,使得在不改变各元素的类的前提下定义作用于这些元素的新操作 | 数据与操作分离 |
测试与评审
测试类型
思想
- 尽早、不断的进行测试
- 程序员避免测试自己设计的程序
- 既要选择有效、合理的数据,也要选择无效、不合理的数据
- 修改后应进行回归测试
- 尚未发现的错误数量于该程序已发现的错误数量成正比
分类
- 动态测试(计算机运行)
- 黑盒测试法:不清楚程序内部逻辑
- 等价类划分
- 边界值划分
- 错误推测:根据经验推测
- 因果图
- 白盒测试法:根据内部逻辑设计测试用例
- 基本路径测试
- 循环覆盖测试
- 逻辑覆盖测试
- 语句覆盖(最弱)
- 判定覆盖
- 条件覆盖
- 条件判定覆盖
- 修正的条件判定覆盖
- 条件组合覆盖
- 点覆盖
- 边覆盖
- 路径覆盖(最强)
- 灰盒测试法
- 黑盒测试法:不清楚程序内部逻辑
- 静态测试(纯手工,不依赖计算机)
- 桌前检查
- 代码审查
- 代码走查
测试阶段
- 单元测试:模块测试,模块功能、性能,接口等
- 集成测试:模块间的测试
- 确认测试:验证软件与需求的一致性,内部确认测试、Alpha 测试、Beta 测试、验收测试
- 系统测试:真实环境下,验证完整的软件配置项能否和系统正确连接
- 回归测试:测试软件变更之后,变更部分的正确性对变更需求的符合性
- 性能测试
- 强度测试:在系统==资源特别低(资源受限)==的情况下考察软件系统极限运行情况
- 负载测试:用于测试超负荷环境中程序是否能够承担,确定在各种工作负载下系统的性能,测试当负载逐渐增加时,系统各项性能指标的变化情况
- 压力测试:通过确定系统的瓶颈或不能接受的性能点,来获得系统能过提供的最大服务级别的测试(负载测试和压力测试可以结合,统称为负载压力测试)
- 并发测试(容量测试):主要用于测试系统可处理同时在线的最大用户数量
面向对象测试
- 算法层(单元测试):包括等价类划分测试、组合功能测试(基于判定表的测试)、递归函数测试和多态消息测试
- 类层(模块测试):包括不变边界测试、模态类测试和非模态类测试
- 模板层/类树层(集成测试):包括堕胎服务测试和展平测试
- 系统层(系统测试)
软件调试
软件调试方法:
- 蛮力法:主要思想是"通过计算机找错",但是低效、耗时
- 回溯法(反向):从出错处人工沿控制流程往回追踪,直至发现出错的根源。复杂程序由于回溯路径多,难以实施
- 原因排除法(正向):主要思想式演绎和归纳,用二分法实现
软件调试与测试的区别:
- 测试的目的式找出存在的错误,而调式的目的式定位错误并修改程序已修正错误
- 调试是测试之后的活动,测试和调试在目标、方法和思路上都有所不同
- 测试从一个一致条件开始,使用预先定义的过程,有预知的结果;调试从一个未知的条件开始,结束的过程不可预计
- 测试构成可以实现设计,进度可以事先确定;调试不能描述过程或持续时间
系统运行与维护
遗留系统演化策略
简记:技术/价值,双高改造,双低淘汰,高低集()成(cheng),低高继()承(cheng)
新旧系统的转换策略
- 淘汰策略
遗留系统的技术含量较低,且具有较低的业务价值。对遗留系统的完全淘汰是企业资源的根本浪费,系统分析师应该善于"变废为宝",通过对遗留系统功能的理解和借鉴,可以帮助新系统的建设,降低新系统开发的风险 - 继承策略
遗留系统的技术含量较低,已满足企业运作的功能或性能要求,但具有较高的商业价值,目前企业的业务尚紧密依赖该系统,对这种遗留系统的演化策略为继承。在开发新系统时,需要完全兼容遗留系统的功能模型和数据模型。为了保证业务的连续性,新老系统必须并行一段时间,再逐渐切换到新系统上运行 - 改造策略
遗留系统具有较高的业务价值,基本上能够满足企业业务运作和决策支持的需要。这种系统可能建成的时间还很短,对这种遗留系统的演化策略为改造。改造包括系统功能的增强和数据模型的改造两个方面:系统功能的增强是指在原有系统的基础上增加新的应用要求,对遗留系统本身不做改变;数据模型的改造是指将遗留系统的旧的数据模型向新的数据模型的转化 - 继承策略
遗留系统的技术含量较高,但其业务价值较低,可能只能完成某个部门(或子公司)的业务管理。这种系统在各自的局部领域里工作良好,但对于整个企业来说,存在多个这样的系统,不同的系统基于不同平台、不同的数据模型,形成了一个个信息孤岛,对这种遗留系统的演化策略为集成
数据转换与迁移
维护类型:
正确定维护
:指改正在系统开发阶段易发生额系统测试阶段尚未发现的错误适应性维护
:指使应用软件适应信息技术变化和管理需求变化而进行的修改。企业外部市场环境和管理需求的不断变化也使得各级管理人员不断提出新的信息需求(操作系统变化、软件运行环境变化,导致系统不能正常运行)完善性维护
:扩充功能和改善性能而进行的修改。对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征预防性维护
:为了改进应用软件。的可靠性和可维护性,为了适应未来的软硬件环境变化,应主动增加预防性的新的功能,以使用系统适应各类变化而不被淘汰。如将专用报表功能改成通用报表功能,以适应将来报表格式的变化
区分适应性与完善性:适应性强调因外部环境变更而导致的修改,完善性强调因改进和改善而导致的修改
补充
软件系统的文档可以分为用户文档
和系统文档
两类。用户文档主要描述系统功能和使用方法,并不关心这些功能是怎样实现的;系统文档描述系统设计、实现和测试等各方面的内容。
常见的用户文档包括:功能描述、安装文档、使用手册、参考手册、操作员手册
标准函数库
是一种典型的、原始的横向重用机制。(软件的横向重用是指重用不同应用领域中的软件元素)
系统建议方案报告包含:
- 前置部分:包括标题、目录和摘要
系统概述
:包括系统建议方案报告的目的、对问题的陈述、项目范围和报告内容的叙述性解释系统研究方法
:简要地解释系统建议方案报告中包含的信息是如何得到的,研究工作是如何进行的候选系统方案及其可行性分析
:系统阐述每个候选方案建议方案
:对每个候选方案进行可行性评价,推荐一个解决方案及理由- 结论:简要地描述摘要的内容,再次指出系统开发的目标和所建议的系统方案
- 附录:阅读者可能会感兴趣的所有信息