设计模式-中介者模式

时间:2022-07-25
本文章向大家介绍设计模式-中介者模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

背景

随着汽车越来越普及了,很多家庭配置了汽车,其实很多是闲置状态,也只是代代步,但是为了方便出门提升司机们的收入,滴滴推出了顺风车服务,乘客和司机大哥发布的信息双方在平台上面都可以收到,这个跟设计模式中的中介者模式类似,平台是中介、司机和乘客是同事角色。

中介者模式是什么?

中介者模式(Mediator Pattern)属于行为模式,又叫调停者模式。定义:用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

角色:

Mediator(中介者):中介者定义一个接口用于与各角色之间通信。 ConcreteMediator(具体中介者):具体中介者通过协调各同事对象实现协作行为。 了解并维护它的各个角色。

Colleague(同事角色):抽象的同事角色,定义了中介者的接口,只知道中介者对象。 Colleagueclass(具体同事角色):具体同事角色,提供功能的同事对象。 每一个同事类都知道它的中介者对象; 每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。

中介者模式可以干嘛?

中介者主要是解决对象与对象之间的依赖问题,解决这种因为一个依赖关系的修改涉及的上下游依赖关系都得随着改变,并且这样也不遵循开闭原则,其次可以增加功能复用性也会提高,并且更易于维护。中介者类承担了两方面的职责:中转作用(结构性)、协调作用(行为性)

中转作用(结构性):通过中介直接去引用同事(colleague)对象,当同事与同事之间需要通信时通过中介对象实现,中转作用

协调作用(行为性):中介者可以将同事之间的关系进一步进行封装和分离;

优点:

解耦合:加入中介者角色可以降低之间的耦合度,减少类与类之间的依赖 ;

易拓展:通过中介者角色可以拓展新的功能,而不会影响原有的功能,遵询了开闭原则,并且功能单一职责,灵活性也提升了。

缺点:

中介对象一但出现故障,将造成很严重的影响,就类似于你家里附件的电压坏了,整个村子都用不了了...

个人理解:

中介者模式就类似于顺风车平台,平台是中介者(Mediator),司机、乘客为同事角色(Colleague),通过平台乘客和司机去发布自己的信息,平台负责展示,并且从中抽水....

中介者模式类图

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

实现代码

/**
 * @Auther: csh
 * @Date: 2020/6/9 17:17
 * @Description:抽象中介者(mediator)
 */
public abstract class AbstractMediator {
    //存放 "乘客信息"
    protected List<AbstractColleague> passengerList = new ArrayList <AbstractColleague>();
    //存放 "司机信息"
    protected List<AbstractColleague> driverList = new ArrayList <AbstractColleague>();


    //添加乘客
    public void addPassenger(AbstractColleague passenger){
        passengerList.add(passenger);
    }

    //添加司机
    public void addDriver(AbstractColleague passenger){
        driverList.add(passenger);
    }
    //由具体中介者子类实现 消息的中转和协调
    public abstract void commission(AbstractColleague passenger,String work);
}
/**
 * @Auther: csh
 * @Date: 2020/6/9 17:37
 * @Description:抽象的同事类
 */
public abstract class AbstractColleague {
    //乘客名称
    protected String name;
    //中介
    protected AbstractMediator abstractMediator;

    public AbstractColleague(String name, AbstractMediator abstractMediator) {
        this.name = name;
        this.abstractMediator = abstractMediator;
    }


    public void setAbstractMediator(AbstractMediator abstractMediator) {
        this.abstractMediator = abstractMediator;
    }

    /**
     * 向中介 发送消息
     */
    protected abstract void sendMessage(String msg);

    /**
     * 从中介 获取消息
     */
    protected abstract void getMessage(String msg);


}
/**
 * @Auther: csh
 * @Date: 2020/6/9 18:16
 * @Description:司机 具体同事实现(Colleagueclass)
 */
public class Driver extends AbstractColleague {


    public Driver(String name, AbstractMediator abstractMediator) {
        super(name, abstractMediator);
    }

    @Override
    protected void sendMessage(String msg) {
        this.abstractMediator.commission(this,msg);
    }

    @Override
    protected void getMessage(String msg) {
        System.out.println("司机【"+this.name+"】收到中介发来的消息:"+msg);
    }
}
/**
 * @Auther: csh
 * @Date: 2020/6/9 18:19
 * @Description:乘客【Colleagueclass(具体同事角色)】
 */
public class Passenger extends AbstractColleague {

    public Passenger(String name, AbstractMediator abstractMediator) {
        super(name, abstractMediator);
    }

    @Override
    protected void sendMessage(String msg) {
        this.abstractMediator.commission(this,msg);
    }

    @Override
    protected void getMessage(String msg) {
        System.out.println("乘客【"+name+"】收到中介发来的消息"+msg);
    }
}
/**
 * @Auther: csh
 * @Date: 2020/6/9 18:20
 * @Description:平台 具体中介角色(ConcreteMediator)
 */
public class Didi extends AbstractMediator {

    @Override
    public void commission(AbstractColleague passenger, String work) {
        if(passenger instanceof Driver){
            //将匹配到的司机发送给乘客
            for (AbstractColleague abstractColleague : passengerList) {
                abstractColleague.getMessage(work);
            }
        }else{
            //将需要打车的乘客发给司机
            for (AbstractColleague abstractColleague : driverList) {
                abstractColleague.getMessage(work);
            }
        }
    }
}
/**
 * @Auther: csh
 * @Date: 2020/6/9 18:20
 * @Description:代理模式,模拟顺风车,乘客发布信息,司机可以收到,而司机发部信息乘客也可收到。
 */
public class Client {
    public static void main(String[] args) {
        //滴滴代理平台
        AbstractMediator didi = new Didi();
        AbstractColleague driver = new Driver("司机1",didi);
        AbstractColleague driver2 = new Driver("司机2",didi);
        AbstractColleague passenger = new Passenger("乘客1",didi);
        AbstractColleague passenger2 = new Passenger("乘客2",didi);
        didi.addDriver(driver);
        didi.addDriver(driver2);
        didi.addPassenger(passenger);
        didi.addPassenger(passenger2);
        driver.sendMessage("有没有去北京?");
        passenger.sendMessage("我需要打车去北京!");
    }
}

结果

乘客【乘客1】收到中介发来的消息有没有去北京?
乘客【乘客2】收到中介发来的消息有没有去北京?
司机【司机1】收到中介发来的消息:我需要打车去北京!
司机【司机2】收到中介发来的消息:我需要打车去北京!

源码下载:https://gitee.com/hong99/design-model/issues/I1IMES

最后

中介者服务就类似于网络拓扑心型结构,所有的数据流和操作都是通过这个中介者来实现,从而避免用户直接去面对系统内部,有利用避免程序内部对外暴露,而且可以通过中介者来解耦对象一对象之间的复杂关系;当然弊端也是挺重的,因为所有的操作或沟通都通过中介者来进行从而导致中介者是面对用户的第一对接都,一但发生事故后果很严重,就比如膜拜单车平台出事估了,所有的单车都开不了锁了,或者滴滴平台出事估了整个平台下不了单...