14.3.3结构型GOF设计模式实用实例
结构型模式通过类和对象的组合以获得更大的结构,采用继承机制来组合接口或实现。
1、Facade 设计模式
(1)意图
外观(Facade)设计模式属于对象结构型设计模式,Facade设计模式定义了一个高层接口,使得子系统更加容易使用,利用Facade设计模式可以为子系统中的一组接口提供一个一致的界面,可以降低系统中各部分之间的相互依赖关系,同时增加系统的灵活性。
(2)结构
图14.8给出了Facade设计模式的一般结构
(3) Facade设计模式的特点
①对于Client来说屏蔽了子系统中的类,因此减少了Client需要有接处理的对象,使得子系统更容易被使用。
②降低了Client和子系统之间的耦合度
③有助于对象间依赖关系的分层,建立具有层次结构的系统
④子系统中的类不需要了解关于Client的知识,也不需要了解关于Facade类的知识,即没有指向Client和Facade的引用
⑤如果需要 Client也可以直接存取子系统中的类
(4)适用性
①为复杂系统提供一个简单的接口
②构建层次结构系统时,适用Facade模式定义每层的人口点
③采用Facade模式可以将子系统与客户程序分离,提高子系统的可以移植性。
2、Facade设计模式的应用举例
在实际的应用系统中,一个字系统可以由很多类组成,子系统的客户为了它们的需要,需要和子系统中的一些类进行交互,客户和子系统的类进行直接交互会导致客户机对象和子系统间高度耦合,任何对子系统中类的接口的修改,会对依赖于它的所有的客类造成影响,图14.9给出了客户与子系统类交互示意图
外观模式(Facade Pattetn) 为子系统提供了一个更高层,更简单的接口。从而降低了子系统的复杂度和依赖,使得子系统更易于使用和管理。
外观是一个能为子系统和客户提供简单接口的类,正确地应用外观模式,客户不再直接和子系统的类交互,而是与外观交承担与子系统中类交互的责任,实际上外观是子系统与客户的接口这样外观模式降低了子系统和客户的耦合度,图14.10给出了使用Facade模式客户与子系统交互的示意图n从图14.10可知,外观对象隔离了客户和子系统对象,从而降低耦合度。
建立一个应用要求
(1)接收客户的详细子类(账户、地址和信用卡信息)
(2)验证输入的信息
(3)保存输入的信息到相应的文件中
这个应用有3个类:Account、Address和Creditcard每个类都有自己的验证和保存数据的方法,这3个类组成的子系统提供确认和保存顾客数据必要的功能,图14.11给出了这3个类的类图
建立一个客户Account Manager,它提供用户输入数据的用户界面,为了验证和保存输入的数据,客户Account Manager需要
(1)建立:Account、Address和Creditcard对象
(2)用这些对象验证输入的数据
(3)用这些对象保存输入的数据
应用外观模式:定义一个外观类:Customer Facade 它为由客户数据处理类:Caddress、Account和Credit Card所组成的子系统提供一个高层次的简单的接口,Customer Facade的类图如图14.12所示
Customer Facade类以Save Customer Data方法的形成提供了业务层次上的服务,客户Account Manager不是直接和子系统的每一个构件交互而是 使用了由Custom Facade对象提供了验证和保存客户数据的更高层次,更简单的接口、如图14.13所示
在新的设计中为了验证和保存客户数据,客户需要:
(1) 建立获得外观对象,CustomerFacade的一个实例
(2)传递数据给CustomerFacade实例进行验证和保存
(3)调用CustomerFacade实例上的Save Customer Data方法
应用外观模式的注意事项如下
(1)在设计外观时,不需要增加额外的功能
(2)不要从外观方法中返回子系统中的构件给客户
(3)应用外观的目的是提供一个高层次的接口,因此外观模式最适合提供特定的高层次的业务,而不是进行底层的单独业务执行
13.3.4行为型GOF设计模式应用实例
行为模式主要描述算法和对象之间的关联模式。
1、Chain of Responsibility(职责链)设计模式
(1)意图
该模式使多个对象都有机会处理请求,并使用这些对象之间保持松耦合的关系
(2)结构
图14.14给出了Chain of Responsibility设计模式的一般结构
(3) Chain of Responsibility设计模式的特点
①职责链是一种可应用于许多具体领域的行为模式,这个模式处理一组对象和一个请求之间的关系
②当一个请求可以被多个对象处理时就可以运用这个模式
③链中的第一个对象获得请求,解决它或者把请求传递到链中的下一个对象,直到有个一个对象可以解决请求,这个传递才会停止。
④最初发出请求的对象并不知道它所发出的请求是被哪个对象处理的,最终处理请求的对象被称为隐含接收者(lmplilit Receiver)
(4)使用性
①有多个对象可以处理一个请求,处理请求的具体时刻可以自动确定
②可以在不明确指定接收者的情况,不向多个对象中的一个提交一个请求
③可以动态修改处理相应请求的对象集合
2、Chain of Responsibility设计模式的应用聚集(Web浏览器事件模型)
在开发交互式Web页面(Web Page)时设计者必须要考虑浏览器刚刚被打开时的事件模型,对于IE可以编写JAVAScript或者VBscript代码来响应诸如鼠标单击这样的事件,这段代码被称为一个事件处理器(Event Handler)它说明了如果有用户鼠标单击事件发生后,Web页面如何做出响应
在一个HTML文档(Document)中一个页面被分为一些被称作Div的区域,每个Div还被进一步分为几个表单(Form)可以将一个按钮(Button)放置在一个表单中,上面划分的每个元素都是HTML文档的构件,某些构件还可以成为其他构件的构件,GOF整理的模式中包括组成模式(Composite pattern)并说明了组成模式通常要和职责链模式共同使用。构件一组成关系实施了职责链中前驱和后继之间的链接,在职责链模式的类结构图中,在一定语境中,对象自己指定如何寻找该对象的后继对象。
当在一个DIV中的某个表单中安放一个按钮,并且Div所在的HTML文档被IE打开时,按下按钮就触发了按钮点击事件消息先被发送给表单对象,接着被发送给表单对象所在的Div对象最后被发送给Div所在的文档对象,这些可能接收消息的每个文档元素对象都有自己的事件处理器来响应按钮点击事件。
图14.15显示了事件模型中的类图
图14.16用参数化协作表示应用于IE事件模型的设计模式
这种模式叫做事件转发(Event Bubbling)
在图14.16中,引出虚线的椭圆代表了设计模式中的协作,椭圆图中为模式的名称,模式外围的矩形代表了协作的参与者对象,带箭头的依赖关系表示合作要依赖于参与协作的对象,依赖关系线上的标签说明被依赖的,参与协作的对象在模式中所担当的角色,协作的参数化是通过在模式中使用特定领域的类名来表达的。
本章小结
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格及解决问题的思考方式。使用设计模式是为了重用已有的设计经验、框架、代码、以便让代码更容易被他人理解,保证代码可靠性。对设计模式的理解和掌握是程序提供自身素质的一个很好的方面。
GRASP模式着重考虑设计类的原则及如何分配类的功能,而GOF模式着重考虑设计的实现、类的交互和软件质量。GRASP可以说是GOF设计模式的基础,GOF模式是符合GRASP模式要求的面向对象设计模式。GOF设计模式针对特定问题提出相应解决方法,是目前常用的设计模式之一。
本章主要介绍设计模式的基本概念和发展GRASP设计模式和GOF设计模式的概念及其分类,并给出典型的应用实例,目的是使读者掌握设计模式的基本理论及应用设计模式解决软件设计中的实际问题的方法。