在现实生活中,常常会出现好多对象之间存在复杂的交互关系,这种交互关系常常是“网状结构”,它要求每个对象都必须知道它需要交互的对象。
如果把这种“网状结构”改为“星形结构”的话,将大大降低它们之间的“耦合性”,这时只要找一个“中介者”就可以了。
定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
通过使对象明确地相互引用来促进松散耦合,并允许独立地改变它们的交互。
类型:行为型
UML图
中介者模式角色介绍
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
优点
- 降低了对象之间的耦合性,使得对象易于独立地被复用。
- 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
缺点
- 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
代码举例
我们模拟一下2个电脑通过路由器来发送消息的情况。
抽象中介者(Mediator)
package factory.mediator;
public abstract class AbstractMediator {
public abstract void contact(String message, Computer computer);
}
中介者
package factory.mediator;
public class Mediator extends AbstractMediator {
private ComputerA computerA;
private ComputerB computerB;
public void setComputerA(ComputerA computerA) {
this.computerA = computerA;
}
public void setComputerB(ComputerB computerB) {
this.computerB = computerB;
}
@Override
public void contact(String message, Computer computer) {
if(computer instanceof ComputerA){
computerB.getMessage(message);
} else if(computer instanceof ComputerB){
computerA.getMessage(message);
}
}
}
抽象同事类
package factory.mediator;
public abstract class Computer {
protected String name;
protected AbstractMediator abstractMediator;
public Computer(String name, AbstractMediator abstractMediator){
this.name = name;
this.abstractMediator = abstractMediator;
}
}
具体同事类
package factory.mediator;
public class ComputerA extends Computer {
public ComputerA(String name, AbstractMediator abstractMediator) {
super(name, abstractMediator);
}
public void getMessage(String message){
System.out.println("电脑" + name + "收到消息:" + message);
}
public void contact(String message){
super.abstractMediator.contact(message, this);
}
}
package factory.mediator;
public class ComputerB extends Computer {
public ComputerB(String name, AbstractMediator abstractMediator) {
super(name, abstractMediator);
}
public void getMessage(String message){
System.out.println("电脑" + name + "收到消息:" + message);
}
public void contact(String message){
super.abstractMediator.contact(message, this);
}
}
测试
package factory.mediator;
public class Client {
public static void main(String[] args) {
Mediator mediator = new Mediator();
ComputerA computerA = new ComputerA("A", mediator);
ComputerB computerB = new ComputerB("B", mediator);
mediator.setComputerA(computerA);
mediator.setComputerB(computerB);
computerA.contact("电脑A发出的消息。。。");
computerB.contact("电脑B发出的消息。。。");
}
}
模式适用场景
-
系统中对象之间存在比较复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
-
想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。