类图
目的
“定义一个封装-系列对象交互的对象。Mediator通过防止对象间显示地相互引用来促使松耦合,且可以独立地改变他们之间的交互。"[GoF]
要解决的问题
如何避免一组交互对象之间的紧密耦合?
如何独立改变一组对象之间的相互作用?
解决方案
定义一个单独的Mediator对象,该对象封装一组对象之间的交互方式。对象与Mediator对象交互,而不是彼此直接交互。
动机
紧耦合的colleague。一组colleague通过互相引用和知道彼此而直接进行交互(紧耦合)
紧耦合的对象依赖(引用并知道)许多其他具有不同接口的对象,这使得它们难以实现,更改,测试和重用。
分布式交互行为。很难更改对象彼此交互的方式,因为交互是分布在对象之间。
适用性
(1) 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
(2) 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
(3) 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。
结构
● Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
● ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,它维持了对各个同事对象的引用。
● Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时它维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
● ConcreteColleague(具体同事类):它是抽象同事类的子类;每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信;在具体同事类中实现了在抽象同事类中声明的抽象方法。
协作
优缺点
优点:
(1) 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
(2) 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合“开闭原则”。
(3) 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
缺点:
在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
实施
实现交互行为
●Mediator负责控制和协调cllague的交互(更新)
●Mediator的复杂性随着colleague的复杂性和数量的增加而增加
●Collague通过在mediator.上调用mediate[this)间接地彼此交互
●Colleague将自己(此)传递给Colleague, 以便mediator可以回调以了解发生了什么更改(从Colleague那里获得所需的数据)。
代码:
package mediator;
public interface Mediator {
public void mediate(String state);
}
package mediator;
import java.util.ArrayList;
import java.util.List;
class Mediator1 implements Mediator{
Colleague1 c1;
Colleague2 c2;
public void mediate(String state) {
System.out.println("Mediator: Mediating the interaction ...");
if(state.equals(c1.getState())){
c2.action(state);
}
else if(state.equals(c2.getState())){
c1.action(state);
}
}
public void setColleagues(Colleague1 c1,Colleague2 c2){
this.c1=c1;
this.c2=c2;
}
}
package mediator;
public interface Colleague {
public void action(String state);
public String getState();
}
package mediator;
public class Colleague1 implements Colleague{
private String State;
private Mediator mediator;
public Colleague1(Mediator mediator){
this.mediator=mediator;
}
public void action(String state) {
State=state;
System.out.println("Colleague1: My state synchronized to :"+state);
}
public String getState() {
return this.State;
}
public void setState(String str) {
// TODO Auto-generated method stub
this.State=str;
System.out.println("Colleague1:My state changed to: "+str+"Calling my mediator ...");
this.mediator.mediate(str);
}
}
package mediator;
public class Colleague2 implements Colleague{
private String State;
private Mediator mediator;
public Colleague2(Mediator mediator){
this.mediator=mediator;
}
public void action(String state) {
State=state;
System.out.println("Colleague2: My state synchronized to :"+state);
}
public String getState() {
return this.State;
}
public void setState(String str) {
this.State=str;
System.out.println("Colleague2:My state changed to: "+str+"Calling my mediator ...");
this.mediator.mediate(str);
}
}
package mediator;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
Mediator1 mediator=new Mediator1();
Colleague1 c1=new Colleague1(mediator);
Colleague2 c2=new Colleague2(mediator);
mediator.setColleagues(c1,c2);
System.out.println("(1) Changing state of Colleague1 ...");
c1.setState("Hello World1!");
System.out.println("\n(2) Changing state of Colleague2 ...");
c2.setState("Hello World2!");
}
}