中介者模式是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护,将网状结构转变为星型结构,所有行为都通过中介
场景
- 一组定义良好的对象,现在要进行复杂的相互通信
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
- 如果类的依赖关系过于复杂,呈现网状的结构,可以使用中介者模式对其进行解耦
实现
- Mediator:抽象中介者角色,抽象类或者接口,定义统一的接口,用于各同事角色之间的通信
- ConcreteMediator:具体中介者角色,继承或者实现了抽象中介者,实现了父类定义的方法,协调各个具体同事进行通信
- Colleague:抽象同事角色,抽象类或者接口,定义统一的接口,它只知道中介者而不知道其他同事对象
- ConcreteColleague:具体同事角色,继承或者实现了抽象同事角色,每个具体同事类都知道自己本身的行为,其他的行为只能通过中介者去进行
实现房屋中介
创建抽象同事角色
public abstract class Person {
protected HouseMediator houseMediator;
public Person(HouseMediator houseMediator) {
this.houseMediator = houseMediator;// 获取中介
}
public abstract void send(String message);// 发布信息
public abstract void getNotice(String message);// 接受信息
}
创建具体同事角色-购房者
public class Purchaser extends Person {
public Purchaser(HouseMediator houseMediator) {
super(houseMediator);
}
@Override
public void send(String message) {
System.out.println("买房者发布信息:" + message);
houseMediator.notice(this, message);
}
@Override
public void getNotice(String message) {
System.out.println("买房者收到消息:" + message);
}
}
创建具体同事角色-房东
public class Landlord extends Person {
public Landlord(HouseMediator houseMediator) {
super(houseMediator);
}
@Override
public void send(String message) {
System.out.println("房东发布信息:" + message);
houseMediator.notice(this, message);
}
@Override
public void getNotice(String message) {
System.out.println("房东收到消息:" + message);
}
}
创建抽象中介者角色
public interface HouseMediator {//房屋中介类
void notice(Person person, String msg);//通知方法
}
创建具体中介者角色,具体的房屋中介,以链家为例,他们能从房东和买房者获得信息,然后做出不同的行为
public class Lianjia implements HouseMediator {
Purchaser mPurchaser;
Landlord mLandlord;
public void setPurchaser(Purchaser purchaser) {
mPurchaser = purchaser;
}
public void setLandlord(Landlord landlord) {
mLandlord = landlord;
}
@Override
public void notice(Person person, String message) {
System.out.println("中介收到信息,并转发给相应的目标人群");
if (person == mPurchaser) {
mLandlord.getNotice(message);
} else if (person == mLandlord) {
mPurchaser.getNotice(message);
}
}
}
客户端测试
public void test() {
Lianjia houseMediator = new Lianjia();
Purchaser purchaser = new Purchaser(houseMediator);
Landlord landlord = new Landlord(houseMediator);
houseMediator.setLandlord(landlord);
houseMediator.setPurchaser(purchaser);
landlord.send("出售一套别墅");
System.out.println("------------------------");
purchaser.send("求购一套学区房");
}
输出结果
房东发布信息:出售一套别墅
中介收到信息,并转发给相应的目标人群
买房者收到消息:出售一套别墅
------------------------
买房者发布信息:求购一套学区房
中介收到信息,并转发给相应的目标人群
房东收到消息:求购一套学区房
优点
- 降低了类的复杂度,将一对多转化成了一对一
- 各个类之间的解耦
- 符合迪米特原则
缺点
同事类越多,中介者的逻辑就越复杂,会变得越难维护
Android 中的应用
在Binder机制中,就用到了中介者模式。我们知道系统启动时,各种系统服务会向ServiceManager提交注册,即ServiceManager持有各种系统服务的引用 ,当我们需要获取系统的Service时,比如ActivityManager、WindowManager等(它们都是Binder),首先是向ServiceManager查询指定标示符对应的Binder,再由ServiceManager返回Binder的引用。并且客户端和服务端之间的通信是通过Binder驱动来实现,这里的ServiceManager和Binder驱动就是中介者
参考
书籍:《设计模式之禅》、《Android源码设计模式》
技术文章:菜鸟教程-设计模式、Android的设计模式-中介者模式