23种常用设计模式之中介者模式

说明

中介者(Mediator)模式属于行为型模式。定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。简单的说,A想跟B通信,需要中介者M来完成。

应用场景

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。可以通过引入中介者类来实现,在中介者中定义对象交互的公共行为,如果需要改变行为则可以增加新的具体中介者类。

模式特征

角色 说明 举栗
抽象中介者(Mediator)角色 它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。 Mediator
具体中介者(ConcreteMediator)角色 实现中介者接口,定义一个集合来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。 ChatPlatform
抽象同事类(Colleague)角色 定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。 User
具体同事类(Concrete Colleague)角色 是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互 NormalUser

代码实现

  • 抽象中介者
public abstract class Mediator {
    List<User> list = new ArrayList<>();//所有在聊天室里的人存这

    abstract void sendToAll(String msg);//群发

    abstract void senToPerson(String msg, String name);//给某个人发送消息

    abstract void join(User user);//用户加入聊天室

    abstract void leave(User user);//用户离开聊天室
}
  • 具体中介者
public class ChatPlatform extends Mediator {
    @Override
    void sendToAll(String msg) {
        for (User u : list) {
            u.accept(msg);
        }
    }

    @Override
    void senToPerson(String msg, String name) {
        for (User u : list) {
            if (u.name.equals(name))
                u.accept(msg);
        }
    }

    @Override
    void join(User user) {
        list.add(user);
    }

    @Override
    void leave(User user) {
        list.remove(user);
    }
}
  • 抽象同事类
public abstract class User {

    protected Mediator mediator;
    String name;
    //在创建对象的时候就把他的中间者传入,他要发送都是通过这个中介者来做的。
    public User(String name, Mediator mediator){
        this.name = name;
        this.mediator = mediator;
    }
    abstract void sendToAll(String msg);//给所有人发消息

    abstract void senToPerson(String msg, String name);//给某个人发送消息

    abstract void accept(String msg);//接受消息

    abstract void join();//加入聊天室

    abstract void leave();//离开聊天室
}
  • 具体同事类
public class NormalUser extends User {
    public NormalUser(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    void sendToAll(String msg) {
        mediator.sendToAll(msg);
    }

    @Override
    void senToPerson(String msg, String name) {
        mediator.senToPerson(msg, name);
    }

    @Override
    void accept(String msg) {
        System.out.println(this.name + "收到消息:" + msg);
    }

    @Override
    void join() {
        mediator.join(this);
    }

    @Override
    void leave() {
        mediator.leave(this);
    }
}
  • 客户端测试
public class Client {
    public static void main(String[] args) {
        Mediator chatPlatform = new ChatPlatform();
        NormalUser a = new NormalUser("A", chatPlatform);
        NormalUser b = new NormalUser("B", chatPlatform);
        NormalUser c = new NormalUser("C", chatPlatform);
        a.join();
        b.join();
        c.join();
        System.out.println("-----------------A群发送消息------------------");
        a.sendToAll("A:大家听得到吗?");
        System.out.println("-----------------A给B私发消息------------------");
        a.senToPerson("A:B,我只想和你说", "B");
        System.out.println("-----------------B给A私发消息------------------");
        b.senToPerson("B:可以,请说", "A");
        System.out.println("-----------------A离开聊天室------------------");
        a.leave();
        System.out.println("-----------------B群发送消息------------------");
        b.sendToAll("B:A能听到吗");
    }
}
  • 结果
-----------------A群发送消息------------------
A收到消息:A:大家听得到吗?
B收到消息:A:大家听得到吗?
C收到消息:A:大家听得到吗?
-----------------A给B私发消息------------------
B收到消息:A:B,我只想和你说
-----------------B给A私发消息------------------
A收到消息:B:可以,请说
-----------------A离开聊天室------------------
-----------------B群发送消息------------------
B收到消息:B:A能听到吗
C收到消息:B:A能听到吗

优缺点

优点
  • 中介者模式简化了对象之间的交互,它用中介者和同事的一对多交互代替了原来同事之间的多对多交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星型结构。
  • 中介者模式可将各同事对象解耦。中介者有利于各同事之间的松耦合,我们可以独立的改变和复用每一个同事和中介者,增加新的中介者和新的同事类都比较方便,更好地符合 “开闭原则”。
  • 可以减少子类生成,中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。
缺点

在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。(也就是把具体同事类之间的交互复杂性集中到了中介者类中,结果中介者成了最复杂的类)

原创文章 67 获赞 31 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u012534326/article/details/102986243
今日推荐