中介者设计模式(Mediator Design Pattern)


目的
定义一个封装一组对象如何交互的对象。Mediator通过防止对象明确地相互引用来促进松耦合,它允许您独立地改变它们的交互。

说明
中介者模式在多个对象相互交互的企业应用程序中非常有用。如果对象直接相互交互,则系统组件彼此紧密耦合,这使得可维护性成本更高并且不易灵活扩展。Mediator模式侧重于在对象之间提供中介以进行通信,并帮助实现对象之间的松散耦合。
空中交通管制员是中介模式的一个很好的例子,机场控制室作为不同航班之间通信的中介。Mediator作为对象之间的路由器,它可以拥有自己的逻辑来提供通信方式。

结构

参与者
1.Mediator

  • 该组件定义了与Colleague对象通信的接口。

2. ConcreteMediator 
  • 该组件通过协调Colleague对象来实现协作行为。
  • 它了解并维护其同事。

3.Colleague classes
  • 每个Colleague类都知道它的Mediator对象。
  • 每当与其他同事进行沟通时,每位同事都会与其 mediator进行沟通。

源代码
这里我们将在聊天室应用程序的上下文中使用Mediator模式。首先,我们将为我们的介体定义一个接口。
//Mediator interface
public interface Mediator {
  public void send(String message, Colleague colleague);
}

虽然我们将同事描述为上面的接口,但在这种情况下使用抽象类更有用:

//Colleage interface
public abstract Colleague{
  private Mediator mediator;
  public Colleague(Mediator m) {
    mediator = m;
  }
 
//send a message via the mediator
  public void send(String message) {
    mediator.send(message, this);
  }
 
//get access to the mediator
  public Mediator getMediator() {return mediator;}
  public abstract void receive(String message);
}

现在让我们创建具体的Mediator实现

public class ApplicationMediator implements Mediator {
  private ArrayList<Colleague> colleagues;
  public ApplicationMediator() {
    colleagues = new ArrayList<Colleague>();
  }
  public void addColleague(Colleague colleague) {
    colleagues.add(colleague);
  }
  public void send(String message, Colleague originator) {
    //let all other screens know that this screen has changed
    for(Colleague colleague: colleagues) {
     
//don't tell ourselves
      if(colleague != originator) {
        colleage.receive(message);
      }
    }
  }
}


最后,我们将创建一个具体的同事 

public class ConcreteColleague extends Colleague {
  public void receive(String message) {
    System.out.println("Colleague Received: " + message);
  }
}

如果假设我们可以让许多不同的同事在收到消息时做出不同的反应,那么这种模式很适合。例如,我们可以让mobileColleague需要以不同方式向桌面同事显示消息。

public class MobileColleague extends Colleague {
  public void receive(String message) {
    System.out.println("Mobile Received: " + message);
  }
}

这是一个驱动整个应用程序的客户端:

public class Client {
  public static void main(String[] args) {
    ApplicationMediator mediator = new ApplicationMediator();
    ConcreteColleague desktop = new ConcreteColleague(mediator);
    ConcreteColleague mobile = new MobileColleague(mediator);
    mediator.addColleague(desktop);
    mediator.addColleague(mobile);
    desktop.send("Hello World");
    mobile.send(
"Hello");
  }
}

重点

  • 当对象之间的通信逻辑复杂时,中介者模式很有用,我们可以拥有一个负责通信逻辑的中心通信点。

  • Java消息服务(JMS)使用Mediator模式和Observer模式允许应用程序订阅数据并将数据发布到其他应用程序。

  • 我们不应该仅仅使用中介模式来实现松散耦合,因为如果mediators的数量增长,那么就很难维护它们。

适用性
使用Mediator模式时
  • 一组对象以明确但复杂的方式进行通信。由此产生的相互依赖性是非结构化的,难以理解

  • 重用对象很困难,因为它引用并与许多其他对象通信

  • 分布在几个类中的行为应该是可定制的,而不需要大量的子类化。