调停者模式

Posted qlqwjy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调停者模式相关的知识,希望对你有一定的参考价值。

  调停者(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、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

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

 

以上是关于调停者模式的主要内容,如果未能解决你的问题,请参考以下文章

调停者模式

Java设计模式之调停者模式

《Java设计模式》之调停者模式(Mediator)

调停者模式

Java 设计模式 之 调停者模式

调停者模式