行为型设计模式 - 中介者模式详解
基本介绍
中介者模式(Mediator Pattern)用一个中间对象来封装一系列的对象交互,使得各对象不需要显式的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
开发中常用的 MVC 模型就是一种中介者模式,Controller 就是 View 和 Model 的中介。
模式结构
Mediator(抽象中介者):定义了同事对象到中介对象的接口,用于同事类间的通信
ConcreteMediator(具体中介者):管理所有的具体同事类,接收同事的消息,完成相应的任务
Colleague(抽象同事类):维持了一个抽象中介者的引用,其子类可以通过该引用与中介者通信
ConcreteColleague(具体同事类):每个同事类只知道自己的行为,并不了解其它同事类,但是它们都依赖中介者对象
举例说明
以房东和租客为例,使用中介者模式解决
1、抽象中介者,定义了一个联系方法
public interface Mediator {
/**
* 和同事类联系
* @param person 发送者
* @param message 传递的信息
*/
void contact(Person person, String message);
}
2、抽象同事类,通过中介对象联系对方
public abstract class Person {
protected String name;
protected Mediator mediator;
public Person(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
}
3、具体中介者,需要知道所有的具体同事类
public class ConcreteMediator implements Mediator {
private HouseOwner houseOwner;
private Tenant tenant;
@Override
public void contact(Person person, String message) {
if (person instanceof HouseOwner) {
//如果是房主,则租客获得消息
tenant.getMessage(message);
} else if (person instanceof Tenant) {
//如果是租客,则房主获得消息
houseOwner.getMessage(message);
}
}
public void setHouseOwner(HouseOwner houseOwner) {
this.houseOwner = houseOwner;
}
public void setTenant(Tenant tenant) {
this.tenant = tenant;
}
}
4、具体同事类(房东和租客),通过中介对象联系,不直接交流
public class HouseOwner extends Person {
public HouseOwner(String name, Mediator mediator) {
super(name, mediator);
}
public void contact(String message) {
this.mediator.contact(this, message);
}
public void getMessage(String message) {
System.out.println(this.name + "(房主)获得信息:" + message);
}
}
public class Tenant extends Person {
public Tenant(String name, Mediator mediator) {
super(name, mediator);
}
public void contact(String message) {
this.mediator.contact(this, message);
}
public void getMessage(String message) {
System.out.println(this.name + "(租客)获得信息:" + message);
}
}
5、测试类
public class Client {
@Test
public void test() {
ConcreteMediator mediator = new ConcreteMediator();
HouseOwner houseOwner = new HouseOwner("包租婆", mediator);
Tenant tenant = new Tenant("小王", mediator);
//中介需要知道房主和租客
mediator.setHouseOwner(houseOwner);
mediator.setTenant(tenant);
//通过中介传递信息
tenant.contact("你们这儿的房子不停水吧?");
houseOwner.contact("不停,你就放心的租吧!");
}
}
6、运行结果
包租婆(房主)获得信息:你们这儿的房子不停水吧?
小王(租客)获得信息:不停,你就放心的租吧!
模式分析
优点
- 将对象间的网状结构转为星型结构,简化了对象之间的交互
- 减少类之间的依赖,降低耦合,符合迪米特法则
- 减少了子类的生成
缺点
- 具体中介者中包含了同事之间的交互细节,可能会导致具体中介者非常复杂,维护困难
适用场景
- 系统中对象之间存在比较复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。