中介者模式是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护,将网状结构转变为星型结构,所有行为都通过中介

场景

  • 一组定义良好的对象,现在要进行复杂的相互通信
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
  • 如果类的依赖关系过于复杂,呈现网状的结构,可以使用中介者模式对其进行解耦

实现

  • Mediator:抽象中介者角色,抽象类或者接口,定义统一的接口,用于各同事角色之间的通信
  • ConcreteMediator:具体中介者角色,继承或者实现了抽象中介者,实现了父类定义的方法,协调各个具体同事进行通信
  • Colleague:抽象同事角色,抽象类或者接口,定义统一的接口,它只知道中介者而不知道其他同事对象
  • ConcreteColleague:具体同事角色,继承或者实现了抽象同事角色,每个具体同事类都知道自己本身的行为,其他的行为只能通过中介者去进行

实现房屋中介

创建抽象同事角色

  1. public abstract class Person {
  2. protected HouseMediator houseMediator;
  3. public Person(HouseMediator houseMediator) {
  4. this.houseMediator = houseMediator;// 获取中介
  5. }
  6. public abstract void send(String message);// 发布信息
  7. public abstract void getNotice(String message);// 接受信息
  8. }

创建具体同事角色-购房者

  1. public class Purchaser extends Person {
  2. public Purchaser(HouseMediator houseMediator) {
  3. super(houseMediator);
  4. }
  5. @Override
  6. public void send(String message) {
  7. System.out.println("买房者发布信息:" + message);
  8. houseMediator.notice(this, message);
  9. }
  10. @Override
  11. public void getNotice(String message) {
  12. System.out.println("买房者收到消息:" + message);
  13. }
  14. }

创建具体同事角色-房东

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的设计模式-中介者模式