顿搜
调停者模式/中介者模式(Mediator)——23种设计模式之行为型模式
04/22
在软件构建过程中,经常会出现多个对象互相关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可使用一个“中介对 象”来管理对象间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。
虽然将一个系统分割成许多对象通常可以增强可复用性, 但是对象间相互连接的激增又会降低其可复用性。用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散, 而且可以独立地改变它们之间的交互。
一、类图表示
调停者模式涉及到Mediator(抽象中介者),ConcreteMediator(具体中介者),Colleague(同事类)等角色
- ①、Mediator(抽象中介者):中介者定义一个接口用于与各同事(Colleague)对象通信。
- ②、ConcreteMediator(具体中介者):通过协调各同事对象实现协作行为,了解并维护它的各个同事
- ③、Colleague(同事类):每一个同事类都知道它的中介者对象,每一个同事对象在需与其他的同事通信的时候,与它的中介者通信
二、代码示例
public interface Mediator {
/**
* 同事对象在自身改变的时候来通知调停者方法
* 让调停者去负责相应的与其他同事对象的交互
*/
public void changed(Colleague c);
}public class ConcreteMediator implements Mediator {
//持有并维护同事A
private ConcreteColleagueA colleagueA;
//持有并维护同事B
private ConcreteColleagueB colleagueB;
public void setColleagueA(ConcreteColleagueA colleagueA) {
this.colleagueA = colleagueA;
}
public void setColleagueB(ConcreteColleagueB colleagueB) {
this.colleagueB = colleagueB;
}
@Override
public void changed(Colleague c) {
/**
* 某一个同事类发生了变化,通常需要与其他同事交互
* 具体协调相应的同事对象来实现协作行为
*/
}
}public abstract class Colleague {
//持有一个调停者对象
private Mediator mediator;
/**
* 构造函数
*/
public Colleague(Mediator mediator){
this.mediator = mediator;
}
/**
* 获取当前同事类对应的调停者对象
*/
public Mediator getMediator() {
return mediator;
}
}public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
/**
* 示意方法,执行某些操作
*/
public void operation(){
//在需要跟其他同事通信的时候,通知调停者对象
getMediator().changed(this);
}
}public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
/**
* 示意方法,执行某些操作
*/
public void operation(){
//在需要跟其他同事通信的时候,通知调停者对象
getMediator().changed(this);
}
}三、优缺点分析
1、优点
- ①、减少了子类生成:将分布于多个对象间的行为集中在一起
- ②、它将各Colleague解耦
- ③、它简化了对象协议:多对多变为一对多
- ④、它对对象如何协作进行了抽象
- ⑤、适当使用调停者模式可以避免同事之间的过渡耦合,使得调停类与同事类可以相对独立地演化
- ⑥、适当使用调停者模式可以较少使用静态的继承关系,使得具体同事类可以更加容易被复用。
- ⑦、调停者模式将多对多的相互作用转化为一对多的相互作用,使得对象之间的关系更加易于维护和理解。
- ⑧、调停者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
2、缺点
- ①、它使控制集中化,中介者模式将交互的复杂性变为中介者的复杂性,中介类可能难以复用。
- ②、调停者模式降低了同事对象的复杂性,代价是增加了调停者类的复杂性。当然,在很多情况下,设置一个调停者并不比不设置一个调停者更好
- ③、调停者类经常充满了各个具体同事类的关系协调代码,这种代码常常是不能复用的。因此,具体同事类的复用是以调停者类的不可复用为代价的。
- ④、调停者模式为同事对象,而不是调停者对象提供了可扩展性,所以这个模式所提供的可扩展性是一种(向同事对象)倾斜的可扩展性。
四、设计原则分析
1、迪米特法则
调停者模式符合迪米特法则。调停者模式创造出一个调停者对象,将系统中有关的对象所引用的其他对象数目减到最少,使得一个对象与其同事的相互作用被这个对象与调停者对象的相互作用所取代。显然,调停者模式是迪米特法则的一个具体应用。
五、应用场景
调停者模式适用于以下场景:
- ①、一组对象以定义良好但是复杂的方式进行通信。 产生的相互依赖关系结构混乱且难以理解。
- ②、一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
- ③、想定制一个分布在多个类中的行为,而又不想生成太多的子类。
六、总结
调停者模式简化了对象协议,将原来多对多的关系变为一对多的关系
- ①、忽略抽象的Mediator类,当各Colleague仅与一 个Mediator一起工作时,没有必要定义一个抽象 的Mediator类
- ②、Colleague—Mediator通信,可以采用Observer 模式,或者在Mediator中定义一个特殊的通知接口,各Colleague在通信时直接调用该接口
- ③、Mediator模式将多个对象间复杂的关联关系解耦,将多个对象间的控制逻辑进行集中管理,变“多个对象相互关联”为“多个对象和一个中介者对象关 联”,简化了系统的维护,抵御了可能的变化。
- ④、随着控制逻辑的复杂化,Mediator模式具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。
