描述
定义
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
类型
对象行为型模式
动机
对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。可以通过将集体行为封装在一个单独的中介者(mediator)对象中以避免这个问题。
UML类图
时序图
实现
主要角色
- Mediator:抽象中介者
- 定义一个接口用于与各同事对象通信。
- ConcreteMediator:具体中介者
- 了解并维护各个同事的引用。
- 通过协调各同事对象实现协作行为。
- Colleague:抽象同事类
- 定义各个同事类公有的方法,与中介者进行交互。
- ConcreteColleague:具体同事类
- 每一个同事类都维护中介者对象的引用。
- 实现了抽象同事类中的抽象方法,与中介者通信。
- Client:客户类
- 创建并绑定中介者和同事对象,调用同事类方法进行交互。
示例
-
Mediator:抽象中介者
interface Mediator { void operation(int receiver, String msg); void register(int receiver, Colleague colleague); }
-
ConcreteMediator:具体中介者
public class ConcreteMediator implements Mediator { private Map<Integer, Colleague> colleagues = new HashMap<>(); @override public register(int receiver, Colleague colleague) { this.colleagues.put(receiver, colleague); } @override public void operation(int receiver, String msg) { if (this.colleagues.containsKey(receiver)) { this.colleagues.get(receiver).sendMsg(msg); } else { System.out.println("no matched receiver!"); } } }
-
Colleague:抽象同事类
interface Colleague { void sendMsg(String msg); void register(Mediator mediator); }
-
ConcreteColleague:具体同事类
public class ConcreteColleagueA implements Colleague { private Mediator mediator; @override public register(Mediator mediator) { this.mediator = mediator; } @override public void sendMsg(String msg) { mediator.operation(2, "ConcreteColleagueA send msg: " + msg); } } public class ConcreteColleagueB implements Colleague { private Mediator mediator; @override public register(Mediator mediator) { this.mediator = mediator; } @override public void sendMsg(String msg) { mediator.operation(1, "ConcreteColleagueB send msg: " + msg); } }
-
Client:客户类
public class Client { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); ConcreteColleagueA concreteColleagueA = new ConcreteColleagueA(); ConcreteColleagueB concreteColleagueB = new ConcreteColleagueB(); mediator.register(1, concreteColleagueA); concreteColleagueA.register(mediator); mediator.register(2, concreteColleagueB); concreteColleagueB.register(mediator); concreteColleagueA.sendMsg("to ConcreteColleagueB"); concreteColleagueB.sendMsg("to concreteColleagueA"); } }
适用场景
- 对象间的通信方式复杂,产生的相互依赖关系结构混乱且难以理解。
- 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
优点
- 减少了子类生成。Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需生成Mediator的子类即可。这样各个Colleague类可被重用。
- 将各Colleague解耦。Mediator有利于各Colleague间的松耦合。你可以独立地改变和复合各Colleague类和Mediator类,更好地符合 “开闭原则”。
- 简化了对象协议。用Mediator和各Colleague间的一对多的交互来代替多对多的交互。一对多的关系更易于理解、维护和扩展。
缺点
- 中介者会变得庞大且复杂,原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。
相关模式
- Facade与中介者的不同之处在于它是对一个对象子系统进行抽象,从而提供了一个更为方便的接口。它的协议是单向的,即Facade对象对这个子系统类提出请求,但反之则不行。相反,Mediator提供了各Colleague对象不支持或不能支持的协作行为,而且协议是多向的。
- Colleague可使用Observer模式与Mediator通信。