中介者模式
定义
用一个中介对象来封装一系列的对象交互。中介使各对象之间不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。
UML图
举个栗子
“联合国”就是世界上各个国家的一个“中介”,许多事情都不是国家之间直接交互,而是通过“安理会”等组织进行协商、投票等过程。
Talk is cheap, show me the code
(屁话少说,放码过来)
/**
* 联合国机构
* Created by callmeDevil on 2019/12/15.
*/
public abstract class UnitedNations {
// 声明
public abstract void declare(String message, Country colleague);
}
/**
* 国家(相当于Colleague类)
* Created by callmeDevil on 2019/12/15.
*/
public abstract class Country {
protected UnitedNations mediator;
public Country(UnitedNations mediator){
this.mediator = mediator;
}
}
/**
* 美国(相当于 ConcreteColleague1 类)
* Created by callmeDevil on 2019/12/15.
*/
public class USA extends Country{
public USA(UnitedNations mediator) {
super(mediator);
}
// 声明
public void declare(String message){
mediator.declare(message, this);
}
//获得消息
public void getMessage(String message){
System.out.println("美国获得对方信息:" + message);
}
}
/**
* 伊拉克(相当于 ConcreteColleague2 类)
* Created by callmeDevil on 2019/12/15.
*/
public class Iraq extends Country{
public Iraq(UnitedNations mediator) {
super(mediator);
}
// 声明
public void declare(String message){
mediator.declare(message, this);
}
//获得消息
public void getMessage(String message){
System.out.println("伊拉克获得对方信息:" + message);
}
}
/**
* 联合国安全理事会
* Created by callmeDevil on 2019/12/15.
*/
public class UnitedNationsSecurityCouncil extends UnitedNations{
// 美国
private USA colleague1;
// 伊拉克
private Iraq colleague2;
// 省略 get set
@Override
public void declare(String message, Country colleague) {
// 重写声明方法,实现了两个对象之间的通信
if (colleague == colleague1) {
colleague2.getMessage(message);
} else {
colleague1.getMessage(message);
}
}
}
public class Test {
public static void main(String[] args) {
UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();
USA c1 = new USA(UNSC);
Iraq c2 = new Iraq(UNSC);
UNSC.setColleague1(c1);
UNSC.setColleague2(c2);
c1.declare("不准研制核武器,否则要发动战争!");
c2.declare("我们没有核武器,也不怕侵略!");
}
}
运行结果
伊拉克获得对方信息:不准研制核武器,否则要发动战争!
美国获得对方信息:我们没有核武器,也不怕侵略!
总结
优点
- Mediator的出现减少了各个Colleague的耦合,使得可以独立的改变和复用各个Colleague类和Mediator
- 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统
缺点
- 中介者模式很容易在系统中应用,也容易误用。当系统出现了‘多对多’交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理的
- 由于ConcreteMediator控制了集中化,于是就把交互复杂性变为中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂
常用情景
- 一组对象以定义良好但是复杂的方式进行交互通信的场合
- 需要定制一个分布在多个类中的行为,而又不想生成太多的子类的场合