二十. 调停者模式
整理自 《java与模式》阎宏编著
1.意图:
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
2.类图:
3.原理:
4.特征:
系统中有大量的对象,这些对象既会影响别的对象,又会被别的对象所影响,因此常常叫做同事(Colleague)对象。
抽象调停者(Mediator)角色:定义出同事对象到调停者对象的接口,其中主要的方法是一个(或多个)事件方法。在某些情况下,这个抽象对象可以省略。
具体调停者(ConcreteMediator)角色:实现了抽象超类所声明的事件方法。具体调停者知晓所有的具体同事类,它从具体同事对象接收消息,向具体同事对象发出命令。
抽象同事类(Colleague)角色:定义出调停者到同事对象的接口。同事对象只知道调停者而不知道其余的同事对象。
具体同事对象角色:从抽象同事类继承,实现自己的职责。
5.说明:
调停者模式是迪米比特法则的一个具体运用。
6.使用案例:
WTO是一个协调组织,各个贸易地区可以经由WTO组织进行协调。WTO扮演的正是调停者的角色。它取代了原来各个贸易地区自行进行相互协调和谈判的强耦合关系。各个贸易地区在加入WTO组织之前的贸易状态,如下图所示:
加入WTO之后的贸易关系,如下图所示:
7.代码:
//抽象同事类(Colleague)角色 Colleague.java
public abstract class Colleague
{
private Mediator myMediator;
/**
* Create colleague which knows about supplied mediator
*/
protected Colleague(Mediator mediator)
{
this.myMediator = mediator;
}
/**
* @return mediator this colleague knows about
*/
protected Mediator getMediator()
{
return myMediator;
}
/**
* 行动方法,由子类实现 ,一个同事对象在得知其它对象状态有改变时,会执行此操作。
*/
public abstract void action();
/**
* 示意性的商业方法,调用此方法可以改变对象的内部状态
*/
public void change()
{
myMediator.changed(this);
}
}
// ConcreteColleague1.java
/**
* 每个同事对象仅知道调停者而不知道其它同事对象
*/
public class ConcreteColleague1 extends Colleague
{
public ConcreteColleague1(Mediator mediator)
{
super(mediator);
}
public void action()
{
}
}
// ConcreteColleague2.java
/**
* 每个同事对象仅知道调停者而不知道其它同事对象
*/
public class ConcreteColleague2 extends Colleague
{
public ConcreteColleague2(Mediator mediator)
{
super(mediator);
}
public void action()
{
}
}
// Mediator.java
public interface Mediator
{
/**
* 事件方法,当自身的状态发生了变化时,一个同事对象可以
* 调用这个事件方法来通知调停者,从而更新所有有关的同事对象。
*/
void colleagueChanged(Colleague colleague);
}
// ConcreteMediator.java
public class ConcreteMediator implements Mediator
{
private ConcreteColleague1 aConcreteColleague1;
private ConcreteColleague2 aConcreteColleague2;
public void colleagueChanged(Colleague colleague)
{
aConcreteColleague1.action();
aConcreteColleague2.action();
}
/**
* 工厂方法,创建同事对象
*/
public void createConcreteMediator ()
{
aConcreteColleague1 = new ConcreteColleague1(this);
aConcreteColleague2 = new ConcreteColleague2(this);
}
public ConcreteColleague1 getAConcreteColleague1()
{
return aConcreteColleague1;
}
public ConcreteColleague2 getAConcreteColleague2()
{
return aConcreteColleague2;
}
}