本文最后更新于:3 years ago
调停者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个调停类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。调停者模式属于 行为型模式
如果想了解调停者模式的具体的介绍,菜鸟教程介绍得比较详细↓
菜鸟教程-调停者模式
结构图
优缺点
优点:
1、降低了类的复杂度,将一对多转化成了一对一。
2、各个类之间的解耦。
3、符合迪米特原则
缺点:
调停者会庞大,变得复杂难以维护。
使用场景
1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
实现代码
调停者模式和上一章说的外观模式是思想上是很相似的,但是调停者是解决系统内部中的多个对象之间复杂的关系的,所以二者面对的对象是不一样的。
如下图所示:
本来准备介绍的栗子比较简单,然后想想还是仔细介绍一下吧
Mediator
模式中Mediator
是抽象中介者,提供了同事对象注册与转发同事对象信息的抽象方法;
Colleague
是抽象同事类,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能;
ConcreteMediator
是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令,协调各个同事角色之间的交互关系;
ConcreteColleague
是具体同事类,每个具体同事只知道自己的行为,而不了解其它同事类的情况,但它们却都认识中介者对象。
这里我们模拟的是,聊天室中当A发送消息时,B、C都能接收到,并且当接收到时,返回收到的信息。B、C同理
代码如下:
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| public class Main { public static void main(String[] args) { Mediator mediator = new ConcreteMediator();
Colleague colleagueA = new ConcreteColleagueA(); Colleague colleagueB = new ConcreteColleagueB(); Colleague colleagueC = new ConcreteColleagueC();
mediator.register(colleagueA); mediator.register(colleagueB); mediator.register(colleagueC);
colleagueA.send(); colleagueB.send(); colleagueC.send(); } }
public abstract class Mediator { abstract void register(Colleague colleague);
abstract void relay(Colleague colleague); }
public abstract class Colleague { protected Mediator mediator;
public void setMedium(Mediator mediator) { this.mediator = mediator; }
abstract void receive();
abstract void send(); }
public class ConcreteMediator extends Mediator { List<Colleague> colleagues;
public ConcreteMediator() { colleagues = new ArrayList<>(); }
@Override void register(Colleague colleague) { if (!colleagues.contains(colleague)) { colleague.setMedium(this); colleagues.add(colleague); } }
@Override void relay(Colleague colleague) { colleagues.forEach(c -> { if (!c.equals(colleague)){ c.receive(); } }); System.out.println("------------"); } }
public class ConcreteColleagueA extends Colleague{ @Override void receive() { System.out.println("ColleagueA receive message"); }
@Override void send() { System.out.println("ColleagueA send message"); mediator.relay(this); } }
public class ConcreteColleagueB extends Colleague{ @Override void receive() { System.out.println("ColleagueB receive message"); }
@Override void send() { System.out.println("ColleagueB send message"); mediator.relay(this); } }
public class ConcreteColleagueC extends Colleague{ @Override void receive() { System.out.println("ColleagueC receive message"); }
@Override void send() { System.out.println("ColleagueC send message"); mediator.relay(this); } }
|
输出结果:
| ColleagueA send message ColleagueB receive message ColleagueC receive message ------------ ColleagueB send message ColleagueA receive message ColleagueC receive message ------------ ColleagueC send message ColleagueA receive message ColleagueB receive message ------------
|
在注册时
| void register(Colleague colleague) { if (!colleagues.contains(colleague)) { colleague.setMedium(this); colleagues.add(colleague); } }
|
每一个同事角色都知道调停者角色,而且与其它的同事角色通信的时候必须依赖调停住者才能完成,所以这里我们需要将调停者传入
我们在ConcreteMediator
中定义一个List
来管理同事对象(Colleague),协调各个同事角色之间的交互关系,在注册时,我们需要将每个同事对象加入
当某个同事对象(Colleague)发送信息(send)时,会去通知调停者,收到信息的用户发送消息。
| void send() { System.out.println("ColleagueB send message"); mediator.relay(this); }
|
这里的调停者就是我们在register中传入的对象
Mediator模式和Facade模式的思想很相似,一个是降低系统内部的耦合度,一个是降低外部与系统的耦合度
都借用了一个’外观类’/‘调停者’来处理其中复杂的关系
具体在实战中的应用我就不多介绍了,大家感兴趣的话,可以自行了解