中介者模式


中介者模式

如何理解中介者模式

复杂的进销存系统类图

类图

  • 虽然不同类型的参与者完成各自的活动,但是每个类相互关联耦合
  • 每个类与多个朋友类相互交互,朋友类越多,耦合性越大,要修改一个,就得修改一大片— 违反迪米特法则
  • 不同参与者之间交互过于复杂,维护比较困难

使用一个中介者对象,他将各个对象之间的交互封装起来作为一个中间桥梁,降低各个参与者的耦合性。

中介者类图

  • 每个参与者只负责自己的业务逻辑,不属于自己的交给中介者去处理
  • 每个参与者不再交互交流,简化了各模块间的耦合性
  1. 抽象中介者类

定义统一的接口,用于各个参与者角色之间的通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class Mediator {

protected ConcreteColleagueA concreteColleagueA;

protected ConcreteColleagueB concreteColleagueB;

public Mediator(){
concreteColleagueA = new ConcreteColleagueA(this);
concreteColleagueB = new ConcreteColleagueB(this);
}

public abstract void doSomethingA();

public abstract void doSomethingB();
}
Q:为什么使用参与类实现类注入,而不使用抽象类注入(接口注入)
A:因为每个参与类没有必须要完成的业务方法(没有相同的方法), 假如有相同的方法,当然要注入抽象类做到依赖倒置。

  1. 抽象参与者类

每一个参与者必须知道中介者角色,所以通过构造函数传入

1
2
3
4
5
6
7
public abstract class Colleague {
protected Mediator mediator;

public Colleague(Mediator mediator){
this.mediator = mediator;
}
}

  1. 具体中介者类

协调各个参与者实现协作工作行为,要依赖各个参与者

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ConcreteMediator extends Mediator{

@Override
public void doSomethingA() {
super.concreteColleagueA.selfMethod();
super.concreteColleagueB.selfMethod();
}

@Override
public void doSomethingB() {
super.concreteColleagueA.selfMethod();
super.concreteColleagueB.selfMethod();
}
}
  1. 具体参与者类A
  • 自身的行为selfMethod,用于处理自身的业务逻辑
  • 依赖的行为depMethod,依靠中介者去完成
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class ConcreteColleagueA extends Colleague{
    public ConcreteColleagueA(Mediator mediator){
    super(mediator);
    }

    public void selfMethod(){
    //自己的业务逻辑
    }

    public void depMethod(){
    //不能处理的业务逻辑,交给中介者处理
    super.mediator.doSomethingA();
    }
    }
  1. 具体参与者类B

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class ConcreteColleagueB extends Colleague{
    public ConcreteColleagueB(Mediator mediator) {
    super(mediator);
    }

    public void selfMethod(){
    //自己能够处理的业务逻辑
    }

    public void depMethod(){
    super.mediator.doSomethingB();
    }
    }
  2. 客户端

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class ConcreteColleagueB extends Colleague{
    public ConcreteColleagueB(Mediator mediator) {
    super(mediator);
    }

    public void selfMethod(){
    //自己能够处理的业务逻辑
    }

    public void depMethod(){
    super.mediator.doSomethingB();
    }
    }

用一个中介对象封装一系列的对象交互,中介者使对象不需要显示的相互作用,从而使其耦合松散,并且可以独立的改变他们之间的交互

中介者模式有什么优势

  1. 系统更加灵活,各个参与者相互独立
  2. 减少类间的依赖,参与类只依赖中介者,减少了依赖,降低了类间的耦合

    中介者模式存在的问题

  3. 中介者承担了太多的职责,一旦出现问题,整个系统都会受影响
  4. 中介者会变得非常复杂,原本参与者间的关系转换成了中介者与参与者的关系,参与者越多,中介者就越复杂

中介者模式要慎用

  1. 量力而行。 中介者模式会使中介者逻辑复杂化。使用不当会把问题变得复杂,如果本身就只有简单的几个依赖关系,就没必要用终结者模式。所以要根据情况权衡中介者模式的使用
  2. 中介者适合多个对象紧密耦合的情况–蜘蛛网结构,中介者模式能将蜘蛛网结构梳理成星型结构

留下的问题

Q:不符合依赖倒置原则,很少使用接口或者抽象类

  • 参与者之间是协作关系,处理不同的任务,不能严格定义参与者需要具有的方法,不能抽象出一个统一的父类
  • 每个中介者所围绕的参与类各不相同,不能抽象出一个具有共性的中介者
  • 两个对象不能提炼出共性,就不要追求两者的抽象