设计模式内容分享(二十):中介者模式

本文详细介绍了中介者模式的概念、适用场景、结构、实现方法,强调了其在降低系统复杂性和耦合度方面的优势,并对比了与其他设计模式的区别。
摘要由CSDN通过智能技术生成

目录

一、中介者模式是什么

二、中介者模式的适用场景

三、中介者模式结构

四、中介者模式实现方式

五、中介者模式的实现

六、中介者模式的优缺点

七、中介者模式和其他模式的区别

八、总结



f055fc2866b14165a50067b273247d32.png

一、中介者模式是什么

  • 定义

    是用来降低多个对象和类之间的通信复杂性。通过一个中介类处理不同类之间的通信,并支持松耦合,使代码易于维护。

  • 特性

    中介者模式又叫调停模式,是迪米特法则的典型应用,属于行为型模式。

  • 主要作用

    • 当对象与对象之间存在大量的关联关系时,系统的结构变得很复杂,牵一发而动全身,属于一种【网状结构】。中介者模式通过一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互,属于一种【星形结构】。

    • 对象之间的关联关系由【网状结构】变为【星形结构】可以将大大降低它们之间的耦合性。

  • 1e660f2b174442a48d5574bb10c22d58.png

二、中介者模式的适用场景

  • 适用场景

    • 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时,可使用中介者模式。

    • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时,可使用中介者模式。

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

  • 【生活案例】

    • MVC 框架中,控制器(C)就是模型(M)和视图(V)的中介者

    • 微信聊天的中服务器是用户之间的中介者。

    • 房产中介是房屋买卖双方的中介者。

    • 塔台是飞机之间的中介者。

bdd63dd7b5cf40fa852a91a63c1e0087.png

三、中介者模式结构

  • 抽象中介者(Mediator)角色:定义统一的接口,用于各组件角色之间的通信,提供了组件对象注册与转发组件对象信息的抽象方法。

  • 具体中介者(Concrete Mediator)角色:实现中介者接口,通过一个List 来管理组件对象,协调各个组件角色之间的交互关系,有时会对组件角色生命周期进行管理。

  • 抽象组件类(Component)角色:定义组件类的接口,持有一个中介者对象的引用,提供组件对象交互的抽象方法,实现组件类的公共行为。

    网上很多人把抽象组件类(Component)角色称之为抽象同事类(Colleague)角色,是一个意思,只是我个人喜欢叫组件,所以本文都称为组件类。

  • 具体组件类(Concrete Component)角色:继承抽象组件类,实现自己的业务,它并不知道其他组件类的具体行为,在需要时通过与中介者通信,中介者会负责与其它的组件交互。

  • 客户端(Client)角色:创建具体中介者对象,并将具体组件类并与该中介者进行绑定。

82be314372dc4c9e99a773cc36edda36.png

四、中介者模式实现方式

  • 声明中介者接口并描述中介者和各种组件之间所需的交流接口。通常仅包括一个通知方法

  • 声明具体中介者类实现中介者接口,**持有一个List 来管理组件对象。**也可以让中介者负责组件对象的创建和销毁。

  • 声明抽象组件抽象类,持有一个中介者对象的引用,通过构造函数建立与中介者的连接。声明公共方法。

  • 声明具体组件类,继承抽象组件类,实现调用中介者的通知方法。

  • 客户端创建具体中介者对象,并将具体组件类并与该中介者进行绑定。

五、中介者模式的实现

【案例】:多架飞机需要跑道降落,塔台指挥。

【案例说明】:每一架飞机都是一个组件,拥有一些相同的行为,塔台作为中介者指挥飞机降落。

  • 抽象中介者(Mediator)角色

    /**
     * 抽象中介者(Mediator)角色 : 塔台
     */
    publicinterface TowerMediator {
        /**
         * 通知方法 : 通知飞机降落
         * @param track
         */
        public abstract void notify(String type,String track);
    
        /**
         * 在中介者中添加组件类
         * @param colleague
         */
        public abstract void register(AirplaneComponent colleague);
        /**
         * 在中介者中移除组件类
         * @param colleague
         */
        public abstract void remove(AirplaneComponent colleague);
    }
    	
    
  • 具体中介者(Concrete Mediator)角色

    /**
     * 具体中介者(Concrete Mediator)角色 : 塔台实现类
     */
     publicclass AirlinerConcreteMediator implements TowerMediator{
        /**
         * 持有一个List 来管理组件对象。
         */
        private List<AirplaneComponent> colleagues;
        public AirlinerConcreteMediator() {
            this.colleagues = new ArrayList<AirplaneComponent>();
        }
    
        @Override
        public void notify(String type,String track) {
            for (AirplaneComponent airplaneComponent : colleagues) {
                if(!type.equalsIgnoreCase(airplaneComponent.airplaneType)){
                    continue;
                }
                airplaneComponent.landing(track);
            }
        }
    
        @Override
        public void register(AirplaneComponent colleague) {
            colleagues.add(colleague);
        }
    
        @Override
        public void remove(AirplaneComponent colleague) {
            colleagues.remove(colleague);
        }
    }
    
  • 抽象组件类(Component)角色

    /**
     * 抽象组件类(Component)角色 : 飞机
     */
    publicabstractclass AirplaneComponent {
        /**
         * 用于区分飞机的类型
         */
        public String airplaneType;
        /**
         * 持有一个中介者对象的引用
         */
        private TowerMediator towerMediator;
        public AirplaneComponent(String airplaneType,TowerMediator towerMediator) {
            this.airplaneType = airplaneType;
            this.towerMediator = towerMediator;
        }
    
        public abstract void landing(String track);
    }
    
  • 具体组件类(Concrete Component)角色

    /**
     * 具体组件类(Concrete Component)角色 : 客机
     */
    publicclass AirlinerConcreteComponent extends AirplaneComponent{
        /**
         * 通过构造函数建立与中介者的连接
         * @param towerMediator
         */
        public AirlinerConcreteComponent(String airplaneType,TowerMediator towerMediator) {
            super(airplaneType,towerMediator);
        }
    
        @Override
        public void landing(String track) {
            System.out.println("接到塔台通知,客机在" + track + "跑道降落!");
        }
    }
    
    
    
    /**
     * 具体组件类(Concrete Component)角色 : 战斗机
     */
    publicclass FighterConcreteComponent extends AirplaneComponent{
    
        /**
         * 通过构造函数建立与中介者的连接
         * @param towerMediator
         */
        public FighterConcreteComponent(String airplaneType,TowerMediator towerMediator) {
            super(airplaneType,towerMediator);
        }
    
        @Override
        public void landing(String track) {
            System.out.println("接到塔台通知,战斗机在" + track + "跑道降落!");
        }
    }
    
    
    
  • 客户端代码实现

    public static void main(String[] args) {
            /**
             * 创建具体中介者对象
             */
            TowerMediator towerMediator = new AirlinerConcreteMediator();
            /**
             * 将具体组件类并与该中介者进行绑定。
             */
            towerMediator.register(new AirlinerConcreteComponent("客机",towerMediator));
            towerMediator.register(new FighterConcreteComponent("战斗机",towerMediator));
            towerMediator.notify("客机","1");
            towerMediator.notify("战斗机","2");
        }
    
  • 案例输出结果

ac4d6fa7b3224a2180534e42b9ec04d7.png

六、中介者模式的优缺点

  • 符合单一职责原则,多个组件间的交流抽取到中介者中, 使其更易于理解和维护。

  • 符合迪米特法则,组件类之间各司其职。

  • 符合开闭原则,无需修改实际组件类就能增加新的中介者。

  • 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,降低了对象之间的耦合性,使得系统易于维护和扩展。

七、中介者模式和其他模式的区别

  • 【外观模式】和【中介者模式】的职责类似:它们都尝试在大量紧密耦合的类中组织起合作。

    • 外观模式为子系统中的所有对象定义了一个简单接口, 但是它不提供任何新功能。子系统本身不会意识到外观的存在。子系统中的对象可以直接进行交流。

    • 中介者模式将系统中组件的沟通行为中心化。各组件只知道中介者对象, 无法直接相互交流。

  • 【中介者模式】和【观察者模式】非常类似

    很多时候我们可以使用中介者模式来实现观察者模式, 中介者对象担当发布者的角色, 其他组件则作为订阅者, 可以订阅中介者的事件或取消订阅。

    • 中介者模式的目标是通过同一个中介者对象消除一系列系统组件之间的相互依赖。

    • 观察者模式的目标是在对象之间建立动态的单向连接, 使得部分对象可作为其他对象的附属发挥作用。

    • 中介者模式与业务相关,订阅/发布模式与业务无关。

八、总结

中介者是迪米特法则的一个典型应用,通过引入中介者对象,可以将系统的【网状结构】变成以中介者为中心的【星形结构】,中介者承担了中转作用和协调作用,简化了对象之间的交互,还可以进一步的控制组件类之间的交互。

 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
终端终结者是一个在Ubuntu上使用的终端模拟器。您可以按照以下步骤来安装和使用终端终结者: 1. 打开终端(按下Ctrl+Alt+T)。 2. 运行以下命令来安装终端终结者:sudo apt-get install terminator 3. 安装完成后,您可以通过在应用程序菜单中搜索“终端终结者”或在终端中运行“terminator”命令来打开它。 4. 一旦打开终端终结者,您可以右键单击终端窗口,并选择“水平”或“垂直”方向来扩展一个新的终端。这样,您就可以在一个窗口中同时操作多个终端。 如果遇到终端终结者无响应的问题,可能是由于系统默认的Python版本设置为Python 3导致的。这时您可以按照以下方法解决: 1. 打开终端终结者的启动文件。您可以通过运行以下命令来找到启动文件的位置:which terminator 2. 打开启动文件并进行编辑。例如,如果启动文件是“/usr/bin/terminator”,则可以运行以下命令来编辑它:sudo nano /usr/bin/terminator 3. 在打开的文件中,找到以“#!/usr/bin/python”开头的一行,并将其修改为“#!/usr/bin/python2”。 4. 保存并关闭文件。 5. 再次尝试运行终端终结者,应该可以正常启动了。 希望这些信息能够帮助您解决问题。如果您有任何其他相关问题,请随时提问。 相关问题: 1. 如何卸载终端终结者? 2. 如何在终端终结者中创建自定义布局? 3. 如何在终端终结者中设置快捷键?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值