zoukankan      html  css  js  c++  java
  • 调停者模式

      调停者(Mediator)模式又称为中介者模式,包装了一系列对象相互作用的方式,使得这些对象不必互相明显引用。从而使它们可以较松散的耦合。当这些对象中的某些对象之间的相互作用发生变化时,不会立即影响到其他的一些对象之间的相互作用。从而保证这些相互作用可以彼此独立地变化。

    0.中国加入WTO的例子

      WTO是一个协调组织,各个贸易地区可以由WTO进行组织。WTO扮演的正是协调者的角色,它取代了原本由各个地区进行协调和谈判的强耦合关系,各个贸易地区加入世界贸易组织前的贸易状态如下:

      WTO使得各个贸易地区之间的强关联关系变为较为松散的耦合关系, 各个贸易地区加入世界贸易组织的贸易状态如下:

    1.结构

    结构如下:

    涉及到的角色如下:

    抽象调停者(Mediator)角色:定义出同事对象到调停者对象的接口,其中主要方法是一个(或多个)事件方法。
    具体调停者(ConcreteMediator)角色:实现了抽象调停者所声明的事件方法。具体调停者知晓所有的具体同事类,并负责具体的协调各同事对象的交互关系。
    抽象同事类(Colleague)角色:定义出调停者到同事对象的接口。同事对象只知道调停者而不知道其余的同事对象。
    具体同事类(ConcreteColleague)角色:所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的调停者通信,调停者会负责与其他的同事交互。

    源码如下:

    抽象调停者:声明一个抽象方法colleagueChange,这就是所谓的事件方法。当自身的状态发生变化的时候,一个同事对象可以调用这个事件方法来通知调停者,从而更新有关的同事对象。

    package mediator;
    
    /**
     * 抽象调停者
     *
     */
    public abstract class AbstractMediator {
    
        /**
         * 同事改变的时候通知调停者,调停者负责与其他同事交互
         * 
         * @param abstractColleague
         */
        public abstract void colleagueChange(AbstractColleague abstractColleague);
    
    }

    具体调停者:

    package mediator;
    
    /**
     * 具体调停者
     *
     */
    public class ConcreteMediator extends AbstractMediator {
    
        private Colleague1 Colleague1;
    
        private Colleague2 Colleague2;
    
        @Override
        public void colleagueChange(AbstractColleague abstractColleague) {
            // 同事改变,协调其他同事类
        }
    
        public void setColleague1(Colleague1 colleague1) {
            Colleague1 = colleague1;
        }
    
        public void setColleague2(Colleague2 colleague2) {
            Colleague2 = colleague2;
        }
    
    }

    抽象同事类:声明一个action方法,当收到其他同事类改变后执行这个方法

    package mediator;
    
    /**
     * 抽象同事
     *
     */
    public abstract class AbstractColleague {
    
        private AbstractMediator mediator;
    
        public AbstractColleague(AbstractMediator mediator) {
            super();
            this.mediator = mediator;
        }
    
        /**
         * 具体的行动方法,由子类实现(商业方法)
         */
        public abstract void action();
    
        public void change() {
            mediator.colleagueChange(this);
        }
    
        public AbstractMediator getMediator() {
            return mediator;
        }
    
    }

    具体同事类:每个同事仅知道调停者,无需知道其他同事

    package mediator;
    
    /**
     * 具体同事类1
     *
     */
    public class Colleague1 extends AbstractColleague {
    
        public Colleague1(AbstractMediator mediator) {
            super(mediator);
        }
    
        @Override
        public void action() {
            // 执行操作
            System.out.println("Colleague1 action");
    
            // 通知调停者
            getMediator().colleagueChange(this);
        }
    
    }
    package mediator;
    
    /**
     * 具体同事类2
     *
     */
    public class Colleague2 extends AbstractColleague {
    
        public Colleague2(AbstractMediator mediator) {
            super(mediator);
        }
    
        @Override
        public void action() {
            // 执行操作
            System.out.println("Colleague2 action");
    
            // 通知调停者
            getMediator().colleagueChange(this);
        }
    
    }

    2.简单的聊天室案例

      多个用户可以向聊天室发送消息,聊天室向所有的用户显示消息。我们将创建两个类 ChatRoom 和 User。User 对象使用 ChatRoom 方法来分享他们的消息。ChatRoom 就相当于调停者。

    代码:

    ChatRoom:

    package mediator;
    
    import java.util.Date;
    
    public class ChatRoom {
    
        public static void showMessage(User user, String message) {
            System.out.println(new Date().toString() + " [" + user.getName() + "] : " + message);
        }
    }

    User:

    package mediator;
    
    public class User {
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public User(String name) {
            this.name = name;
        }
    
        public void sendMessage(String message) {
            ChatRoom.showMessage(this, message);
        }
    }

    测试类:

    package mediator;
    
    public class Client {
    
        public static void main(String[] args) {
            User a = new User("A");
            User b = new User("B");
    
            a.sendMessage("Hi! B!");
            b.sendMessage("Hello! A!");
        }
    }

    结果:

    Mon Nov 04 14:35:51 CST 2019 [A] : Hi! B!
    Mon Nov 04 14:35:51 CST 2019 [B] : Hello! A!

    3.总结

      调停者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

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

    主要解决:对象与对象之间存在大量的关联关系,这样势必会导致系统的结构变得很复杂,同时若一个对象发生改变,我们也需要跟踪与之相关联的对象,同时做出相应的处理。

    何时使用:多个类相互耦合,形成了网状结构。

    如何解决:将网状结构分离为星型结构。

    关键代码:对象 Colleague 之间的通信封装到一个类中单独处理。

    应用实例: 1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。 2、机场调度系统。 3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

    优点: 1、降低了类的复杂度,将一对多转化成了一对一。 2、各个类之间的解耦。 3、符合迪米特原则。

    缺点:中介者会庞大,变得复杂难以维护。

    使用场景: 1、系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱而且难以复用该对象。 2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

    注意事项:不应当在职责混乱的时候使用。

  • 相关阅读:
    es6小记
    CPU密集型和I/O密集型区别
    Gulp小记
    原生表单的小详解
    div无法触发blur事件解决办法
    HMTL列表详解
    Angular开发小笔记
    Angular组件生命周期钩子
    css小笔记
    HTML格式化标签
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/11700130.html
Copyright © 2011-2022 走看看