设计模式~调停者模式(Mediator)
调停者模式是对象的行为模式。
调停者模式包装了一系列对象相互作用的方式,使得这些对象不必互相明显引用。
从而使它们可以比较松散的耦合。当这些对象中的某些对象之间的相互作用发生改变时,
不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立的变化。
不要滥用模式
要想恰到好处的在一个系统里面使用设计模式,必须做到以下几点:
1. 完全了解面临的问题,这就是说要完全了解具体情况。
2. 完全了解模式,这就是说要十分懂得理论。
3. 非常了解怎样使用设计模式解决实际问题,这就是说要将模式理论与具体系统需求情况相结合。
什么是调停者模式
在调停者模式中,所有的成员对象都可以协调工作,但是又不直接相互管理。
这些对象都与一个处于中心地位的调停者对象发生紧密的关系,由这个调停者对象进行协调工作。
这个协调者对象叫做调停者(Mediator),而调停者所协调的成员对象称作同事对象(Colleague)。
调停者模式的结构
调停者模式的角色:
- 抽象调停者模式:定义出同事对象到调停者对象的接口,其中主要的方法是一个(或者多个)事件方法。在有些情况下,这个抽象对象可以省略。一般而言,这个角色由一个Java抽象类或者Java对象实现。
- 具体调停者角色:从抽象调停者继承而来,实现了抽象超类所声明的事件方法。具体调停者知晓所有的具体同事类,它从具体同事对象接收消息,向具体同事对象发出命令。一般而言,这个角色由一个具体Java类实现。
- 抽象同事类角色:定义出调停者到同事对象的接口。同时对象只知道调停者而不知道其余的同事对象。一般而言,这个角色由一个Java抽象类或者Java对象实现。
- 具体同事类角色:所有的具体同事类均从抽象同事类继承而来。每一个具体同事类都清楚它自己在小范围内的行为,而不知道它在大范围内的目的。
下面是一个简化的示意性实现
代码清单:
抽象同事类
public abstract class Colleague { private Mediator mediator; public Colleague(Mediator m) { mediator = m; } public Mediator getMediator(){ return mediator; } public abstract void action(); public void change(){ mediator.colleagueChanged(this); } }
具体同事类
public class Colleague1 extends Colleague { public Colleague1(Mediator m) { super(m); } /** * 行动方法的具体实现 */ public void action() { System.out.println("This is an action from Colleague 1"); } }
public class Colleague2 extends Colleague { public Colleague2(Mediator m){ super(m); } public void action() { // TODO Auto-generated method stub System.out.println("This is an action from Colleague 2"); } }
抽象调停者类
public abstract class Mediator { //事件方法,由子类实现 public abstract void colleagueChanged(Colleague c); public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); mediator.createConcreteMediator(); Colleague c1 = new Colleague1(mediator); Colleague c2 = new Colleague2(mediator); mediator.colleagueChanged(c1); } }
具体调停者类
public class ConcreteMediator extends Mediator { private Colleague1 colleague1; private Colleague2 colleague2; /** * 事件方法的具体实现 */ @Override public void colleagueChanged(Colleague c) { // TODO Auto-generated method stub colleague1.action(); colleague2.action(); } /** * 工厂方法,创建同事对象 */ public void createConcreteMediator(){ colleague1=new Colleague1(this); colleague2 = new Colleague2(this); } public Colleague1 getColleague1(){ return colleague1; } public Colleague2 getColleague2(){ return colleague2; } }
调停者模式的时序
在某一个同事对象的状态发生变化时,这个同事对象需要通过调停者对象的事件方法通知其他的同事对象采取行动。
比如,Colleague1对象发生了状态变化,这时它调用Mediator对象的事件方法 colleagueChanged(), 并将自己作为参量传给Mediator对象;
后者则根据商业逻辑通过调用 Colleague1 和 Colleague2 的行动方法 action() 将这个信息传给所有有关的同事对象。
具体活动时序如下:
调停者模式的优点和缺点
优点:
1. 适当使用调停者模式可以较少使用静态的继承关系,使得具体同事类可以更加容易的被复用。
2. 适当使用调停者模式可以避免同事对象之间的过度耦合,使得调停类与同事类可以相对独立的演化。
3. 调停者模式将多对多的相互作用转化一对多的相互作用,使得对象之间的关系更加容易维护和理解。
4. 调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
缺点:
1. 调停者模式降低了同事对象的复杂性,代价是增加了调停者类的复杂性。当然,在很多情况下,设置一个调停者并不比不设置一个调停者更好。
2. 调停者类经常充满了各个具体同事类的关系协调代码,这种代码常常是不能复用的。因此,具体同事类的复用是以调停者类的不可复用为代价的。
显然,调停者模式为同事对象,而不是调停者对象提供了可扩展性,所以这个模式所提供的可扩展性是一种(向同事对象)倾斜的可扩展性。
调停者模式的使用条件
不应当在责任划分混乱时使用
不应当对数据类和方法类使用
正确理解封装
封装首先是行为,以及行为所涉及的状态的封装。行为与状态是不应当分割开来的。
调停者模式的用途是管理很多的对象的相互作用,以便使这些对象可以专注于自身的行为,而独立于其他的对象。