设计模式之中介者模式
可以通过一个将集体行为封装在一个单独的中介者对象中以避免这个问题。中介者负责控制和协调一组对象间的交互。使得对象间的不在相互显示引用,减少了很多的连接数目。它们之间不需要知道相互的信息,仅仅需要知道这个中间人就可以了。如大家在聊天室里聊天,不用管对方是谁,直接登入聊天时就可以了。
其适用性:
一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解,
一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象,
想定制一个分布在多个类中的行为,而又不想生成太多的子类。
其结构图:
每一个同事类都知道它的中介者对象,每一个同事在需要与其他同事通信的时候,与它的中介者通信。中介者再转发请求以实现协作行为。在设计Colleague-Mediator之间的通信时,可以使用Observer模式,将Mediator实现为一个Observer,各Colleague作为Subject,一旦其状态改变就发送通知个Mediator,Mediator做出的响应是将状态改变的结果传播给其他的Colleague。另一种方式就是在Mediator中定义一个特殊的通知接口,各Colleague在通信时直接调用该接口。
本人实现的较为简单,如下:
public abstract class Colleage {
protected String message;
protected Mediator mediator;
public abstract void action();
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
具体的同事类如下,都较为简单,在此列举一个:
public class ConcreteColleageA extends Colleage {
@Override
public void action() {
//To change body of implemented methods use File | Settings | File Templates.
this.getMediator().doActionFromA2B();
}
}
中介者抽象接口有两个抽象方法:
public abstract class Mediator {
public abstract void doActionFromA2B();
public abstract void doActionFromB2A();
}
在使用时具体的中介者来实现该接口方法:
public class ConcreteMediator extends Mediator {
private Colleage colleageA;
private Colleage colleageB;
public ConcreteMediator(Colleage A,Colleage B){
this.colleageA = A;
this.colleageB = B;
}
@Override
public void doActionFromA2B() {
//To change body of implemented methods use File | Settings | File Templates.
this.colleageB.setMessage(this.colleageA.getMessage());
}
@Override
public void doActionFromB2A() {
//To change body of implemented methods use File | Settings | File Templates.
this.colleageA.setMessage(this.colleageB.getMessage());
}
}
本文的实现方式是将两个同事类的message,更改为自己的message信息,在客户段测试类可以直接显示出来:
public class Main {
public static void main(String[] args) {
ConcreteColleageA a = new ConcreteColleageA();
ConcreteColleageB b = new ConcreteColleageB();
Mediator mediator = new ConcreteMediator(a,b);
a.setMediator(mediator);
b.setMediator(mediator);
a.setMessage("send message to colleageB");
a.action();
System.out.println(a.getMessage());
System.out.println(b.getMessage());
b.setMessage("send message to colleageA");
b.action();
System.out.println(a.getMessage());
System.out.println(b.getMessage());
}
}
适当使用调停者模式可以较少适用静态的继承关系,使得具体同事类可以更加容易地被复用;还可以避免同事对象之间的国度耦合,使得条挺累与同事类可以相对独立地演化;其将多对多的相互作用转化为一对多的相互作用,使得对象之间的关系更加易于维护和理解。其与Facade模式的不同在于Facade意在简化接口,其实单向的,而Mediator是具有多向的协议协作行为。