在系统设计中,尽管将一个系统分割成许多对象通常可以增加其可复用性,但是对象之间相互连接的激增又会降低其可复用性了。因为大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难了。
迪米特法则告诉我们:如果两个类之间不必彼此直接通信,那么这两个类之间就不应该发生直接的相互作用。如果其中一个类需要调用另一个类的方法,可以通过第三者转发这个调用。这就用到了中介者模式。
中介者模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变他们之间的交互。
举个例子:各个国家与联合国安理会之间的关系就可以用中介者模式表现出来。
联合国机构相当于中介者:
public abstract class UnitedNations {
public abstract void declare(String message, Country country);
}
各个国家之间要进行通信,就需要认识中介者对象:
public class Country {
protected UnitedNations mediator;
public Country(UnitedNations mediator) {
this.mediator = mediator;
}
}
具体国家类:
public class USA extends Country {
public USA(UnitedNations mediator) {
super(mediator);
}
/**
* 声明
* @param message
*/
public void declare(String message) {
mediator.declare(message, this);
}
/**
* 获得消息
* @param message
*/
public void getMessage(String message) {
System.out.println("美国获得消息:" + message);
}
}
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);
}
}
联合国类,相当于中介者的具体实现,负责实现国家之间的通信:
public class UnitedNationsSecurityCouncil extends UnitedNations {
private USA country1;
private Iraq country2;
public void setCountry1(USA country1) {
this.country1 = country1;
}
public void setCountry2(Iraq country2) {
this.country2 = country2;
}
/**
* 实现两个对象间的通信
* @param message
* @param country
*/
@Override
public void declare(String message, Country country) {
if (country == country1) {
country2.getMessage(message);
} else {
country1.getMessage(message);
}
}
}
测试类:
public class MediatorTest {
public static void main(String[] args) {
UnitedNationsSecurityCouncil mediator = new UnitedNationsSecurityCouncil();
USA usa = new USA(mediator);
Iraq iraq = new Iraq(mediator);
mediator.setCountry1(usa);
mediator.setCountry2(iraq);
usa.declare("不准研制核武器,否则发动战争!");
iraq.declare("没有核武器,也不怕侵略!");
}
}
输出:
伊拉克获得消息:不准研制核武器,否则发动战争!
美国获得消息:没有核武器,也不怕侵略!
由联合国类实现国家间的通信,国与国之间不存在耦合关系。
中介者模式优缺点:
尽管这样设计减少了国家类之间的耦合,但是中介者类必须知道所有的国家类,这使得中介者类的责任过多,如果它出了问题,整个系统都会有问题。
中介者模式的优点:中介者的出现减少了各个国家之间的耦合,使得可以独立地改变和复用各个Country类和Mediator,任何国家的改变不会影响到其它国家,而只是与联合国之间发生变化。其次,由于把对象如何协作进行了抽象(declare方法),将中介作为一个独立地概念并将其封装到一个对象中,这样关注的对象就从对象各自本身的行为转移到他们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
由于联合国类控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个国家都复杂。终结者模式常见的应用就是计算器,每个按钮都不知道其它按钮存在,全部通过form窗体作为中介传输信息。
中介者模式一般用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多各类中的行为,而又不想生成太多的子类的场合。