Java 设计模式——中介者模式

模式定义

用一个中介者对象来封装一系列的对象交互。这样就使各个对象之间不需要显示的相互引用,达到降低耦合的目的,并且可以独立的改变它们之间的交互

使用范围

  1. 一组已经定义好的对象以复杂的方式进行通信,产生相互依赖的关系结构且难以理解时;
  2. 一个对象引用很多其他对象,并直接与这些对象通信时;
  3. 想定制一个分布在多个类中的行为,又不想生成太多的子类(如根据某种行为定义一个接口,让想拥有该行为的类实现该接口)

模式参与者

  • Mediator

    接口,用于抽象3中所说的行为

  • MediatorImpl

    实现了Mediator,同时持有彼此需要相互通信的对象的实例

  • AbstractMember

    需要相互通信的对象的抽象类(用于抽象各具体对象的通用属性)

  • ExactMember

    具体的对象实现

代码实现

要模拟的场景描述:

两个知道彼此姓名单不认识的员工他们需要交流,但他们属于不同的部门,但Hr对他们的个人信息都十分了解,所以就有Hr安排他们彼此认识

  1. 抽象出员工都需要的抽象行为

    1
    2
    3
    public abstract class Mediator {
    public abstract void sayHi(String message, Employee employee);
    }
  1. 抽象行为的具体实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    public class ConcreteMediator extends Mediator {
    EmployeeA employeeA;
    EmployeeB employeeB;

    public EmployeeA getEmployeeA() {
    return employeeA;
    }

    public void setEmployeeA(EmployeeA employeeA) {
    this.employeeA = employeeA;
    }

    public EmployeeB getEmployeeB() {
    return employeeB;
    }

    public void setEmployeeB(EmployeeB employeeB) {
    this.employeeB = employeeB;
    }

    @Override
    public void sayHi(String message, Employee employee) {
    if (employee == employeeA) {
    employeeB.sayHi(message);
    } else {
    employeeA.sayHi(message);
    }
    }
    }
  1. 员工的抽象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Employee {
    protected String name;
    protected Mediator mediator;

    public Employee(String name, Mediator mediator) {
    this.name = name;
    this.mediator = mediator;
    }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

4. 员工的具体实现

```java
class EmployeeA extends Employee {

public EmployeeA(String name, Mediator mediator) {
super(name, mediator);
}

public void getMessage(String message) {
System.out.println("员工" + name + "说:" + message);
}

public void sayHi(String message) {
mediator.sayHi(message, this);
}
}

class EmployeeB extends Employee {

public EmployeeB(String name, Mediator mediator) {
super(name, mediator);
}

public void getMessage(String message) {
System.out.println("员工" + name + "说:" + message);
}

public void sayHi(String message) {
mediator.sayHi(message, this);
}
}
  1. 安排一个会议室,让他们彼此打招呼(即定义客户端,运行代码测试)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Client {
    public static void main(String[] args) {
    ConcreteMediator mediator = new ConcreteMediator();

    EmployeeA employeeA = new EmployeeA("张三", mediator);
    EmployeeB employeeB = new EmployeeB("李四", mediator);

    mediator.setEmployeeA(employeeA);
    mediator.setEmployeeB(employeeB);

    employeeA.sayHi("我有事要和李四说。");
    employeeB.sayHi("我下午有时间,下午商量。");
    }
    }

    例子可能不当,请见谅!

从上面的例子可以看到,作为中介着的ConcreteMediator持有需要交流的A、B员工实例(即可直接访问需要彼此交互的对象),A、B员工的构造方法中又接受了一个中介者队形作为参数,这样A、B对象就可以调用Mediator里面的方法进行通信。

总结

中介者模式,虽然降低了不同对象之间相处引用而引起的耦合,但同样会是中介者里面的逻辑处理变的复杂起来。而且示例中的对象方法和属性都相同,在对象更复杂的情况下,中介者的使用难度更大