美文网首页程序员技术干货
Java 设计模式(20) —— 中介者模式

Java 设计模式(20) —— 中介者模式

作者: 磊_lei | 来源:发表于2018-06-12 08:53 被阅读112次

一、中介者模式

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

中介者模式

二、示例

智能家居项目:现在要设计一套智能家居系统,家里有闹钟、咖啡机、窗帘、电视。当早晨闹钟响起之后要控制咖啡机自动煮咖啡,咖啡煮好之后窗帘要自动打开,电视机也打开开始播放新闻

用传统模式规划此项目的话是通过对象之间的彼此控制,用闹钟控制咖啡机,用咖啡机控制窗帘和电视。虽然传统模式也可以实现功能,但是各组件之间相互依赖性较高,且不利于新电器的增加,网状结构较复杂

引入中介者模式,定义一个中介者,连接各个组件,各组件的功能全部通过中介者控制,则每个组件只需与中介者通信即可,且利于组件的增加和减少

1.定义中介者的接口


/**
 * 中介者模式,中介者的接口,用于注册加入中介,发送消息和接收消息
 */
public interface Mediator {
    public abstract void Register(String colleagueName, Colleague colleague);

    public abstract void GetMessage(int stateChange, String colleagueName);

    public abstract void SendMessage();
}

2.定义各组件实现的抽象类

/**
 * 中介者模式,各组件实现的抽象类
 */
public abstract class Colleague {
    private Mediator mediator;
    public String name;

    public Colleague(Mediator mediator, String name) {

        this.mediator = mediator;
        this.name = name;

    }

    public Mediator GetMediator() {
        return this.mediator;
    }

    public abstract void SendMessage(int stateChange);
}

3.各组件实现抽象类的抽象方法和自己实现的功能方法

/**
 * 中介者模式,闹钟对象,属于中介者控制的组件
 */
public class Alarm extends Colleague {

    public Alarm(Mediator mediator, String name) {
        super(mediator, name);
        mediator.Register(name, this);
    }

    public void SendAlarm(int stateChange) {
        SendMessage(stateChange);
    }

    @Override
    public void SendMessage(int stateChange) {
        this.GetMediator().GetMessage(stateChange, this.name);
    }

}

/**
 * 中介者模式,咖啡机对象,属于中介者控制的组件
 */
public class CoffeeMachine extends Colleague {

    public CoffeeMachine(Mediator mediator, String name) {
        super(mediator, name);
        mediator.Register(name, this);
    }

    @Override
    public void SendMessage(int stateChange) {
        this.GetMediator().GetMessage(stateChange, this.name);
    }

    public void StartCoffee() {
        System.out.println("It's time to startcoffee!");
    }

    public void FinishCoffee() {

        System.out.println("After 5 minutes!");
        System.out.println("Coffee is ok!");
        SendMessage(0);
    }
}


/**
 * 中介者模式,窗帘对象,属于中介者控制的组件
 */
public class Curtains extends Colleague {

    public Curtains(Mediator mediator, String name) {
        super(mediator, name);
        mediator.Register(name, this);
    }

    @Override
    public void SendMessage(int stateChange) {
        this.GetMediator().GetMessage(stateChange, this.name);
    }

    public void UpCurtains() {
        System.out.println("I am holding Up Curtains!");
    }

}

/**
 * 中介者模式,电视机对象,属于中介者控制的组件
 */
public class TV extends Colleague {

    public TV(Mediator mediator, String name) {
        super(mediator, name);
        mediator.Register(name, this);
    }

    @Override
    public void SendMessage(int stateChange) {
        this.GetMediator().GetMessage(stateChange, this.name);
    }

    public void StartTv() {
        System.out.println("It's time to StartTv!");
    }

    public void StopTv() {
        System.out.println("StopTv!");
    }
}

4.定义中介者,用于集中管控所有组件之间的功能


/**
 * 中介者模式,中介者,用于集中管理所有的组件控制,协调各组件的功能
 */
public class ConcreteMediator implements Mediator {
    private HashMap<String, Colleague> colleagueMap;
    private HashMap<String, String> interMap;

    public ConcreteMediator() {
        colleagueMap = new HashMap<String, Colleague>();
        interMap = new HashMap<String, String>();
    }

    @Override
    public void Register(String colleagueName, Colleague colleague) {
        colleagueMap.put(colleagueName, colleague);


        if (colleague instanceof Alarm) {
            interMap.put("Alarm", colleagueName);
        } else if (colleague instanceof CoffeeMachine) {
            interMap.put("CoffeeMachine", colleagueName);
        } else if (colleague instanceof TV) {
            interMap.put("TV", colleagueName);
        } else if (colleague instanceof Curtains) {
            interMap.put("Curtains", colleagueName);
        }

    }

    @Override
    public void GetMessage(int stateChange, String colleagueName) {

        if (colleagueMap.get(colleagueName) instanceof Alarm) {
            if (stateChange == 0) {
                ((CoffeeMachine) (colleagueMap.get(interMap
                        .get("CoffeeMachine")))).StartCoffee();
                ((TV) (colleagueMap.get(interMap.get("TV")))).StartTv();
            } else if (stateChange == 1) {
                ((TV) (colleagueMap.get(interMap.get("TV")))).StopTv();
            }

        } else if (colleagueMap.get(colleagueName) instanceof CoffeeMachine) {
            ((Curtains) (colleagueMap.get(interMap.get("Curtains"))))
                    .UpCurtains();

        } else if (colleagueMap.get(colleagueName) instanceof TV) {

        } else if (colleagueMap.get(colleagueName) instanceof Curtains) {

        }

    }

    @Override
    public void SendMessage() {

    }

}

5.组件调用


/**
 * 中介者模式:用一个中介对象来封装一系列的对象交互
 */
public class MainTest {

    public static void main(String[] args) {

        // 定义闹钟,咖啡机,窗帘,电视等组件,用中介者集中管控
        Mediator mediator = new ConcreteMediator();
        Alarm mAlarm = new Alarm(mediator, "mAlarm");
        CoffeeMachine mCoffeeMachine = new CoffeeMachine(mediator,
                "mCoffeeMachine");
        Curtains mCurtains = new Curtains(mediator, "mCurtains");
        TV mTV = new TV(mediator, "mTV");
        mAlarm.SendAlarm(0);
        mCoffeeMachine.FinishCoffee();
        mAlarm.SendAlarm(1);
    }

}

根据以上中介者模式的设计方式可以实现各组件只需发送修改自己的状态即可,剩下的控制全由中介者负责,降低各组件之间的耦合度,利于拓展。

三、总结

  • 优点:

    • 通过将对象彼此解耦,可以增加对象的复用性
    • 通过将控制逻辑集中,可以简化系统维护
    • 可以让对象之间所传递的消息变得简单而且大幅减少
    • 提高系统的灵活性,使得系统易于扩展和维护
  • 缺点:

    • 中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
    • 如果设计不当,中介者对象本身变得过于复杂
  • 适用场合:

    • 一组对象之间的通信方式比较复杂,导致相互依赖,结构混乱
    • 一个对象引用很多其他对象并直接与这些对象通信,导致难以复用该对象

Java设计模式所有示例代码,持续更新中

相关文章

网友评论

    本文标题:Java 设计模式(20) —— 中介者模式

    本文链接:https://www.haomeiwen.com/subject/tstleftx.html