其主要思想是:将一个复杂的大系统分解为一些子系统,以便降低复杂度,并且增加可修改性。
调用-返回风格体系结构可以被组织成任何形式。但层次结构的组织形式更清晰
层次结构的设计被称为共享数据的主程序-子程序软件体系结构
主程序-子程序软件体系结构在设计上使用层次化的划分方法,该体系结构中使用由编程语言直接支持的单一的控制线程。
子程序的结构是明确的,子程序通常组成程序模块。子程序的调用呈现层次状,其正确与否往往取决于其调用的子程序的正确与否。
相比于非结构化编程,主程序-子程序软件体系结构能够较好地支持系统的可改变性和可伸缩性等性能,其采用分而治之的策略
功能演化困难
现实中的系统功能不容易描述
功能化设计丢掉了数据与数据结构
由功能设计得到的软件产品的可复用的代码较少
优点
缺点
封装性
继承性
多态
优点
缺点
在数据流风格体系结构中的组件是可以被重复使用的,且在保证输入与输出接口都不变的情况下,可以独立修改一个组件,而不影响其他的组件。
注意同步问题
Batch Sequential(批处理)
Pipe-and-Filter(管道-过滤器)
Process Control(控制)
在该系统中,组件为独立的程序,并且这些组件按照先后顺序处理,即只有当一个组件的运行彻底结束以后,下一个组件才能开始执行。可以认为,数据在处理步骤之间的传输是成批(块)的,而不是以数据流的方式进行的。这也是"顺序批处理"名称的由来。
在管道-过滤器软件体系结构中,每个组件都有一组输入和输出,组件读入输入数据流,经过数据处理,然后产生输出数据流。
在输入被完全消费之前,输出便产生了
组件被称为过滤器,这种风格的连接件就像是数据流传输的管道
过滤器三个部分组成
管道的三个组件
作用:在过滤器之间传送数据
单向流
可能具有缓冲区
管道形成传输图
不同的管道中流动的数据流,具有不同的数据格式
原因:数据在流过每一个过滤器时,被过滤器进行了丰富、精炼、转换、融合、分解等操作,因而发生了变化
并发性:对于海量数据处理问题,可以提高高通量的产出
可复用性:封装了过滤器,使得过滤器可以被非常容易地插入与替换
将每个过滤器的输入/输出限制为单一的,则管道-过滤器退化为顺序批处理系统(Batch sequential)
管道过滤器构成的网络,其输出的正确姓与过滤器的递增处理顺序无关
不适合于需要共享大量数据的应用设计。
不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重;
c、每个方法的功能:
Filter类:setInPipe()和setOutPipe()负责设置输入输出管道,Start()和Stop()负责控制过滤器开始工作和暂停工作;
Filter类的子类:processData()负责实现每个子类对应的功能;
Pipe类:read()和write()实现数据的读取与写入,close()实现流的关闭。
c、每个方法的功能:
Filter类:setInPipe()和setOutPipe()负责设置输入输出管道,Start()和Stop()负责控制过滤器开始工作和暂停工作;
Filter类的子类:processData()负责实现每个子类对应的功能;
Pipe类:read()和write()实现数据的读取与写入,close()实现流的关闭。
计算机中,消息是具有特定含义的数据
事件:能够激活对象功能的动作。当发生这种动作后将给所涉及对象发送一个消息,对象便可执行相应的功能
隐式调用将调用者与被调用者解耦,调用者可以不知道谁是被调用者。也不知道调用后的后果如何。
连接件:事件-过程绑定
过程<事件处理器,事件的接收和处理方>向特定的事件进行注册
构件<事件源>发布事件
当某些事件被发布时,向其注册的过程被隐式调用
调用的次序是不确定的
在某些情况下,一个事件也可能触发其他事件,形成事件链。
这种连接机制成为“事件—事件绑定”。
事件派遣模块
功能:负责接收到来的事件并派遣它们到其他模块
派遣方式:
1.广播式:派遣模块将事件广播到所有的模块,但只有感兴趣的模块才去取事件,并触发自身的行为
关于setChanged
分为两种情况
1.传统模式
在传统模式中,Observable是接口,方法是可以自己定义的,一般来说就三个方法,注册,取消注册,通知
2.Java API模式
在传统模式中,Observable是抽象类,setChanged是必须的,而且是用来设置一个 boolean 类型的内部标志位,注明目标对象发生了变化。当它为真时,notifyObservers() 才会通知观察者。一般来说,也是三个方法,注册,改变状态,通知
当调用Observable类的notifyObserver之前,还应该同时调用什么方法?
在调用Observable类的notifyObserver
方法之前,应该先调用setChanged
方法。
setChanged
方法是Observable类的一个方法,用于设置对象的状态已经改变。它会将Observable对象的changed
字段设置为true,表示对象的状态已经发生了改变。
在观察者模式中,当被观察对象的状态发生改变时,需要先调用setChanged
方法来标记状态已经改变,然后再调用notifyObserver
方法通知所有观察者。这样做的目的是确保只有当状态发生改变时才会通知观察者,避免不必要的通知。
因此,在调用notifyObserver
方法之前,应该先调用setChanged
方法来设置对象的状态已经改变。这样可以确保观察者能够正确地接收到状态改变的通知。
2、解释:
Observable和Observer为接口类,FishbowlGUI为被观察类(实现Observable接口),ChemistryGUI、TemperatureGUI、LevelGUI为观察者类(实现Observer接口)。
FishbowlGUI有3个私有变量quality、temperature和level,分别代表鱼缸的水质、水温和水位高度,每个私有变量都有其对应的get和set方法。
三个观察者类都要实现takeAction(Observable s)方法,每个类实现该方法的方式不同:
该方法通过参数传入一个被观察者对象,当得到通知后,将对被观察者类FishbowlGUI的某些方法进行调用,以便获取变化的状态。
2、AirportInfo类三个方法的功能:
3、update方法的参数:
4、具体行为:
5、工作原理:
层次之间存在接口,通过接口形成call/return的关系,上层是下层的客户端
层次系统的基本构件:
各层次内部包含的构件
连接件:
层间的交互协议
拓扑结构:
分层
1.支持逐层抽象的系统设计
2.支持更新
3.支持复用
4.支持测试
1.并不是每个系统都可以很容易地划分为分层的模式
2.效率降低
3.很难找到合适的、正确的层次抽象方法
指出层次软件体系结构的三个典型应用。
MVC体系结构将一个互动的应用分为三部分:Model、View、Controller。Model包含核心功能与数据,View为用户显示信息,Controller处理用户输入。
根据责任分离与增加可扩展性的原则,Model应该被设计成独立于特定的输入行为和输出表示的程序。
View模块将模型中的数据显示给用户。而因为相同的数据可以有不同形式的显示方法,所以一个Model可以有很多个View
模型的责任
视图的责任
控制器的责任
MVC(Model-View-Controller)既是一种设计模式,又是一种软件体系结构。
作为设计模式,MVC旨在解决用户界面和应用程序逻辑之间的分离问题。它将应用程序分为三个主要组件:模型(Model)、视图(View)和控制器(Controller)。模型负责处理应用程序的数据和业务逻辑,视图负责呈现数据给用户,而控制器负责处理用户输入和协调模型与视图之间的交互。
作为软件体系结构,MVC定义了应用程序的整体结构和组织方式。它提供了一种分层的方式来组织和管理应用程序的各个部分。模型、视图和控制器作为独立的组件存在,并通过定义明确的接口和协议进行通信,实现了松耦合和高内聚的设计。
因此,MVC既是一种设计模式,用于解决特定的设计问题,又是一种软件体系结构,用于组织和管理整个应用程序的结构。它在软件开发中被广泛应用,并具有可扩展性和可维护性等优点。
将观察者类中的更新方法的参数类型设为Observable
,可以使观察者能够获取到被观察对象的具体信息和状态,从而能够根据实际情况作出相应的处理。这样做的好处包括:
获取被观察对象的状态: 通过将参数类型设为Observable
,观察者可以获取到被观察对象的状态信息。这使得观察者能够及时获知被观察对象的更新内容,从而根据具体的状态进行相应的处理。
实现多态性: 通过使用Observable
作为参数类型,观察者可以接收任何符合Observable
接口的具体实现类的对象。这种多态性的设计使得观察者能够适用于不同类型的被观察对象,而不需要修改观察者类的代码。这增强了代码的灵活性和可扩展性。
降低耦合度: 通过使用Observable
作为参数类型,观察者与被观察对象之间的耦合度降低。观察者不需要依赖具体的被观察对象类,只需要依赖于通用的Observable
接口。这种松耦合的设计使得观察者能够更加独立、可复用和可测试。
总而言之,将观察者类中的更新方法的参数类型设为Observable
使得观察者能够获取被观察对象的具体信息和状态,实现多态性,降低耦合度,从而提高了系统的灵活性、可扩展性和可维护性。
两层客户端-服务器体系结构是一种常见的软件架构模式,它由两个主要组成部分组成:客户端和服务器。每个组件都有特定的功能和职责。
客户端层:
服务器层:
在这种体系结构下,程序的工作原理如下: