Java程序设计模式之中介者模式Word格式文档下载.docx
《Java程序设计模式之中介者模式Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《Java程序设计模式之中介者模式Word格式文档下载.docx(11页珍藏版)》请在冰点文库上搜索。
统一管理对象间的交互。
但也可能使得Mediator对象成为一个系统中的庞然大物,难以维护
使用场景:
集中负责维护对象模型的关系完整性以及需要封装对象间交互方式的时候.
其实MVC中的controller就是一种Mediator,是UI层和后端应用sevice层间的中介者。
中介者将交互的复杂性变为中介者的复杂性
一.定义
用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
二.角色
抽象中介者:
定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。
一般包括一个或几个抽象的事件方法,并由子类去实现。
中介者实现类:
从抽象中介者继承而来,实现抽象中介者中定义的事件方法。
从一个同事类接收消息,然后通过消息影响其他同时类。
同事类:
如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。
在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。
同事类越多,关系越复杂。
并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。
在中介者模式中,同事类之间必须通过中介者才能进消息传递。
三.适用环境
(1)一组对象以定义良好但是复杂的方式进行通信。
产生的相互依赖关系结构混乱且难以理解。
(2)一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
(3)想定制一个分布在多个类的行为,而又不想生成太多的子类。
四.模式动机
在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题:
系统结构复杂:
对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理。
对象可重用性差:
由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱。
系统扩展性低:
增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作很不灵活,扩展性差。
五.模式结构
中介者模式包含如下角色:
(1)抽象中介者(Mediator)角色:
抽象中介者角色定义统一的接口用于各同事角色之间的通信。
(2)具体中介者(ConcreteMediator)角色:
具体中介者角色通过协调各同事角色实现协作行为。
为此它要知道并引用各个同事角色。
(3)同事(Colleague)角色:
每一个同事角色都知道对应的具体中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。
Mediator:
抽象中介者
ConcreteMediator:
具体中介者
Colleague:
抽象同事类
ConcreteColleague:
具体同事类
六.模式分析
中介者模式可以使对象之间的关系数量急剧减少:
(1)典型的抽象中介者类代码:
publicabstractclassMediator
{
protectedArrayListcolleagues;
publicvoidregister(Colleaguecolleague)
{
colleagues.add(colleague);
}
publicabstractvoidoperation();
(2)典型的具体中介者类代码:
publicclassConcreteMediatorextendsMediator
publicvoidoperation()
......
((Colleague)(colleagues.get(0))).method1();
(3)典型的抽象同事类代码:
publicabstractclassColleague
protectedMediatormediator;
publicColleague(Mediatormediator)
this.mediator=mediator;
publicabstractvoidmethod1();
publicabstractvoidmethod2();
(4)典型的具体同事类代码:
publicclassConcreteColleagueextendsColleague
publicConcreteColleague(Mediatormediator)
super(mediator);
publicvoidmethod1()
publicvoidmethod2()
mediator.operation1();
例子:
我们使用一个例子来说明一下什么是同事类:
有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。
也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。
类A类B互相影响,就称为同事类。
代码如下:
//抽象同事类
abstractclassAbstractColleague{
protectedAbstractMediatormediator;
//舍去在构造函数中建立起与中介者的联系
//publicAbstractColleague(AbstractMediatormediator){
//
this.mediator=mediator;
//}
//在抽象同事类中添加用于与中介者取得联系(即注册)的方法
publicvoidsetMediator(AbstractMediatormediator){
this.mediator=mediator;
}
//具体同事A
classColleagueAextendsAbstractColleague{
//舍去在构造函数中建立起与中介者的联系
//publicColleagueA(AbstractMediatormediator){
//
super(mediator);
//}
//每个具体同事必然有自己分内的事,没必要与外界相关联
publicvoidself(){
System.out.println("
同事A-->
做好自己分内的事情..."
);
}
//每个具体同事总有需要与外界交互的操作,通过中介者来处理这些逻辑并安排工作
publicvoidout(){
请求同事B做好分内工作..."
super.mediator.execute("
ColleagueB"
"
self"
}
//具体同事B
classColleagueBextendsAbstractColleague{
//舍去在构造函数中建立起与中介者的联系
//publicColleagueB(AbstractMediatormediator){
super(mediator);
//}
publicvoidself(){
同事B-->
}
publicvoidout(){
请求同事A做好分内工作
..."
ColleagueA"
//抽象中介者
abstractclassAbstractMediator{
//中介者肯定需要保持有若干同事的联系方式
protectedHashtable<
String,AbstractColleague>
colleagues=newHashtable<
();
//中介者可以动态地与某个同事建立联系
publicvoidaddColleague(Stringname,AbstractColleaguec){
//在中介者这里帮助具体同事建立起于中介者的联系
c.setMediator(this);
this.colleagues.put(name,c);
//中介者也可以动态地撤销与某个同事的联系
publicvoiddeleteColleague(Stringname){
this.colleagues.remove(name);
//中介者必须具备在同事之间处理逻辑、分配任务、促进交流的操作
publicabstractvoidexecute(Stringname,Stringmethod);
//测试类
publicclassClient{
publicstaticvoidmain(String[]args){
//创建一个中介者
AbstractMediatormediator=newMediator();
//不用构造函数为具体同事注册中介者来取得联系了
//ColleagueAcolleagueA=newColleagueA(mediator);
//ColleagueBcolleagueB=newColleagueB(mediator);
ColleagueAcolleagueA=newColleagueA();
ColleagueBcolleagueB=newColleagueB();
//中介者分别与每个同事建立联系
mediator.addColleague("
colleagueA);
colleagueB);
//同事们开始工作
colleagueA.self();
colleagueA.out();
======================合作愉快,任务完成!
\n"
colleagueB.self();
colleagueB.out();
"
}
七.优缺点
减少了子类。
Mediator将多个对象间的行为集中在一起,改变这些行为只需生成Mediator的子类即可,这样各个Colleague类可被重用。
它将各Colleague解耦。
Mediator有利于各Colleague间的松耦合,你可以独立的改变和复用各Colleague类和Mediator类。
它简化了对象协议。
用Mediator和各Colleague间的一对多的交互来代替多对多的交互。
一对多的关系更易于理解、维护和扩展。
它对对象如何协作进行了抽象。
将中介作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它们之间的交互上来。
这有助于弄清楚一个系统中的对象是如何交互的。
它使控制集中化,中介者模式将交互的复杂性变为中介者的复杂性。
因为中介者封装了协议,它可能变得比任一个
Colleague都复杂。
这可能使得中介者自身成为一个难于维护的庞然大物。
八.模式之间的比较:
由于中介者模式在定义上比较松散,在结构上和观察者模式、命令模式十分相像;
而应用目的又与结构模式“门面模式”有些相似。
在结构上,中介者模式与观察者模式、命令模式都添加了中间对象——只是中介者去掉了后两者在行为上的方向。
因此中介者的应用可以仿照后两者的例子去写。
但是观察者模式、命令模式中的观察者、命令都是被客户所知的,具体哪个观察者、命令的应用都是由客户来指定的;
而大多中介者角色对于客户程序却是透明的。
当然造成这种区别的原因是由于它们要达到的目的不同。
从目的上看,中介者模式与观察者模式、命令模式便没有了任何关系,倒是与前面讲过的门面模式有些相似。
但是门面模式是介于客户程序与子系统之间的,而中介者模式是介于子系统与子系统之间的。
这也注定了它们有很大的区别:
门面模式是将原有的复杂逻辑提取到一个统一的接口,简化客户对逻辑的使用。
它是被客户所感知的,而原有的复杂逻辑则被隐藏了起来。
而中介者模式的加入并没有改变客户原有的使用习惯,它是隐藏在原有逻辑后面的,使得代码逻辑更加清晰可用。
但是中介者角色集中了太多的责任,所有有关的同事对象都要由它来控制。
这不由得让我想起了简单工厂模式,但是由于中介者模式的特殊性——与业务逻辑密切相关,不能采用类似工厂方法模式的解决方法。
因此建议在使用中介者模式的时候注意控制中介者角色的大小。
讨论了这么多关于中介者模式的特点。
可以总结出中介者模式的使用时机:
一组对象以定义良好但是复杂的方式进行通信,产生了混乱的依赖关系,也导致对象难以复用。