个人在CSDN的BLOG:http://blog.csdn.net/feb13/article/details/7906868
MEDIATOR 中介者
参考《设计模式——可复用面向对象软件的基础》和《研磨设计模式》的读书笔记。
1、 意图
用一个中介者对象来封装一系列的对象交互。中介者使其各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立改变它们之间的交互。
2、 适用性
3、 结构
4、 参与者
Mediatord(中介者)
——中介者定义一个接口用于与各同事(Colleague)对象通信。
ConcreteMediator(具体中介者)
——了解中介者通过协调各同事对象实现协作行为。
——了解并维护它的各个同事。
ColleagueClass(同事类,包括其子类)
——每一个同事类都知道它的中介者对象。
——每一个同事类对象在需与其他同事通信的时候,与它的中介者通信。
5、 协作
同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现协作行为。
6、 效果
1) 减少了子类生成;Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需要生成Mediator的子类即可。这样各个Colleague类可被重用。
2) 它将各Colleague解耦;Mediator有利于各Colleague间的松耦合。你可以独立地改变和复用Colleague类和Mediator类。
3) 它简化了对象协议;用Mediator和各Colleague间的一对多的交互来代替多对多的交互。一对多的关系更易于理解、维护和扩展。
4) 它对对象如何协作进行了抽象;将中介作为一个独立的概念并将其封装在一个对象中,使你将注意力从对象各自本身的行为转移到它们之间的交互上来。这有助于弄清楚一个系统中的对象是如何交互的。
5) 它使控制集中化;中介者模式将交互的复杂性变为中介者的复杂性。因为中介者封装了协议,它可能变得比任一个Colleague都复杂。这可能使得中介者自身成为一个难以维护的庞然大物。
7、 实现
1) 忽略抽象的Mediator类;当各Colleague仅与一个Mediator一起工作时,没有必要定义一个抽象的Mediator类。Mediator类提供的抽象耦合已经使各Colleague可与不同的Mediator子类一起工作,反之亦然。
2) Colleague——Mediator通信;当一个感兴趣的事件发生时,Colleague必须与其Mediator通信。一种实现方法是 Observer模式,将Mediator实现为一个Observer,各Colleague作为Subset,一旦其状态改变就发送通知给 Mediator;一种方法是在Mediator中定义一个特殊的通知接口,各Colleague在通信时直接调用该接口。
8、 代码示例
Mediatord
package com.examples.pattern.mediator; /** * 中介者,定义各个同事对象通信的接口 */ public interface Mediator { /** * 同事对象自身改变的时候来通知中介者的方法 让中介者去负责相应的与其他同事对象的交互 * * @param colleague * 同事对象自身,好让中介者对象通过对象实例去获得同事对象的状态 */ public void changed(Colleague colleague); }
ConcreteMediator
package com.examples.pattern.mediator; /** * 具体的中介者实现 */ public class ConcreteMediator implements Mediator { /** * 持有并维护同事A */ private ConcreteColleagueA colleagueA; /** * 持有并维护同事B */ private ConcreteColleagueB colleagueB; /** * 设置中介者需要了解并维护的同事A对象 * @param colleagueA */ public void setColleagueA(ConcreteColleagueA colleagueA) { this.colleagueA = colleagueA; } /** * 设置中介者需要了解并维护的同事B对象 * @param colleagueB */ public void setColleagueB(ConcreteColleagueB colleagueB) { this.colleagueB = colleagueB; } @Override public void changed(Colleague colleague) { System.out.println(colleague); } }
Colleague Class
package com.examples.pattern.mediator; /** * 同事类的抽象父类 */ public abstract class Colleague { /** * 持有中介者对象,每一个同事类都知道它的中介者对象 */ private Mediator mediator; /** * 构造者方法,传入中介者对象 * @param mediator */ public Colleague(Mediator mediator) { this.mediator = mediator; } /** * 获得当前同事类对应的中介者对象 * @return */ public Mediator getMediator() { return mediator; } }
package com.examples.pattern.mediator; /** * 具体的同事类A */ public class ConcreteColleagueA extends Colleague { public ConcreteColleagueA(Mediator mediator) { super(mediator); } public void someOperation(){ //在需要跟其他同事通信的时候,通知中介者对象 getMediator().changed(this); } }
package com.examples.pattern.mediator; public class ConcreteColleagueB extends Colleague { public ConcreteColleagueB(Mediator mediator) { super(mediator); } public void someOperation(){ //在需要跟其他同事通信的时候,通知中介者对象 getMediator().changed(this); } }
Client
package com.examples.pattern.mediator; public class Client { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); ConcreteColleagueA ca = new ConcreteColleagueA(mediator); ConcreteColleagueB cb = new ConcreteColleagueB(mediator); mediator.setColleagueA(ca); mediator.setColleagueB(cb); ca.someOperation(); cb.someOperation(); } }
9、 相关模式
Façade与中介者的不同之处在于它是对 一个对象子系统进行抽象,从而提供了一个更方便的接口。它的协议是单向的,即Façade对象对这个子系统类提出请求,但反之则不行。相 反,Mediator提供了各Colleague对象不支持或不能支持的协作行为,而且协议是多向的。
Colleague可使用Observer模式与Mediator通信。
10、 广义中介者
在我们的通常使用中,经常会简化中介者模式,来使开发变得简单,有如下变化: