设计模式——中介者模式

350 阅读3分钟
原文链接: www.jianshu.com

定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

中介模式.png

我的日常


在我的日常工作中,项目经理(老祁)就是一个称职的黑中介。

销售经理(老王)中标了就屁颠屁颠的跑到老祁面前说: '老祁老祁咱们的XX项目中标了。'

老祁听完之后就咧开大嘴,藏不住的幸福从他的嘴里流出,然后屁颠屁颠的跑到办公室,命令小组研发人员: '赶紧的咱们的项目中标了,两周后完成开发任务,麻溜的。'

两周之后项目如期完成,老祁按耐不住激动的心情,跑到运维(小姜)跟前说: '小姜呀,你去把项目部署到客户那里,以后这个项目就靠你运维了,加油哦,我看好你!'。

最终,这个项目在老祁的运筹帷幄中顺利上线,得到了上级领导的认可,故事就这样圆满结束。

en interesting!


中介者模式的目的

项目经理老祁在这个故事里 集中相关对象之间复杂的沟通和控制方式,最终做到了将 销售、研发、运维 完美的解耦。

类关系

  • Mediator:抽象中介者,定义一个方法用于与各同事(Colleague)对象向中介对象的传达消息。
  • Colleague:抽象同事类。
  • ConreteMediator:具体中介者,实现抽象类的方法,他需要知道所有具体同事对象,接收某个具体同事对象传达的消息,并对相关具体同事对象发号施令。
  • ConcreteColleague:具体同事类,每个同事只知道自己的行为,不了解其他同事对象的情况,但是他人事中介者对象。


    关系图.png

实战

Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构:


原始依赖结构.jpg

使用中介者模式可以将复杂的依赖结构变成星形结构:


中介者模式依赖图.jpg
  • 同事类
public abstract class Colleague {
    public abstract void onEvent(Mediator mediator);
}
public class Alarm extends Colleague {

    @Override
    public void onEvent(Mediator mediator) {
        mediator.doEvent("alarm");
    }

    public void doAlarm() {
        System.out.println("doAlarm()");
    }
}
public class CoffeePot extends Colleague {
    @Override
    public void onEvent(Mediator mediator) {
        mediator.doEvent("coffeePot");
    }

    public void doCoffeePot() {
        System.out.println("doCoffeePot()");
    }
}
public class Calender extends Colleague {
    @Override
    public void onEvent(Mediator mediator) {
        mediator.doEvent("calender");
    }

    public void doCalender() {
        System.out.println("doCalender()");
    }
}
public class Sprinkler extends Colleague {
    @Override
    public void onEvent(Mediator mediator) {
        mediator.doEvent("sprinkler");
    }

    public void doSprinkler() {
        System.out.println("doSprinkler()");
    }
}
  • 中介者类
public abstract class Mediator {
    public abstract void doEvent(String eventType);
}
public class ConcreteMediator extends Mediator {
    private Alarm alarm;
    private CoffeePot coffeePot;
    private Calender calender;
    private Sprinkler sprinkler;

    public ConcreteMediator(Alarm alarm, CoffeePot coffeePot, Calender calender, Sprinkler sprinkler) {
        this.alarm = alarm;
        this.coffeePot = coffeePot;
        this.calender = calender;
        this.sprinkler = sprinkler;
    }

    @Override
    public void doEvent(String eventType) {
        switch (eventType) {
            case "alarm":
                doAlarmEvent();
                break;
            case "coffeePot":
                doCoffeePotEvent();
                break;
            case "calender":
                doCalenderEvent();
                break;
            default:
                doSprinklerEvent();
        }
    }

    public void doAlarmEvent() {
        alarm.doAlarm();
        coffeePot.doCoffeePot();
        calender.doCalender();
        sprinkler.doSprinkler();
    }

    public void doCoffeePotEvent() {
        // ...
    }

    public void doCalenderEvent() {
        // ...
    }

    public void doSprinklerEvent() {
        // ...
    }
}
public class Client {
    public static void main(String[] args) {
        Alarm alarm = new Alarm();
        CoffeePot coffeePot = new CoffeePot();
        Calender calender = new Calender();
        Sprinkler sprinkler = new Sprinkler();
        Mediator mediator = new ConcreteMediator(alarm, coffeePot, calender, sprinkler);
        // 闹钟事件到达,调用中介者就可以操作相关对象
        alarm.onEvent(mediator);
    }
}
优点
  • 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。
  • 提供系统的灵活性,使得各个同事对象独立而易于复用。
缺点
  • 中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。
  • 新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。
适用场景
  • 一组定义良好的对象,现在要进行复杂的相互通信。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。



相关链接:www.cnblogs.com/snaildev/p/…