中介者模式(MediatorPattern) : 定义了一个对象来封装一系列对象的交互. 各个对象之间不需要显式的互相引用, 而是都引用同一个中介者, 用户可以独立的改变它们之间的交互.
设计模式-概述
结构
中介者模式有4中角色:
- 抽象中介者(Mediator): 定义了一个接口用来各同事间通信.
- 具体中介者(ConcreteMediator): 具体实现了各个同事间的通信.
- 抽象同事类(Colleague): 定义各个同事类公有的方法, 维持了一个抽象中介者的引用, 以便子类使用.
- 具体同事类(ConcreteColleague): 每一个同事类对象在需要与其他同事类通信时, 需要先通过中介者完成与其他同事类的通信.
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
| @@startuml mediator-1 !include common.cuml
Class(Mediator,"Mediator") <<abstract>> { }
Class(ConcreteMediator,"具体中介者") { }
Class(Colleague,"抽象同事类") <<abstract>> { }
Class(ConcreteColleagueA,"具体同事类A") { }
Class(ConcreteColleagueB,"具体同事类B") { }
Mediator <-left- Colleague : mediator Colleague <|-- ConcreteColleagueA Colleague <|-- ConcreteColleagueB ConcreteMediator --> ConcreteColleagueA ConcreteMediator --> ConcreteColleagueB ConcreteMediator -up-|> Mediator
@@enduml
|
代码实现
实现一个同事A触发某方法, 通过中介者, 群发消息的功能
- concreteColleagueA, concreteColleagueB 为两个同事
- 通过concreteColleagueA的method2(), 触发所有通过同一个中介者的同事的method1()方法.
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
| package com.yuda.desigmode.main6;
import java.util.ArrayList; import java.util.List;
public class Main { public static void main(String[] args) { Mediator mediator = new ConcreteMediator(); Colleague concreteColleagueA = new ConcreteColleagueA(mediator); Colleague concreteColleagueB = new ConcreteColleagueB(mediator); mediator.register(concreteColleagueA); mediator.register(concreteColleagueB); System.out.println("触发concreteColleagueA的method2"); concreteColleagueA.method2(); } }
abstract class Colleague { protected Mediator mediator;
public Colleague(Mediator mediator) { this.mediator = mediator; }
public abstract void method1();
public void method2() { mediator.operation(); } }
abstract class Mediator { protected List<Colleague> colleagueList = new ArrayList<>();
public void register(Colleague colleague) { colleagueList.add(colleague); }
public abstract void operation(); }
class ConcreteMediator extends Mediator {
@Override public void operation() { for (Colleague colleague : colleagueList) { colleague.method1(); } } }
class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) { super(mediator); }
@Override public void method1() { System.out.println("ConcreteColleagueB.method1"); } }
class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) { super(mediator); }
@Override public void method1() { System.out.println("ConcreteColleagueA.method1"); } }
|
使用场景
中介者模式简化了对象之间的交互, 通过中介者和同事的一对多代替了同事之间的多对多的方式, 实现了同事之间的解耦合, 缺点是中介者的实现方式可能会很复杂.
- 系统中有多个对象, 对象间有复杂的引用关系.
- 一个对象会与多个对象通信, 且关系复杂.
- 想要把通信的行为封装起来, 同事类中无需维护通信行为时.
具体应用
- MVC架构中控制器: Controller 作为一种中介者, 它负责控制视图对象View和模型对象Model之间的交互. 如在Struts中, Action就可以作为JSP页面与业务对象之间的中介者.
- JDK中的Timer类的schedule()方法, 都调用了私有的sched()方法, 所有任务都加入队列, 队列中可以看做同事, 同事间通信都依赖与Timer, Timer就是中介者.