目录
软件体系结构概述
一、软件体系结构的定义
目前还没有一个标准的,普遍接受的定义
二、软件体系结构的优势
- 容易理解
- 它从一个高层设计的抽象层次来表征一个系统
- 简化了我们理解的庞大系统的能力
- 重用
- 重用大的构件
- 重用一些集成构件的框架
- 特定领域的软件体系结构
- 设计模式
- 控制成本
- 系统维护者可以更好的理解变更带来的影响,因而可以更加精确的估算变更所需的成本
- 可分析性
- 对系统的一致性检查提供高层次的视图
- 研究系统是否与某种特定领域系统的体系结构
- 分析依赖于其中的构件
经典软件体系结构
非结构化编程——最早的编程泛型
结构化设计的优缺点
优点
- 逻辑设计与物理设计分离
- 开发过程中形成一套规范化的文档,便于将来修改和维护
缺点 - 开发周期长,开发过程复杂
- 系统难于适应环境变化
- 经验表明,较小的程序(小于10万行)适合于结构化开发
一、调用-返回风格软件体系结构
分而治之
主要思想:将一个复杂的大系统分解为一些子系统,以便降低复杂度,并且增加可修改性
这种系统的程序执行顺序通常只由一个单线程控制
控制流示意
图中的长箭头可以理解为是一个程序构件对另外一个构件的调用,而短箭头为程序运行控制流的走向,这也就是名称“调用-返回”的由来
- 拥有整个软件的入口的构件叫做主程序(Main Program),它控制子程序的执行顺序
- 可以被所有构件访问的共享数据被称为全局变量(Global varible)
1.主程序-子程序
结构化设计
层次化的划分方法
- 调用-返回风格体系结构可以被组织成任何形式,但层次结构的组织形式更清晰
- 层次结构的设计被称为共享数据的主程序-子程序软件体系结构
自顶向下的设计方法(层次化划分) - 系统从功能的角度进行设计,从高层开始,逐步细化为详细设计
- 该设计从系统要完成的功能需求出发,首先将一个整体问题分为几个子问题,然后再考虑将每个子问题再次划分为几个更小的子问题,依次下去,直到不可再分为止。
- 结构化设计从数据流图开始,然后将数据流图转换为程序结构图
例如:
这个解析在书P187-188
自顶向下的设计方法的问题
-
功能演化困难
-
现实中的系统功能不容易描述
-
功能化设计丢掉了数据与数据结构
-
由功能设计得到的软件产品的可复用的代码较少
2.面向对象
面向对象设计
面向对象软件体系结构
面向对象的特点
- 封装性
- 继承性
- 多态
- 复用和可维护性
- 对象是对现实世界的抽象并且可以管理自己
- 系统功能通过对象服务表示
- 共享数据区域被取消
- 对象可以是分布式的
面向对象的继承机制
- 继承的目的是代码复用
- 继承提供了一个统一的接口,容易实现多态
面向对象设计的优点
- 容易维护
- 可复用性好
- 映射现实世界
- 容易对一个系统进行剖分
面向对象设计的缺点 - 面向对象程序占用内存较大
- 一个对象要和另外一个对象交互,该对象必须知道另外一个对象的身份,包括对象名、方法名和参数类型等。
主程序-子程序与面向对象体系结构的相似之处
二、数据流风格软件体系结构
在数据流风格体系结构中的组件是可以被重复使用的,且在保证输入与输出接口都不变的情况下,可以独立修改一个组件,而不影响其他组件
在实现数据流风格软件体系结构的软件时,需要特别注意组件之间的同步问题
控制流和数据流对比
控制流 | 数据流 |
---|---|
![]() | ![]() |
数据流风格三种例子
1.顺序批处理软件体系
在该系统中,组件为独立的程序,并且这些组件按照先后顺序处理,即只有当一个组件的运行彻底结束以后,下一个组件才能开始执行。可以认为,数据在处理步骤之间的传输是成批(块)的,而不是以数据流的方式进行的。这也是"顺序批处理"名称的由来。
批处理系统特点
- 每个处理程序模块都是互为独立的程序
- 只有上一步程序彻底完成,下一步程序才能开始
- 数据作为一个整体进行传输
- 因为以上的特点,所以不必对其组件进行同步处理
- 因为几个组件只能按照顺序运行,而不能同步运行,所以性能可能比那些能按照几个组件同时运行的程序要差一些
- 使用顺序批处理结构设计的软件不适用于要求对数据进行实时处理的系统
例如:
2.管道-过滤器软件体系
- 在管道-过滤器软件体系结构中,每个组件都有一组输入和输出,组件读入输入数据流,经过数据处理,然后产生输出数据流。
- 在输入被完全消费之前,输出便产生了
- 组件被称为过滤器,这种风格的连接件就像是数据流传输的管道
过滤器
过滤器三个部分组成
- Input Port 负责存储待处理的数据
- Filter 负责处理数据
- Output Port 负责存储已经处理完的数据
管道
管道的三个组件
- Input Stream 输入流
- Pipe 管道
- Output Stream 输出流
作用:在过滤器之间传送数据
- 单向流
- 可能具有缓冲区
- 管道形成传输图
不同的管道中流动的数据流,具有不同的数据格式
原因:数据在流过每一个过滤器时,被过滤器进行了丰富、精炼、转换、融合、分解等操作,因而发生了变化
管道-过滤器软件体系优点
- 并发性:对于海量数据处理问题,可以提高高通量的产出
- 可复用性:封装了过滤器,使得过滤器可以被非常容易地插入与替换
管道过滤器构成的网络,其输出的正确姓与过滤器的递增处理顺序无关
将每个过滤器的输入/输出限制为单一的,则管道-过滤器退化为顺序批处理系统
例如:
管道-过滤器优点
管道-过滤器缺点
3.顺序批处理系统与管道-过滤器软件体系结构的比较
4.控制
过程控制系统
三、基于事件的软件体系结构
计算机中,消息是具有特定含义的数据
事件:能够激活对象功能的动作。当发生这种动作后将给所涉及对象发送一个消息,对象便可执行相应的功能
显式调用
隐式调用
隐式调用的应用:事件系统
1.事件系统软件体系结构的概念
事件系统构成原理
事件系统的连接机制
- 连接件:事件-过程绑定
- 过程<事件处理器,事件的接收和处理方>向特定的事件进行注册
- 构件<事件源>发布事件
- 当某些事件被发布时,向其注册的过程被隐式调用
- 调用的次序是不确定的
例如:
事件系统调度策略
1.带有分离的派遣模块的事件管理器
事件派遣模块
功能:负责接收到来的事件并派遣它们到其他模块
派遣方式:1.广播式:派遣模块将事件广播到所有的模块,但只有感兴趣的模块才去取事件,并触发自身的行为
2.选择广播式:派遣模块将事件送到那些已经注册了的模块中
选择广播式的两种策略
- Point-to-Point(点对点模式):基于消息队列
- Publish-Subscribe(发布-订阅模式)
2.没有中心派遣模块的事件管理器
- 这种模式被称为==“被观察者/观察者”==
- 每一个模块都允许其他模块向自己所发送的某些消息表明兴趣
- 当某一模块发出某一事件时,它自动将这些事件发布给那些曾经向自己注册过此事件的模块
观察者模式的组成
- Observable:被观察者接口,声明了三个应该实现的方法。在简单的情况下,register(obs:Observer) 方法负责将参数中的观察者注册到Subject对象,在Subject对象中保持一个具体的观察者列表,用于记载所有的观察者。unRegister(obs:Observer) 方法用于在列表中删除参数中观察者对象。Notify() 方法用于通知观察者subject状态的改变。
- Subject:具体的观察者要依赖的对象,它要实现Observable的所有方法。在Subject中的getState() 方法可以被ConcreteObserver调用,以便得到最新的状态。
- Observer:观察者接口,代表依赖对象。观察者可以有多个。
- ConcreteObserver:代表具体的观察者对象。
关于setChanged
分为两种情况
1.传统模式
在传统模式中,Observable是接口,方法是可以自己定义的,一般来说就三个方法,注册,取消注册,通知
2.Java API模式
在传统模式中,Observable是抽象类,setChanged是必须的,而且是用来设置一个 boolean 类型的内部标志位,注明目标对象发生了变化。当它为真时,notifyObservers() 才会通知观察者。一般来说,也是三个方法,注册,改变状态,通知
四、层次软件体系结构
层次之间存在接口,通过接口形成call/return的关系,上层是下层的客户端
层次体系结构包括但不限于下述典型的应用领域:
- 层次通信协议
- 数据库系统领域
- 操作系统领域
层次系统的基本构件:
- 各层次内部包含的构件
连接件:
- 层间的交互协议
拓扑结构:
- 分层
拓扑约束:
- 对相邻层间交互的约束
分层模式:
-
严格分层
-
松散分层
层间交互方式:
1.由上而下的交互方式
2.由下而上的交互方式
两种方式的区别
层次软件体系结构的优点
1.支持逐层抽象的系统设计
2.支持更新
3.支持复用
4.支持测试
层次软件体系结构的缺点
1.并不是每个系统都可以很容易地划分为分层的模式
2.效率降低
3.很难找到合适的、正确的层次抽象方法
典型层次软件体系结构
![]() | ![]() | ![]() |
---|
五、MVC软件体系结构
MVC体系结构将一个互动的应用分为三部分:Model、View、Controller。
Model:包含核心功能与数据
View:为用户显示信息
Controller:处理用户输入
MVC体系结构的一般形式
应用观察者机制的MVC体系结构设计类图
MVC软件体系结构的优点
MVC软件体系结构的缺点
三层体系结构与MVC软件体系结构的比较