【引入】
国与国之间的关系,类似于对象与对象之间的关系,这就要求对象之间需要知道其他所有对象。但是对象之间大量的链接使得一个对象不可能在没有其他对象支持下工作,系统表现为一个不可分割的整体,降低其可复用性。
这里提及一下 迪米特法则 (即两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用) 如果一个类要调用某个类的方法,可以通过第三方转发这个的调用。正如国与国之间,可以通过联合国这个中介者来发生相互通信。
中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Colleague叫做抽象同事类;
public abstract class Colleague {
private Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public Mediator getMediator() {
return mediator;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
}
ConcreteColleague是具体同事类,每个具体的同事只知道自己的行为,而不了解其他同事类的情况,但是它们却都认识中介者对象;
public class ConcreteColleague1 extends Colleague {
public ConcreteColleague1(Mediator mediator) {
super(mediator);
}
public void send(String message) {
getMediator().send(message, this);
}
public void Notify(String message) {
System.out.println("同事1收到消息:" + message);
}
}
public class ConcreteColleague2 extends Colleague {
public ConcreteColleague2(Mediator mediator) {
super(mediator);
}
public void send(String message) {
getMediator().send(message, this);
}
public void Notify(String message) {
System.out.println("同事2收到消息:" + message);
}
}
Mediator是抽象中介者,定义了同事对象列表中介者对象的接口;
public abstract class Mediator {
/**
* 定义一个抽象的发送消息方法,得到同事对象和发送信息
* @param message
* @param colleague
*/
public abstract void send(String message,Colleague colleague);
}
ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有的具体同事类,并且从具体同事类接受消息,向具体同事类发出命令;
public class ConcreteMediator extends Mediator {
private ConcreteColleague1 colleague1;
private ConcreteColleague2 colleague2;
public void setColleague1(ConcreteColleague1 colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(ConcreteColleague2 colleague2) {
this.colleague2 = colleague2;
}
@Override
public void send(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.Notify(message);
} else {
colleague1.Notify(message);
}
}
}
客户端类
public class Client {
public static void main(String[] args) {
ConcreteMediator mediator=new ConcreteMediator();
ConcreteColleague1 colleague1=new ConcreteColleague1(mediator);
ConcreteColleague2 colleague2=new ConcreteColleague2(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.send("早上好啊!");
colleague2.send("早安!");
}
}
美国和伊拉克之间的对话都是通过联合国安理会作为中介来完成。
UML类图:
UniteNations (联合国机构类) 相当于Mediator类
/**
* 联合国机构
*/
public abstract class UniteNations {
//声明
public abstract void declare(String message,Country colleague);
}
国家类 相当于Colleague类
/**
* 国家
*/
public abstract class Country {
protected UniteNations mediator;
public Country(UniteNations mediator) {
this.mediator = mediator;
}
}
美国类 相当于ConcreteColleague1类
public class USA extends Country {
public USA(UniteNations mediator) {
super(mediator);
}
//声明
public void declare(String message) {
mediator.declare(message, this);
}
//获得消息
public void getMessage(String message) {
System.out.println("美国获得对方信息:" + message);
}
}
伊拉克类 相当于ConcreteColleague2类
public class Iraq extends Country {
public Iraq(UniteNations mediator) {
super(mediator);
}
//声明
public void declare(String message) {
mediator.declare(message, this);
}
//获得消息
public void getMessage(String message) {
System.out.println("伊拉克获得消息:" + message);
}
}
联合国安理会 相当于ConcreteMediator类
public class UnitedNationSecurityCouncil extends UniteNations {
private USA colleague1;
private Iraq colleague2;
public void setColleague2(Iraq colleague2) {
this.colleague2 = colleague2;
}
public void setColleague1(USA colleague1) {
this.colleague1 = colleague1;
}
@Override
public void declare(String message, Country colleague) {
if (colleague == colleague1) {
colleague2.getMessage(message);
} else {
colleague1.getMessage(message);
}
}
}
客户端类
public class Client {
public static void main(String[] args) {
UnitedNationSecurityCouncil UNSC=new UnitedNationSecurityCouncil();
USA colleague1=new USA(UNSC);
Iraq colleague2=new Iraq(UNSC);
UNSC.setColleague1(colleague1);
UNSC.setColleague2(colleague2);
colleague1.declare("伊拉克你们不准研制核武器,否则我们将发动战争!");
colleague2.declare("我们没有核武器,但是我们不怕战争!");
}
}
- 降低了类的复杂度,将一对多转化成了一对一。
- 各个类之间的解耦。
- 符合迪米特原则。
缺点:
- 中介者会庞大,变得复杂难以维护。
使用场景:
- 系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
注意事项:不应当在职责混乱的时候使用。