作为一个编程菜鸟,过去在学习设计模式的时候,老师给推荐了一本《大话设计模式》。阅读以后受益匪浅,可惜当初没有坚持看完。
最近有时间了,又重新捡起来学习了一遍,整理了一下笔记,由于本人能力有限,欢迎大家批评指正。
1.中介者模式 Mediator Pattern
- 尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象间相互连接的激增又会降低其可复用性了。因为大量的连接使得一个对象不可能再没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难。
- 用一个中介对象来封装一系列的对象交互,中介者使对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
- 中介者模式属于行为型模式,用于降低多个对象和类之间的通信复杂性。
2.uml类图
- Collegue:抽象同事类
- ConcreteCollegue:具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象
- Mediator:是抽象中介者,定义了同事对象到中介者对象的接口
- ConcreteMediator:是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同时对象发出命令。
3.优缺点
- 中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了“多对多”交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。不应当在职责混乱的时候使用。
- Mediator的出现减少了各个Collegue的耦合,使得可以独立地改变和复用各个Collegue类和Mediator。
- 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
- ConcreteMediator控制了集中化,把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteCollegue都复杂。中介者模式的优点来自于集中控制,其缺点也是它。
- 降低了类的复杂度,将一对多转化成了一对一,符合迪米特原则。
4.应用场景
- 中介者模式一般应用于一组对象以定义良好但是引用关系复杂,它们之间依赖关系结构混乱而且难以复用该对象的场合。
- 以及想定制一个分布在多个类中的行为,通过一个中间类来封装多个类中的行为,而又不想生成太多的子类的场合。
5.实例
(1)需求
美国和伊拉克之间的对话都是通过联合国安理会作为中介来完成。
(2)uml类图
(3)代码
a.国家抽象Colleague类
package com.longinus.mp;
public abstract class Country {
protected UnitedNations mediator;
public Country(UnitedNations mediator) {
this.mediator = mediator;
}
}
b.抽象中介者类
package com.longinus.mp;
public abstract class UnitedNations {
public abstract void declare(String message,Country colleague);
}
c.具体国家 Colleague 类
package com.longinus.mp;
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);
}
}
package com.longinus.mp;
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);
}
}
d.具体中介者类
package com.longinus.mp;
public class SecurityCouncil extends UnitedNations {
private USA colleague1;
private Iraq colleague2;
public USA getColleague1() {
return colleague1;
}
public void setColleague1(USA colleague1) {
this.colleague1 = colleague1;
}
public Iraq getColleague2() {
return colleague2;
}
public void setColleague2(Iraq colleague2) {
this.colleague2 = colleague2;
}
@Override
public void declare(String message, Country colleague) {
if (colleague == colleague1) {
colleague2.getMessage(message);
} else {
colleague1.getMessage(message);
}
}
}
e.测试类
package com.longinus.mp;
public class Test {
public static void main(String[] args) {
SecurityCouncil unsc = new SecurityCouncil();
USA c1 = new USA(unsc);
Iraq c2 = new Iraq(unsc);
unsc.setColleague1(c1);
unsc.setColleague2(c2);
c1.declare("不准研制核武器,否则发动战争");
c2.declare("我们没有核武器,也不怕侵略");
}
}
f.输出结果
伊拉克获得对方信息:不准研制核武器,否则发动战争
美国获得对方信息:我们没有核武器,也不怕侵略