详解JAVA面向对象的设计模式 (五)、中介者模式
中介者模式(调停模式) Mediator
模式的定义与特点
中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。
中介者模式是一种对象行为型模式,其主要优点如下。
- 降低了对象之间的耦合性,使得对象易于独立地被复用。
- 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
其主要缺点是:当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。
模式的结构与实现
中介者模式实现的关键是找出“中介者”,下面对它的结构和实现进行分析。
模式的结构
中介者模式包含以下主要角色。
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。
- 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。
- 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
- 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。
实现例子
既然是中介者模式,我们就写一个租房中介的例子。
- 租房中介即中介者
- 来自不同省份的准租客即同事
- 某省份的准租客发送已认租信息后,中介者转发给所有注册的准租客
- 所有准租客收到已出租信息
// 抽象中介
public abstract class AbstractMediator {
public abstract void relay(AbstractTenant tenant);
public abstract void register(AbstractTenant tenant);
}
// 抽象租客
public abstract class AbstractTenant {
// 来自哪个省
protected String province;
// 指向的中介
protected AbstractMediator mediator;
public void setMediator(AbstractMediator mediator) {
this.mediator = mediator;
}
public abstract void send();
public abstract void receive(String msg);
}
具体类
// 具体中介
public class Mediator extends AbstractMediator {
List<AbstractTenant> tenants = new ArrayList<>();
@Override
public void relay(AbstractTenant sender) {
for (AbstractTenant t : tenants){
if (t.equals(sender)) {
continue;
}
t.receive("房子已经出租给" + sender.province + "租客");
}
}
@Override
public void register(AbstractTenant tenant) {
if (!tenants.contains(tenant)) {
tenants.add(tenant);
tenant.setMediator(this);
}
}
}
// 具体租客(广东,四川,江西)
public class GuangdongTenant extends AbstractTenant {
public GuangdongTenant() {
province = "广东";
}
@Override
public void send() {
System.out.println(province + "租客发送认租信息!");
mediator.relay(this);
}
@Override
public void receive(String msg) {
System.out.println("租房中介告知" + province + "准租户:" + msg);
}
}
// 四川
public class SichuanTenant extends AbstractTenant {
public SichuanTenant() {
province = "四川";
}
@Override
public void send() {
System.out.println(province + "租客发送认租信息!");
mediator.relay(this);
}
@Override
public void receive(String msg) {
System.out.println("租房中介告知" + province + "准租户:" + msg);
}
}
//江西
public class JiangxiTenant extends AbstractTenant {
public JiangxiTenant() {
province = "江西";
}
@Override
public void send() {
System.out.println(province + "租客发送认租信息!");
mediator.relay(this);
}
@Override
public void receive(String msg) {
System.out.println("租房中介告知" + province + "准租户:" + msg);
}
}
由于例子的业务内容很简单,所以具体的send receive实现都一样,实际开发中可以灵活重写这2个方法。
测试一下
public static void main(String[] args) {
AbstractTenant guangdongTenant = new GuangdongTenant();
AbstractTenant sichuanTenant = new SichuanTenant();
AbstractTenant abstractTenant = new JiangxiTenant();
AbstractMediator mediator = new Mediator();
mediator.register(guangdongTenant);
mediator.register(sichuanTenant);
mediator.register(abstractTenant);
guangdongTenant.send();
}
/**
输出:
广东租客发送认租信息!
租房中介告知四川准租户:房子已经出租给广东租客
租房中介告知江西准租户:房子已经出租给广东租客
*/