【设计模式】中介者模式(行为设计模式)

对于中介者,任谁一听都想到了房产中介,然而房产中介的职责和这个中介者模式的职责很类似,就是在买房和卖房之间建立一个桥梁通讯(当然了,我们这个不收费O(∩_∩)O)

中介者模式的意图

中介者使各个对象之间不需要显示的相互引用,而是通过一个比较特殊的中介对象使得程序组件间进行通讯,以此来实现介绍程序组件之间的耦合。(看到这里,我想到了Vue里面的Vuex)


这个模式会限制对象之间进行直接通讯,通过中介对象来协作(想一下,后端好像MVC模式中的Controller部分????!!!!!好特么像)


具体来说,中介者模式的意图就在于:减少对象之间的混乱关系(那些让人分不清的多对多的关系)时,通过中介者进行统一管理这些对象,将对象之间的交互封装在中介者的对象里面。(一下子懵逼了??????好像没啥用,又好像有大用,到底会给我们解决什么困难?)

解决了什么问题

  • 比如我们进行聊天,用户与用户之间一定存在多对多的关系,这时候我们可以使用一个中介者(咱们的群聊)来进行统一管理,用户只需要将信息或文件发送到群里面或者上传就行,这样用户就不需要一个一个用户发送了(这是一个比较传统的问题)
  • 还有一个我们熟悉的开发问题,当然现在好像都需要这个意识。。。:一个开发中,基本上每个对象都会与其他对象发送相互作用,我们一旦引入新对象,系统的结构又要复杂很多倍,这时候我们通常会设置中介者对象,这样对象与对象之间就不会直接进行联系,而是通过中介者进行联系。
    说白了,中介者就是为了解决“依赖关系结构混乱”问题


    看到这里,基本上都理解了,这时候我们可以看看中介者模式大概如何实现了!

结构图(找的一张图不要介意。。)

应用实例

采用中介模式来说明联合国的作用,联合国实际上是一个协调性组织,各个成员国之间有下属机构WTO、WFC、WHO,他们作为各个成员国家之间的事务协调者,采用中介模式来设计该模拟系统。

抽象中介者(Mediator)角色

/**
 * @Description 联合国
 */
public interface UN {

    /**
     * 该国家在联合国进行注册
     * @param country 国家
     */
    public void register(Country country);

    /**
     * 对联合国进行事务发送请求
     * @param from 发送国
     * @param to 接受国
     * @param message 信息(这里我们只用大概来形容)
     */
    public void sendNegotiate(String from, String to, String message);
}

具体中介者(ConcreteMediator)角色:维护同事的交互关系

联合国下属机构
/**
 * @Description 联合国下属机构
 */
public class WFC implements UN{
    private Map<String, Country> countrys = new HashMap<>();


    @Override
    public void register(Country country) {
        // 检查是否已经存在过该国家
        if(!countrys.containsValue(country)) {
            countrys.put(country.getName(), country);
        }
//        country.setUn(this);

    }

    @Override
    public void sendNegotiate(String from, String to, String message) {
        Country country = countrys.get(from);
        if(country != null) {
            // 这里可以进行违禁字检查
            System.out.println(from + "发送信息给" + to + ":" + message);
            country.receiveNegotiate(to, message);
        }

    }
}
/**
 * @Description 联合国下属机构
 */
public class WHO implements  UN{
    private Map<String, Country> countrys = new HashMap<>();


    @Override
    public void register(Country country) {
        // 检查是否已经存在过该国家
        if(!countrys.containsValue(country)) {
            countrys.put(country.getName(), country);
        }
        country.setUn(this);

    }

    @Override
    public void sendNegotiate(String from, String to, String message) {
        Country country = countrys.get(from);

        if(country != null) {
            // 这里可以进行违禁字检查
            System.out.println(from + "发送信息给" + to + ":" + message);
            country.receiveNegotiate(to, message);
        }

    }
}
/**
 * @Description 联合国下属机构
 */
public class WTO implements UN{
    private Map<String, Country> countrys = new HashMap<>();


    @Override
    public void register(Country country) {
        // 检查是否已经存在过该国家
        if(!countrys.containsValue(country)) {
            countrys.put(country.getName(), country);
        }
//        country.setUn(this);

    }

    @Override
    public void sendNegotiate(String from, String to, String message) {
        Country country = countrys.get(from);
        if(country != null) {
            // 这里可以进行违禁字检查
            System.out.println(from + "发送信息给" + to + ":" + message);
            country.receiveNegotiate(to, message);
        }

    }
}

抽象同事类(Colleague)角色

/**
 * @Description
 */
public abstract class Country {

    public UN un;
    public String name;

    public Country(String name) {
        this.name = name;
    }

    public UN getUn() {
        return un;
    }

    public void setUn(UN un) {
        this.un = un;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void sendNegotiate(String to, String message);

    public void receiveNegotiate(String to, String message) {
        System.out.println(to + "接收到" + this.name + "发送的信息:" + message);
    }
}

具体同事类(Concrete Colleague)角色

/**
 * @Description
 */
public class DevelopedCoun extends Country{

    public DevelopedCoun(String name) {
        super(name);
    }

    @Override
    public void sendNegotiate(String to, String message) {
        if(un != null) {
            un.sendNegotiate(this.name, to, message);
        }else {
            System.out.println(this.name + "未加入" + to + ", 不能通过该组织发送消息");
        }
    }
}
/**
 * @Description
 */
public class DevelopingCoun extends Country{

    public DevelopingCoun(String name) {
        super(name);
    }

    @Override
    public void sendNegotiate(String to, String message) {
        if(un != null) {
            un.sendNegotiate(this.name, to, message);
        }else {
            System.out.println(this.name + "未加入" + to + ", 不能通过该组织发送消息");
        }
    }
}

实现类

/**
 * @author haoyang
 * @create 2022-11-04 18:52
 * @Description 
 */
public class Client {
    public static void main(String[] args) {
        // 设立机构
        UN un1 = new WFC();
        UN un2 = new WHO();
        UN un3 = new WTO();
        // 建立国家
        Country china, usa;
        // 设置国家类别
        china = new DevelopingCoun("中国");
        usa = new DevelopedCoun("美国");
        // 在该机构注册国家
        un1.register(china);
        un2.register(china);
        un3.register(china);
        un1.register(usa);
        un2.register(usa);
        un3.register(usa);
        // 发送信息
        china.sendNegotiate(usa.getName(), "你个傻逼");
    }
}

优缺点

优点

  • 简化了对象之间的交互,降低了类的复杂度,将一对多转换为一对一
  • 可将各同事对象解耦
  • 减少子类生成,中介者模式将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使得各个同事类可被重用,无需直接对同事类进行扩展

缺点

  • 具体中介者中包含了大量同事之间的交互细节,中介者可能会变得非常复杂庞大,可能会难以维护。

使用时注意点

1、减少类间依赖,降低了耦合,符合迪米特法则

2、多个类相互解耦,会形成网状结构,使用中介者模式将网状结构分离为星型结构,进行解耦

3、如果设计不当,中介者对象本身变得过于复杂,这点在实际使用时,要特别注意

4、中介者承担了较多的责任,一旦中介者出现了问题,整个系统就会受到影响

适用场景

1、对象之间存在复杂的引用关系,导致他们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
3、一个对象由于引用了其他很多对象并且直接和这些对象进行通信,导致了难以复用该对象

posted @ 2022-11-04 20:01  雨季悠理  阅读(271)  评论(0编辑  收藏  举报