导图社区 软件工程
软件工程包括可行性研究、需求分析、总体设计/概要设计、编码及单元测试、设计优化、软件架构等等。
编辑于2022-11-16 15:55:28 山西软件工程
问题定义
问题是什么
阶段结果:系统规模和目标的报告书
可行性研究
目的:不是解决问题,而是问题是否值得被解决
主要方面:技术、经济、操作
结果(任务):可行性研究报告、初步项目开发计划
具体实现
系统流程图(物理系统)
表示数据在各部件间流动
物理数据流图
物理模型
数据流图(DFD)
描述信息流和数据从输入移动到输出的过程中受得变换
数据源点/终点、处理、数据存储、数据流
每个加工至少有一个输入输出
一定要标输入输出流名称
数据字典
组成
数据流
数据流分量(数据元素)
数据存储
处理
用途:作为分析阶段的工具
定义数据:顺序、选择、重复
需求分析
系统必须做什么
结果:需求规格说明书
数据模型
ER图
描绘数据对象及数据对象之间的关系
功能模型
数据流图
数据变换的逻辑过程
行为模型
状态图
作为外部事件结果的系统行为
总体设计/概要设计
系统应该如何实现,划分出组成该系统的物理元素
结果:系统说明、用户手册、测试计划、详细的实现计划、数据库设计
设计原理
模块化
把程序划分成独立命名且可独立访问的模块,每个模块完成一个子功能,把这些模块集成起来构成一个整体,可以完成指定的功能满足用户的需求。
抽象
逐步求精
信息隐藏和局部化
应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的
子主题
模块独立
耦合
无耦合/非直接耦合
应该这样设计和确定模块,使得一个模块内包含的信息(过程和数据)对于不需要这些信息的模块来说,是不能访问的
数据耦合
一个模块访问另一个模块时,彼此之间是通过简单数据参数 (不是控制参数、公共数据结构或外部变量) 来交换输入、输出信息的
特征耦合
把整个数据结构作为参数传递,而被调用的模块仅需使用其中一部分数据
控制耦合
模块间通过传递控制信息(开关、标志、名字等)来完成调用
公共环境耦合
一组模块都访问同一个公共数据环境,公共的数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等
松散的
一个模块往公共环境送数据、另一个取
紧密的
两个都既送又取
内容耦合
一个模块访问另一个模块的内部
一个模块不通过正常入口而转到另一个模块的内部
两个模块有一部分程序代码重叠
一个模块有多个入口
内聚
偶然
一个模块任务间关系松散或者没有关系
逻辑
模块完成的任务在逻辑上属于相同或者相似的一类
时间
模块包含的任务必须在同一段时间内执行 (如初始化模块)
过程
一个模块内的处理元素相关,并且以特定的次序执行,如将程序流程图中循环,判定部分划分成模块
通信
模块中所有元素都使用同一个输入数据和/或产生同一个输出数据
顺序
一个模块内的处理元素和同一个功能密切相关,并且必须顺序执行(前一个处理的输出是后一个处理的输入)
功能
模块内所有处理元素属于一个整体,完成一个单一的功能
启发规则
改进软件结构提高模块独立性
模块规模应该适中
深度、宽度、扇入和扇出应该适当
深度:软件结构中控制的层数,标志系统大小和复杂程度
宽度:软件结构内同一个层次上模块总数的最大值
扇出:一个模块直接调用的模块数目
扇入:表示有多少个上级模块调用它
作用域应该在控制域内
力争降低模块接口的复杂程度
设计单入口和单出口的模块
模块功能应该可以预测
图形工具
层次图
连线表示调用关系
HIPO图
自顶向下
结构图
连线表示调用关系
空心圆传数据、实心圆传控制信息
面向数据流的设计方法
变化流
子主题
事务流
子主题
详细设计
根本目标:应该怎样具体实现所要求的系统
结构程序设计
仅仅通过顺序、选择、循环进行连接。仅有一个入口一个出口
自顶向下、逐步求精
过程设计的工具
程序流程图
盒图
PAD图
判定表
判定树
PDL(伪码)
流图
环形复杂度
复合条件
环形复杂度
流图中的区域数
边数-结点数+2
判定节点数+1
编码及单元测试
软件测试
目的:为了发现程序中的错误而执行程序的过程
测试方法
黑盒(功能)测试
白盒(结构)测试
测试用例:包括测试数据和预期结果
逻辑覆盖
语句覆盖
每个语句至少执行一次
判定覆盖
不仅每个语句必须至少执行一次,而且每个判定的每种可能的结果都应该至少执行一次,也就是每个判定的每个分支都至少执行一次
条件覆盖
判定表达式中的每个条件都取到各种可能的结果
判定/条件覆盖
使得判定表达式中的每个条件都取到各种可能的值,而且每个判定表达式也都取到各种可能的结果
条件组合覆盖
每个判定表达式中条件的各种可能组合都至少出现一次
路径覆盖
测试步骤
模块测试/单元测试
保证每个模块作为一个单元能正确运行
发现编码和详细设计中的错误
单元测试和编码属于软件过程的同一阶段
测试重点
模块接口
局部数据结构
重要执行通路
出错处理通路
边界条件
代码审查
计算机测试
驱动程序
接收测试数据
存根程序
代替被测试模块所调用的模块
集成测试
子系统测试
注重测试模块的接口
系统测试
软件设计中和需求说明中的错误(概要设计)
测试和组装软件的系统化技术
非渐增式测试
渐增式测试
自顶向下
对主控制模块进行测试,测试时用存根程序代替所有直接附属于主控制模块的模块
根据选定的结合策略(深度优先或宽度优先),每次用一个实际模块代换一个存根程序(新结合进来的模块往往又需要新的存根程序)
深度优先:M1->M2->M5->M8->M6->M3->S7->S4
宽度优先:M1->M2->M3->S4->M5->M6->S7->M8
优点
不需要测试驱动程序
能够在测试阶段的早期实现并验证系统的主要功能
能在早期发现上层模块的接口错误
缺点
需要存根程序
低层关键模块中的错误发现比较晚
不能充分展开人力
自底向上
不需要存根程序
子主题
验收测试/确认测试
目的:验证系统确实能够满足用户的要求
发现系统说明书中的错误(需求分析阶段)
必须有用户积极参与或以用户为主进行
Alpha测试:由用户在开发者场所环境进行
Beta测试:开发者不在场
平行运行
综合测试
维护
已交付使用之后,为了改正错误而满足新的需要而修改软件的过程
四项活动
改正性维护
适应性维护
完善性维护
预防性维护
影响软件可维护性
可理解性
可测试性
可修改性
可移植性
可重用性
软件再工程
库存目录分析
文档重构
逆向工程
代码重构
数据重构
正向工程
设计优化
小即是美
体现出设计思想的灵活性、 完整性与轻量性,是优化的基础。
原则
KISS
YAGNI
设计优化思想
运行时的多态
多态性在结构上形成类的继承层次。
B从A继承,C从B继承,只有A类方法是可用的
A类中的具体方法可在C类重写
重写的方法本质上与父类方法具有相似的行为,但在细节 上进行了有针对性的调整。
重写的方法与原方法在相同的条件作用下工作,子类的方 法不应具有比其父类更严格的条件限制。
重写的方法最高不能超出父类方法的状态。
优点
运行时多态使方法的调用动态绑定,可减少switch 的使用,减少分散的重复的但又相同的计算逻辑。
耦合的数据链
交互集中的设计与交互分散的设计
集中到分散
优点:分散交互设计的好处是每个类只需了解与其本身相关的子任 务,避免了不得不去了解其他所有类的情况,分散的交互方 式使得模块的组织简单化
狎昵关系
面向对象提供的封装机制并不能完全保证模块的独立性必须要在设计中充分考虑业务结构的特点并做出利于稳定的设计决策才行
被拒绝的遗赠
已经存在某个类,但该类不具有所需要的功能,为满足需求在该类的基础上进行功能和结构的扩展
继承:但当子类只需要重用父类的某些功能,对父类的行为并不想保持一致,这就是拒绝的遗赠现象,预示着继承层次的误用,应考虑第二种方式进行扩展。
委托:其基本形式是新类与原有类构成关联关系,即具有一个它的实例变量。
新的功能会非常容易地在新类中进行重用,而且与上层类之间的依赖也不再强烈。
循环依赖
如果两个类分别处于不同的包中,并且具有双向导航的关联关系,这样的循环依赖好像是不可避免的。
优点:通过调整打破两个包间的循环依赖状态,整体上只保留包B对包A的依赖。
设计原则
接口隔离
依赖倒置原则
开放封闭原则
Liskov替换原则
单一职责原则
合成/聚合复用原则
设计模式
创建模式
抽象工厂(Abstract Factory)
通过创建一个抽象工厂减少了耦合程度,消除对对象创建的耦合
提供了对不同系列产品的创建
单例模式(Singleton)
保证了一个类仅有一个实例,并提供一个访问它的全局访问点。
要求
类的所有构造方法都为私有的,防止其被外部创建
提供一个公有的方法获取该类的实例
类中的实例变量为私有或受保护的
结构模式
适配器模式(Adapter)
把一个类的接口变换成客户类所期待的另一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作
两种工作方式:委托和继承(接口实现)
桥模式(Bridge)
是将抽象部分与它的实现部分(行为)进行分离,使它们都可以独立地变化
识别出一个类所具有的两个独立变化的维度,将其设计为两个独立的继承等级结构,为两个维度都提供抽象层,并建立抽象耦合
装饰模式(Decorator)
以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性
既有继承又存在组合,是桥模式的特殊形式
门面模式(Facade)
可以较为自由的实现内部功能,只要保证行为具有门面接口中约定的行为即可,在大型的软件开发中可以事先将各个子系统的外部行为确定下来,即门面接口,然后逐渐完善内部设计和开发,称为“基于契约的设计(Design by Contract)”
代理模式(Proxy)
用来对有价值(稀缺)资源的管理,比如数据库的连接等,目的就是为了提高这些资源的利用率或者系统性能。
行为模式
观察者模式(Observer)
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象
当这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己
MVC架构
主题对象相当于模型
观察者对象相当于视图
策略模式(Strategy)
针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换
优点
能够使得算法可以在不影响到客户端的情况下发生变化,而且将算法的行为和环境分开,环境类负责维持和查询行为类,各种算法在具体的策略类中提供
由于算法和环境独立开来,算法的增减、修改都不会影响到环境和客户端
状态模式(State)
状态模式允许一个对象在其内部状态改变的时候改变行为
软件架构
定义:软件架构为软件系统提供了一个结构、行为、和属性的高级抽象,由构成系统的元素的描述、这些元素的相互作用、知到元素集成的模式及这些模式的约束组成。
目的:解决软件的重用、质量和维护问题。
4+1视图
逻辑视图
可以用对象模型代表逻辑视图,用类图描述逻辑视图
功能描述、类模型
开发视图(模块视图)
软件模块的组织和管理
子系统、接口
进程视图(并发视图)
侧重功能特性、主要关注非功能特性
处理流程、并行性、同步
物理视图
考虑系统性能、可靠性等
目标硬件、网络
场景视图
体系结构的核心模型
构件、连接件、配置、端口、角色
软件架构风格
数据流风格
批处理序列
管道与过滤器
特点:每个构件都有一组输入和输出,这种风格的连接件就是数据流传输的管道 ,将一个过滤器的输出传到另一过滤器的输入。过滤器是独立的实体
优点:适合批处理和非交互处理的系统,使软件具有良好的信息隐藏性和模块独立性,从而高内聚、低耦合
调用/返回风格
层次结构
特点:每一层为上层提供服务,并作为其下层客户。
优点:允许将一个复杂的系统按递增的步骤进行分解,而且便于功能的增强和扩展。
正交软件
特点:由组织层和线索的构件构成,如果线索是相互独立的,即不同线索中的构件之间没有相互调用,那么这个结构就是完全正交的。
优点:在软件演化过程中,系统需求会不断发生变化。在正交软件架 构中,因线索的正交性,每个需求变动仅影响某一条线索
客户机/服务器结构 C/S
服务器:负责管理系统资源:访问与并发性控制、安全性、备份 与恢复和全局数据完整性规则。
客户机:客户应用程序提供用户与服务器交互的界面、向服务器提交用 户请求并接收来自服务器的信息、利用客户应用程序对存在于 客户端的数据执行应用逻辑要求
优点
服务器为多个客户应用程序 管理数据
对于硬件和软件的变化具有 极大的适应性和灵活性
易于对系统进行扩充和缩小
系统中的功能构件充分隔离
浏览器/服务器结构 B/S
优点
应用(程序)在一定程度上具有集中特征。
减轻安装、配置和升级等维护工作
层与层之间相互独立,任何一层的改变都不影响其他层原有的 功能,所以可用不同厂家的产品组成性能更佳的系统。(平台 透明性)
独立构件
进程通信
事件系统
MVC系统
模型(Model)-视图(View)-控制器(Controller)
虚拟机风格
解释器
基于规则的系统
数据中心
数据库系统
超文本系统
仓库/黑板系统
特点:中央数据结构说明当前状态,独立构件在中央数据存储上执行 ,仓库与外构件间的相互作用在系统中会有较大的变化
优点:黑板系统的传统应用是信号处理领域,如语音和模式识别,另 外的应用包括松耦合代理数据共享存取等
面向对象分析
5个层次
主题层
类与对象层
结构层
属性层
服务层
面向对象方法学
面向对象
对象+类+继承+通信
特点
认为客观世界是由各种对象组成的,任何事物都是对象
把所有对象都划分成各种对象类
按照子类与父类的关系,把若干个对象类组成一个层次结构的系统
对象彼此间仅能通过传递消息相互联系
突出优点
子主题
面向对象概念
对象
由描述该对象属性的数据以及可以对这些数据施加的操作封装在一起的统一体
对象特点
以数据为中心
对象是主动的
实现了数据封装
本质上具有并行性
模块独立性好
类
对具有相同数据和相同操作的一组相似对象的定义(类是支持继承的抽象数据类型,而对象是类的实例)
消息
要求某个对象执行在定义它的那个类中所定义的某个操作的规格说明
方法
对象所能执行的操作,也就是类中所定义的服务。方法描述了对象执行操作的算法,响应消息的方法
属性
类中所定义的数据,它是对客观世界实体所具有的性质的抽象
封装
把某个事物包起来,使外界不知道该事物的具体内容
条件
有一个清晰的边界。所有私有数据和实现操作的代码都被封装在这个边界内,从外面看不见更不能直接访问
有确定的接口(即协议)。这些接口就是对象可以接受的消息,只能通过向对象发送消息来使用它。
受保护的内部实现。实现对象功能的细节(私有数据和代码)不能在定义该对象的类的范围外进行访问。
继承
继承是指能够直接获得已有的性质和特征,而不必重复定义它们
多态性
在类等级不同层次中可以说明名字、参数特征和返回值类型都相同的虚拟成员函数,而不同层次的类中的虚函数实现算法各不相同
重载
函数重载
在同一作用域内的若干个参数特征不同的函数可以使用相同的函数名字
运算符重载
同一个运算符可以施加于不同类型的操作数上面
面向对象建模
对象模型
描述系统数据结构
最重要、最基本、最核心
描述了系统的静态结构
类图
动态模型
描述系统控制结构
UML状态图
功能模型
描述系统功能
数据流图
UML用例图
敏捷生命周期模型
原则
个体和互动胜过流程和工具
工作的软件胜过详尽的文档
客户合作胜过合同谈判
相应变化胜过遵循计划
极限编程(XP)
小规模,频繁的版本开发,短迭代
测试驱动开发(TDD)
结对编程(PP)
持续集成(CI)
每日站立会议(DSM)
共同拥有代码(CCO)
系统隐晦(SM)
传统生命周期
瀑布模型
快速原型
增量模型
螺旋模型
喷泉模型
内聚从低到高
耦合程度从低到高
浮动主题