中介者模式

智能家庭

 智能家居有许多。当你起床时,你希望各个设备能够协同做一些事情。

 比如:闹钟响起->音响播放音乐->空调关闭

 

传统方案:

在这里插入图片描述

问题:

 当有多种电器时,相互之间的调用关系会比较复杂。不利于松耦合。

 各个对象之间传递的内容容易混乱

 当系统中途增加一个电器对象,或者执行流程改变,则需要改动代码较大,不利于系统的可维护性、扩展性。
 

中介者模式

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


 

中介者模式结构

在这里插入图片描述

 1.组件 (Component) 是含有各种业务逻辑的类。 每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。组件不知中介者实际所属的类, 则可通过连接不同的中介者,提高复用。

 2.中介者 (Mediator)接口声明了与组件交流的方法(通常只有一个通知方法)。组件可将任意上下文(Context)作为通知方法的参数, 使接收组件与发送者不耦合。

 3.具体中介者 (Concrete Mediator) 封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理, 甚至有时会对其生命周期进行管理。

组件并不知道其他组件的情况。 如果组件内发生了重要事件, 它只能通知中介者。 中介者收到通知后能轻易地确定发送者, 这或许已足以判断接下来需要触发的组件了。对于组件来说, 中介者看上去完全就是一个黑箱。 发送者不知道最终会由谁来处理自己的请求, 接收者也不知道最初是谁发出了请求。

 

中介者模式适合应用场景

 1.当一些对象和其他对象紧密耦合以致难以对其进行修改时, 可使用中介者模式。

 2.当组件因过于依赖其他组件而无法在不同应用中复用时, 可使用中介者模式。

 3.如果为了能在不同情景下复用一些基本行为, 导致你需要被迫创建大量组件子类时, 可使用中介者模式。

 

实现方式

  1. 找到一组当前紧密耦合, 且提供其独立性能带来更大好处的类 (例如更易于维护或更方便复用)。
  2. 声明中介者接口并描述中介者和各种组件之间所需的交流接口。 在绝大多数情况下, 一个接收组件通知的方法就足够了。 如果你希望在不同情景下复用组件类, 那么该接口将非常重要。 只要组件使用通用接口与其中介者合作, 你就能将该组件与不同实现中的中介者进行连接。
  3. 实现具体中介者类。 该类可从自行保存其下所有组件的引用中受益。
  4. 你可以更进一步, 让中介者负责组件对象的创建和销毁。 此后, 中介者可能会与工厂或外观类似。
  5. 组件必须保存对于中介者对象的引用。 该连接通常在组件的构造函数中建立, 该函数会将中介者对象作为参数传递。
  6. 修改组件代码, 使其可调用中介者的通知方法, 而非其他组件的方法。 然后将调用其他组件的代码抽取到中介者类中, 并在中介者接收到该组件通知时执行这些代码。

 

中介者模式优缺点

 优点:

  ✔️ 单一职责原则。 你可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。

  ✔️ 开闭原则。 你无需修改实际组件就能增加新的中介者。

  ✔️ 你可以减轻应用中多个组件间的耦合情况。

  ✔️ 你可以更方便地复用各个组件。

 缺点:

  ❌一段时间后, 中介者可能会演化成为上帝对象。

 

解决智能家庭

在这里插入图片描述

代码:

//同事抽象类
public abstract class Colleague {
    public Mediator mediator;
    public String name;

    public Colleague(Mediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public Mediator getMediator() {
        return mediator;
    }

    public abstract void sendMessage(int stateChange);
}

public class Clock extends Colleague{

    public Clock(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 colockOpen(){
        System.out.println("闹钟响了");
    }

    public void colockStop(){
        System.out.println("闹钟停了");
    }

    public void sendColock(int stateChange){
        colockOpen();
        sendMessage(stateChange);
    }
}

public class Sound extends Colleague{

    public Sound(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 soundOpen(){
        System.out.println("音响打开");
    }

    public void soundStop(){
        System.out.println("音响关闭");
    }

    public void soundPlaying(){
        System.out.println("音响播放...");
    }

    public void sendSound(int stateChange){
        sendMessage(stateChange);
    }

}

public class AirCondition extends Colleague{

    public AirCondition(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 airConditionOpen(){
        System.out.println("打开空调");
    }

    public void airConditionStop(){
        System.out.println("关闭空调");
    }

}
public abstract class Mediator {
    //给中介者对象,加入到集合中
    public abstract void register(String colleagueName,Colleague colleague);

    //接收消息,由具体的同时对象发出
    public abstract void getMessage(int stateChange,String colleagueName);

    public abstract void SendMessage();
}

//具体的中介者类
public class ConcreteMediator extends Mediator {
    //集合,存入所有的同时对象
    private HashMap<String,Colleague> colleagueHashMap;
    private HashMap<String,String> interMap;

    public ConcreteMediator() {
        colleagueHashMap = new HashMap<>();
        interMap = new HashMap<>();
    }

    @Override
    public void register(String colleagueName, Colleague colleague) {
        colleagueHashMap.put(colleagueName,colleague);

        if (colleague instanceof Clock){
            interMap.put("Clock",colleagueName);
        }else if (colleague instanceof AirCondition){
            interMap.put("AirCondition",colleagueName);
        }else if(colleague instanceof  Sound){
            interMap.put("Sound",colleagueName);
        }
    }

    /*
        核心方法
            1.得到消息后,完成对应任务
            2.中介者在这里协调各个具体的同事对象
     */
    @Override
    public void getMessage(int stateChange, String colleagueName) {
        //处理闹钟的消息
        if (colleagueHashMap.get(colleagueName) instanceof Clock){
            if (stateChange == 0){
                ((Sound)(colleagueHashMap.get(interMap.get("Sound")))).soundOpen();
            }
            if (stateChange == 1){
                ((Sound)(colleagueHashMap.get(interMap.get("Sound")))).soundPlaying();
            }
        }else if (colleagueHashMap.get(colleagueName) instanceof Sound){ //处理音响的信息
            ((AirCondition)colleagueHashMap.get(interMap.get("AirCondition"))).airConditionStop();
        }else if (colleagueHashMap.get(colleagueName) instanceof AirCondition){
            System.out.println("流程完毕...");
        }
    }

    @Override
    public void SendMessage() {

    }
}

public class Client {
    public static void main(String[] args) {
        Mediator mediator = new ConcreteMediator();

        Clock clock = new Clock(mediator,"clock");
        Sound sound = new Sound(mediator,"sound");
        AirCondition airCondition = new AirCondition(mediator,"airCondition");


        clock.sendColock(1);
        sound.sendSound(0);

    }
}

 中介者模式的注意事项和细节
  1.多个类相互耦合,会形成网状结构 , 使用中介者模式将网状结构分离为星型结构
进行解耦
  2.减少类间依赖,降低了耦合符合迪米特原则
  3.中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响
  4.如果设计不当,中介者对象本身变得过于复杂, 这点在实际使用时,要特别注意

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值