中介者模式

82 阅读4分钟

Mediator

定义

能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。

应用场景

1.当一些对象和其他对象紧密耦合以致难以对其进行修改

该模式让你将对象间的所有关系抽取成为一个单独的类,以使对于特定组件的修改工作独立于其他组件。

2.组件因过于依赖其他组件而无法在不同应用中复用

应用中介者模式后, 每个组件不再知晓其他组件的情况。 尽管这些组件无法直接交流, 但它们仍可通过中介者对象进行间接交流。 如果你希望在不同应用中复用一个组件, 则需要为其提供一个新的中介者类。

3.为了能在不同情景下复用一些基本行为,导致你需要被迫创建大量组件子类

由于所有组件间关系都被包含在中介者中, 因此你无需修改组件就能方便地新建中介者类以定义新的组件合作方式。

实现方式

1.找到一组当前紧密耦合, 且提供其独立性能带来更大好处的类(例如更易于维护或更方便复用)。

2.声明中介者接口并描述中介者和各种组件之间所需的交流接口。 在绝大多数情况下, 一个接收组件通知的方法就足够了。 如果你希望在不同情景下复用组件类, 那么该接口将非常重 要。 只要组件使用通用接口与其中介者合作, 你就能将该组件与不同实现中的中介者进行连接。

3.实现具体中介者类。该类可从自行保存其下所有组件的引用中受益。

4.你可以更进一步,让中介者负责组件对象的创建和销毁。 此 后, 中介者可能会与工厂外观类似。

5.组件必须保存对于中介者对象的引用。 该连接通常在组件的构造函数中建立, 该函数会将中介者对象作为参数传递。

6.修改组件代码, 使其可调用中介者的通知方法, 而非其他组件的方法。 然后将调用其他组件的代码抽取到中介者类中, 并在中介者接收到该组件通知时执行这些代码。

优缺点

优点

1.单一职责原则。 你可以将多个组件间的交流抽取到同一位置,使其更易于理解和维护。

2.开闭原则。 你无需修改实际组件就能增加新的中介者。

3.你可以减轻应用中多个组件间的耦合情况。

4.你可以更方便地复用各个组件。

缺点

1.一段时间后, 中介者可能会演化成为上帝对象

结构

UML图

classDiagram
ConcreataMediator --|>Mediator
ComponentA --> Mediator
ComponentB --> Mediator
ConcreataMediator  --> ComponentA
Colleague o--> Mediator

参与者

1.组件(Component)是各种包含业务逻辑的类。每个组件都 有一个指向中介者的引用, 该引用被声明为中介者接口类型。 组件不知道中介者实际所属的类, 因此你可通过将其连接到 不同的中介者以使其能在其他程序中复用。

2.中介者(Mediator)接口声明了与组件交流的方法,但通常 仅包括一个通知方法。 组件可将任意上下文(包括自己的对象) 作为该方法的参数, 只有这样接收组件和发送者类之间 才不会耦合。

3.具体中介者(Concrete Mediator)封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理, 甚 至有时会对其生命周期进行管理。

组件并不知道其他组件的情况。 如果组件内发生了重要事件, 它只能通知中介者。 中介者收到通知后能轻易地确定发送者, 这或许已足以判断接下来需要触发的组件了。

对于组件来说, 中介者看上去完全就是一个黑箱。 发送者不知道最终会由谁来处理自己的请求, 接收者也不知道最初是谁发出了请求。

通用写法

public abstract class Colleague {
   protected Mediator mediator;
​
   public Colleague(Mediator mediator){
       this.mediator = mediator;
  }
}
​
public class ConcreteColleagueA extends Colleague{
   public ConcreteColleagueA(Mediator mediator){
       super(mediator);
       this.mediator.setColleagueA(this);
  }
​
   //自发行为
   public void selfMethodA(){
       //处理自己的逻辑
       System.out.println(this.getClass().getSimpleName()+"=> self-Method");
  }
​
   //依赖逻辑
   public void deptMethod(){
       //其他逻辑
       System.out.println(this.getClass().getSimpleName()+"=> deptMethod");
       this.mediator.transferA();
  }
}
​
public class ConcreteColleagueB extends Colleague{
   public ConcreteColleagueB(Mediator mediator){
       super(mediator);
       this.mediator.setColleagueB(this);
  }
​
   //自发行为
   public void selfMethodB(){
       //处理自己的逻辑
       System.out.println(this.getClass().getSimpleName()+"=> self-Method");
  }
​
   //依赖逻辑
   public void deptMethod(){
       //其他逻辑
       System.out.println(this.getClass().getSimpleName()+"=> deptMethod");
       this.mediator.transferB();
  }
}
​
public abstract class Mediator {
   protected ConcreteColleagueA colleagueA;
   protected ConcreteColleagueB colleagueB;
​
   public void setColleagueA(ConcreteColleagueA colleagueA) {
       this.colleagueA = colleagueA;
  }
​
   public void setColleagueB(ConcreteColleagueB colleagueB) {
       this.colleagueB = colleagueB;
  }
​
   //中介业务逻辑
   public abstract void transferA();
​
   public abstract void transferB();
}
​
public class ConcreteMediator extends Mediator{
   @Override
   public void transferA() {
       //协调行为 A -> B
       this.colleagueB.selfMethodB();
  }
​
   @Override
   public void transferB() {
       //协调行为 B -> A
       this.colleagueA.selfMethodA();
  }
}
​
public class Client {
   public static void main(String[] args) {
       Mediator mediator = new ConcreteMediator();
       ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
       ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
       colleagueA.deptMethod();
       colleagueB.deptMethod();
  }
}