目录
- 软件体系结构概述
- 一、调用-返回风格软件体系结构
- 概念
- 主程序-子程序软件体系结构
- 自顶向下的设计方法的问题
- 结构化设计的优缺点
- 面向对象体系结构
- 面向对象设计的优缺点
- 主程序-子程序与面向对象体系结构
- 相似
- 差异
- 课程作业
- 二、数据流风格软件体系结构
- 概念
- 控制流 vs. 数据流
- 数据流风格三种例子
- Batch Sequential(批处理)
- 批处理系统特点
- 批处理系统案例:数字图像处理软件
- Pipe-and-Filter(管道-过滤器)
- 过滤器
- 管道
- 管道-过滤器软件体系优点
- 案例分析:主动型过滤器实例
- 类图
- 案例分析:设计遗产文件更新系统
- 案例分析:数字图像处理系统
- 顺序批处理系统与管道-过滤器软件体系结构的比较
- Process Control(控制)
- 作业
- 三、基于事件的软件体系结构
- 显式调用
- 隐式调用
- 事件系统软件体系结构的概念
- 事件系统的连接机制
- 例子:图形用户界面
- 事件系统调度策略
- 1.带有分离的派遣模块的事件管理器
- 观察者模式
- 类图
- 观察者模式应用实例
- 课程作业
- 四、层次软件体系结构
- 两种方式的区别
- 双向分层
- 分层风格 VS 主程序-子过程风格:二者的不同
- 层次软件体系结构的优点
- 层次软件体系结构的缺点
- 课程作业
- 五、MVC软件体系结构
- MVC软件体系结构的概念与机制
- MVC模型各部分功能
- MVC的改变--传播机制
- MVC软件体系结构的概念与机制(类图)
- 使用观察者模式的MVC体系结构设计类图
- MVC软件体系结构应用实例
- 优缺点
- 三层体系结构与MVC 软件体系结构的比较
- 课程作业
- MVC是一种设计模式还是一种软件体系结构?(***)
- 画图
- 课程作业
软件体系结构概述
- 调用-返回风格软件体系结构
- 数据流风格软件体系结构
- 基于事件的软件体系结构
- 层次软件体系结构
- MVC软件体系结构
一、调用-返回风格软件体系结构
其主要思想是:将一个复杂的大系统分解为一些子系统,以便降低复杂度,并且增加可修改性。
概念
- 每个软件构件都设计为有一个唯一的程序执行起点和一个唯一的程序执行终点;
- 程序从其执行起点开始执行该构件的代码,程序执行结束,将控制返回给程序调用构件,
- 其中,程序构件通常叫做子程序,
- 从一个构件到另外一个构件的控制传递叫做子程序调用。
调用-返回风格体系结构可以被组织成任何形式。但层次结构的组织形式更清晰
层次结构的设计被称为共享数据的主程序-子程序软件体系结构
主程序-子程序软件体系结构
主程序-子程序软件体系结构在设计上使用层次化的划分方法,该体系结构中使用由编程语言直接支持的单一的控制线程。
子程序的结构是明确的,子程序通常组成程序模块。子程序的调用呈现层次状,其正确与否往往取决于其调用的子程序的正确与否。
相比于非结构化编程,主程序-子程序软件体系结构能够较好地支持系统的可改变性和可伸缩性等性能,其采用分而治之的策略
自顶向下的设计方法的问题
功能演化困难
现实中的系统功能不容易描述
功能化设计丢掉了数据与数据结构
由功能设计得到的软件产品的可复用的代码较少
结构化设计的优缺点
优点
- 逻辑设计与物理设计分离
- 开发过程中形成一套规范化的文档,便于将来修改和维护
缺点
- 开发周期长,开发过程复杂
- 系统难于适应环境变化
- 经验表明,较小的程序(小于10万行)适合于结构化开发
面向对象体系结构
封装性
继承性
多态
面向对象设计的优缺点
优点
- 容易维护
- 可复用性好
- 映射现实世界
- 容易对一个系统进行剖分
缺点
- 面向对象程序占用内存较大
- 一个对象要和另外一个对象交互,该对象必须知道另外一个对象的身份,包括对象名、方法名和参数类型等。
主程序-子程序与面向对象体系结构
相似
差异
课程作业
结构化设计、面向对象设计
结构图、
二、数据流风格软件体系结构
概念
- 数据流系统的各软件组件在无数据到达时处于休眠状态,当有数据到达时,该软件组件被激活,开始对数据进行处理。
- 数据流风格软件体系结构将整个软件系统看作由一系列作用在连续数据集合上的“变换”组成。数据和作用于其上的操作是互相独立的。
- 软件系统被分解为一些数据处理单元或称为组件,数据流控制数据处理顺序。
在数据流风格体系结构中的组件是可以被重复使用的,且在保证输入与输出接口都不变的情况下,可以独立修改一个组件,而不影响其他的组件。
注意同步问题
控制流 vs. 数据流
数据流风格三种例子
Batch Sequential(批处理)
Pipe-and-Filter(管道-过滤器)
Process Control(控制)
Batch Sequential(批处理)
在该系统中,组件为独立的程序,并且这些组件按照先后顺序处理,即只有当一个组件的运行彻底结束以后,下一个组件才能开始执行。可以认为,数据在处理步骤之间的传输是成批(块)的,而不是以数据流的方式进行的。这也是"顺序批处理"名称的由来。
批处理系统特点
- 每个处理程序模块都是互为独立的程序
- 只有上一步程序彻底完成,下一步程序才能开始
- 数据作为一个整体进行传输
- 因为以上的特点,所以不必对其组件进行同步处理
- 因为几个组件只能按照顺序运行,而不能同步运行,所以性能可能比那些能按照几个组件同时运行的程序要差一些
- 使用顺序批处理结构设计的软件不适用于要求对数据进行实时处理的系统
批处理系统案例:数字图像处理软件
Pipe-and-Filter(管道-过滤器)
在管道-过滤器软件体系结构中,每个组件都有一组输入和输出,组件读入输入数据流,经过数据处理,然后产生输出数据流。
在输入被完全消费之前,输出便产生了
组件被称为过滤器,这种风格的连接件就像是数据流传输的管道
过滤器
过滤器三个部分组成
- Input Port 负责存储待处理的数据
- Filter 负责处理数据
- Output Port 负责存储已经处理完的数据
管道
管道的三个组件
- Input Stream 输入流
- Pipe 管道
- Output Stream 输出流
作用:在过滤器之间传送数据
单向流
可能具有缓冲区
管道形成传输图
不同的管道中流动的数据流,具有不同的数据格式
原因:数据在流过每一个过滤器时,被过滤器进行了丰富、精炼、转换、融合、分解等操作,因而发生了变化
管道-过滤器软件体系优点
并发性:对于海量数据处理问题,可以提高高通量的产出
可复用性:封装了过滤器,使得过滤器可以被非常容易地插入与替换
将每个过滤器的输入/输出限制为单一的,则管道-过滤器退化为顺序批处理系统(Batch sequential)
管道过滤器构成的网络,其输出的正确姓与过滤器的递增处理顺序无关
案例分析:主动型过滤器实例
类图
案例分析:设计遗产文件更新系统
案例分析:数字图像处理系统
不适合于需要共享大量数据的应用设计。
不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重;
顺序批处理系统与管道-过滤器软件体系结构的比较
Process Control(控制)
作业
a、逻辑图:
b、设计类图:
c、每个方法的功能:
Filter类:setInPipe()和setOutPipe()负责设置输入输出管道,Start()和Stop()负责控制过滤器开始工作和暂停工作;
Filter类的子类:processData()负责实现每个子类对应的功能;
Pipe类:read()和write()实现数据的读取与写入,close()实现流的关闭。
a、逻辑图:
b、设计类图:
c、每个方法的功能:
Filter类:setInPipe()和setOutPipe()负责设置输入输出管道,Start()和Stop()负责控制过滤器开始工作和暂停工作;
Filter类的子类:processData()负责实现每个子类对应的功能;
Pipe类:read()和write()实现数据的读取与写入,close()实现流的关闭。
三、基于事件的软件体系结构
计算机中,消息是具有特定含义的数据
事件:能够激活对象功能的动作。当发生这种动作后将给所涉及对象发送一个消息,对象便可执行相应的功能
显式调用
隐式调用
隐式调用将调用者与被调用者解耦,调用者可以不知道谁是被调用者。也不知道调用后的后果如何。
事件系统软件体系结构的概念
事件系统的连接机制
连接件:事件-过程绑定
过程<事件处理器,事件的接收和处理方>向特定的事件进行注册
构件<事件源>发布事件
当某些事件被发布时,向其注册的过程被隐式调用
调用的次序是不确定的
在某些情况下,一个事件也可能触发其他事件,形成事件链。
这种连接机制成为“事件—事件绑定”。
例子:图形用户界面
事件系统调度策略
1.带有分离的派遣模块的事件管理器
事件派遣模块
功能:负责接收到来的事件并派遣它们到其他模块
派遣方式:
1.广播式:派遣模块将事件广播到所有的模块,但只有感兴趣的模块才去取事件,并触发自身的行为
2.选择广播式:派遣模块将事件送到那些已经注册了的模块中
观察者模式
类图
- Observable:被观察者接口,声明了三个应该实现的方法。在简单的情况下,2. 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() 才会通知观察者。一般来说,也是三个方法,注册,改变状态,通知
观察者模式应用实例
课程作业
当调用Observable类的notifyObserver之前,还应该同时调用什么方法?
在调用Observable类的notifyObserver
方法之前,应该先调用setChanged
方法。
setChanged
方法是Observable类的一个方法,用于设置对象的状态已经改变。它会将Observable对象的changed
字段设置为true,表示对象的状态已经发生了改变。
在观察者模式中,当被观察对象的状态发生改变时,需要先调用setChanged
方法来标记状态已经改变,然后再调用notifyObserver
方法通知所有观察者。这样做的目的是确保只有当状态发生改变时才会通知观察者,避免不必要的通知。
因此,在调用notifyObserver
方法之前,应该先调用setChanged
方法来设置对象的状态已经改变。这样可以确保观察者能够正确地接收到状态改变的通知。
1、设计类图:
2、解释:
Observable和Observer为接口类,FishbowlGUI为被观察类(实现Observable接口),ChemistryGUI、TemperatureGUI、LevelGUI为观察者类(实现Observer接口)。
FishbowlGUI有3个私有变量quality、temperature和level,分别代表鱼缸的水质、水温和水位高度,每个私有变量都有其对应的get和set方法。
三个观察者类都要实现takeAction(Observable s)方法,每个类实现该方法的方式不同:
- 当quality超过特定范围时,化学传感器ChemistryGUI排除鱼缸部分废水,补充新水;
- 当temperature低于或高于特定温度时,TemperatureGUl开启加热设备或者冷却设备调整水温;
- 当level高于或低于特定高度时,LevelGUI开启排水设备,排除部分水或者添加新鲜的水。
该方法通过参数传入一个被观察者对象,当得到通知后,将对被观察者类FishbowlGUI的某些方法进行调用,以便获取变化的状态。
1、设计类图:
2、AirportInfo类三个方法的功能:
- AddObserver(Observer obs)方法,将多个观察者添加到被观察者的observerList中,以便在通知观察者时使用;
- setChanged()和notifyObservers(),通知观察者被观察者对象的状态已经改变,同时会运行观察者对象的update()方法。执行顺序为:setChanged()先执行,notifyObservers()后执行。
3、update方法的参数:
- 第一个参数为Observable类型,代表被观察者对象;
- 第二个参数为Object类型,代表发生的事件,Object为被观察者的一种状态值,提供给update()方法,以便更新观察者。
4、具体行为:
- VoiceInfo类的update()方法完成的工作是从AirportInfo类获取语音机场信息,然后将这些信息发送给乘客;
- DisplayInfo类的update()方法负责从AirportInfo类获取文字机场信息,然后将这些信息显示在屏幕上。
5、工作原理:
- 被观察者AirportInfo有一个observerList(ArrayList类型)成员变量,用于记载动态添加的观察者。
- 对被观察者状态感兴趣的对象(观察者)VoiceInfo和DisplayInfo,应该调用被观察者的addObserver()方法将自己注册为它的一个观察者。
- 每当AiportInfo的状态发生改变时,它将调用setChanged()方法和notifyObservers()方法(通知已经注册的观察者VoiceInfo和DisplayInfo)。
- 接收到通知以后,VoiceInfo和DisplayInfo都将查询AirportInfo的状态,以便保持状态同步。根据新的状态,VoiceInfo和DisplayInfo将分别调用update()方法执行相关操作。
四、层次软件体系结构
层次之间存在接口,通过接口形成call/return的关系,上层是下层的客户端
层次系统的基本构件:
各层次内部包含的构件
连接件:
层间的交互协议
拓扑结构:
分层
拓扑约束:
对相邻层间交互的约束
两种方式的区别
双向分层
分层风格 VS 主程序-子过程风格:二者的不同
层次软件体系结构的优点
1.支持逐层抽象的系统设计
2.支持更新
3.支持复用
4.支持测试
层次软件体系结构的缺点
1.并不是每个系统都可以很容易地划分为分层的模式
2.效率降低
3.很难找到合适的、正确的层次抽象方法
课程作业
指出层次软件体系结构的三个典型应用。
- 网络体系结构
- 操作系统
- 应用开发
五、MVC软件体系结构
MVC软件体系结构的概念与机制
MVC体系结构将一个互动的应用分为三部分:Model、View、Controller。Model包含核心功能与数据,View为用户显示信息,Controller处理用户输入。
根据责任分离与增加可扩展性的原则,Model应该被设计成独立于特定的输入行为和输出表示的程序。
View模块将模型中的数据显示给用户。而因为相同的数据可以有不同形式的显示方法,所以一个Model可以有很多个View
MVC模型各部分功能
模型的责任
- 从数据库取出数据,并且赋予数据变量
- 负责业务逻辑实现
- 负责数据验证,然后将数据存入数据库
视图的责任
- 获取用户输入
- 向controller发送处理请求
- 接收来自Controller的反馈并将model的处理结果显示给用户
控制器的责任
- 接收来自客户的请求
- 调用model业务逻辑方法
- 调用View显示执行结果
MVC的改变–传播机制
MVC软件体系结构的概念与机制(类图)
使用观察者模式的MVC体系结构设计类图
MVC软件体系结构应用实例
优缺点
三层体系结构与MVC 软件体系结构的比较
课程作业
MVC是一种设计模式还是一种软件体系结构?(***)
MVC(Model-View-Controller)既是一种设计模式,又是一种软件体系结构。
作为设计模式,MVC旨在解决用户界面和应用程序逻辑之间的分离问题。它将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。模型负责处理应用程序的数据和业务逻辑,视图负责呈现数据给用户,而控制器负责处理用户输入和协调模型与视图之间的交互。
作为软件体系结构,MVC定义了应用程序的整体结构和组织方式。它提供了一种分层的方式来组织和管理应用程序的各个部分。模型、视图和控制器作为独立的组件存在,并通过定义明确的接口和协议进行通信,实现了松耦合和高内聚的设计。
因此,MVC既是一种设计模式,用于解决特定的设计问题,又是一种软件体系结构,用于组织和管理整个应用程序的结构。它在软件开发中被广泛应用,并具有可扩展性和可维护性等优点。
将观察者类中的更新方法的参数类型设为Observable
,可以使观察者能够获取到被观察对象的具体信息和状态,从而能够根据实际情况作出相应的处理。这样做的好处包括:
-
获取被观察对象的状态: 通过将参数类型设为
Observable
,观察者可以获取到被观察对象的状态信息。这使得观察者能够及时获知被观察对象的更新内容,从而根据具体的状态进行相应的处理。 -
实现多态性: 通过使用
Observable
作为参数类型,观察者可以接收任何符合Observable
接口的具体实现类的对象。这种多态性的设计使得观察者能够适用于不同类型的被观察对象,而不需要修改观察者类的代码。这增强了代码的灵活性和可扩展性。 -
降低耦合度: 通过使用
Observable
作为参数类型,观察者与被观察对象之间的耦合度降低。观察者不需要依赖具体的被观察对象类,只需要依赖于通用的Observable
接口。这种松耦合的设计使得观察者能够更加独立、可复用和可测试。
总而言之,将观察者类中的更新方法的参数类型设为Observable
使得观察者能够获取被观察对象的具体信息和状态,实现多态性,降低耦合度,从而提高了系统的灵活性、可扩展性和可维护性。
画图
课程作业
两层客户端-服务器体系结构是一种常见的软件架构模式,它由两个主要组成部分组成:客户端和服务器。每个组件都有特定的功能和职责。
-
客户端层:
- 胖客户端(Fat Client):在胖客户端架构中,客户端负责处理大部分的应用逻辑和数据处理。它具有丰富的用户界面和功能,能够在本地执行复杂的计算任务和数据处理。胖客户端通常需要在本地安装和运行较大的软件包。
- 瘦客户端(Thin Client):在瘦客户端架构中,客户端主要负责用户界面的显示和用户输入的收集,而应用逻辑和数据处理主要由服务器端完成。瘦客户端相对较轻量,它依赖于服务器提供的应用程序和数据,并通过网络与服务器进行通信和交互。
-
服务器层:
- 服务器:服务器是中央处理单元,负责接收来自客户端的请求并提供所需的服务和数据。服务器层包括应用程序和数据的存储、处理和管理。它负责执行复杂的计算任务和数据操作,并将结果返回给客户端。
在这种体系结构下,程序的工作原理如下:
- 客户端向服务器发送请求,请求可能包括用户输入、数据查询等。
- 服务器接收到请求后,根据请求的类型和内容,进行相应的数据处理和计算,并生成响应结果。
- 服务器将响应结果发送回客户端。
- 客户端接收到服务器的响应结果后,根据需要进行界面的更新和显示,同时可能会涉及进一步的用户操作。
- 这个过程可能会在客户端和服务器之间进行多次交互,直到完成所需的任务。