简易理解设计模式之:中介者模式——多人聊天室例子

介绍:

中介者模式属于行为型模式。它的定义为:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互调用,从而使其耦合松散,而且可以独立地改变他们之间的交互。

类图:
中介者模式UML类图.png
Mediator(抽象中介者角色):定义一个接口用于各同事之间的通讯。
ConcreteMediator(具体中介者角色):它从具体的同事对象接受信息,向具体同事对象发出命令,负责协调同事之间的交互。
Colleague(抽象同事角色):通过中介者对象与其它同事类进行交互,并定义所有相互影响的同事类的公共功能。
ConcreteColleagueA/B(具体同事角色):继承于Colleague,每个具体同事类都知道本身在小范围内的行为,而不知道它在大范围内的目的。

用法:
当对象之间的关系复杂且相互依赖时,为防止修改一个对象的行为同时涉及修改很多其它对象的行为,可使用中介者模式。

个人理解:
中介者模式的核心逻辑就是解耦对象‘多对多’的相互依赖关系。当遇到一大堆混乱的对象呈现“网状结构”,利用通过中介者模式解耦对象之间的通讯。理解上就是下图所示:

从“网状结构”到“星型结构”.png
例子:
日常生活中,我们经常会用社交工具(QQ、微信)进行聊天。在这其中,群组聊天的设计正是中介者模式的例子,我们下面模拟一下:

设计思路:每个聊天用户就相当于同事类,聊天服务器就相当于我们的中介者。整个流程是用户向聊天服务器发送一条消息,服务器会将此消息发送给群组中的所有人。

设计多人聊天群组
1、创建抽象中介者角色

public abstract class ChatMediator {
    public abstract void register(ChatClient client);
    public abstract void notice(ChatClient client,String message);
}

定义一些接口用于同事类的通讯。在这里我们定义一个加入群聊的行为和向所有人发送通知的行为。

2、实现具体中介者角色

public class ChatServer extends ChatMediator {

    private List<ChatClient> clientList = new ArrayList<>();

    @Override
    public void notice(ChatClient client, String message) {
        for (ChatClient c : clientList) {
            if (!client.equals(c)) {
                c.receiveMessage(message);
            }
        }
    }

    @Override
    public void register(ChatClient client) {
        if (client != null && !clientList.contains(client)) {
            clientList.add(client);
        }
    }

}

具体中介者负责协调同事类之间的交互,notice()方法向所群组中除了自己之外的用户发送消息。

3、创建抽象同事类

public abstract class ChatClient {
    protected ChatMediator mediator;

    public ChatClient(ChatMediator mediator){
        this.mediator = mediator;
    }

    public abstract void sendMessage(String message);
    public abstract void receiveMessage(String message);
}

每个用户都有一个发送消息的方法和接收消息的方法,而消息的传递则通过中介者对象mediator处理。

4、实现具体同事类

public class Andy extends ChatClient {

    public Andy(ChatMediator mediator) {
        super(mediator);
        mediator.register(this);
    }

    @Override
    public void sendMessage(String message) {
        System.out.println();
        System.out.println("安迪发送一条消息:" + message);
        mediator.notice(this, message);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("安迪收到一条消息:" + message);
    }
}

具体同事类忽略Ben、Cat、David等等的用户,实现相似!

对于每个具体同事类(用户)而言,它并不需要知道这个群里面到底有多少人,只知道自己是负责发送和接收消息的。

5、测试与运行结果

public class Group {

    public static void main(String[] args) {
        //聊天服务器
        ChatServer chatServer = new ChatServer();

        //三个小伙伴
        Andy andy = new Andy(chatServer);
        Ben ben = new Ben(chatServer);
        Cat cat = new Cat(chatServer);

        System.out.println("=====群聊信息=====");
        andy.sendMessage("今晚去看复仇者联盟4吧!");
        System.out.println("-----——分割线——-----");
        ben.sendMessage("好啊好啊~我期待了很久!");
        System.out.println("-----——分割线---——--");
        cat.sendMessage("我来负责买票!!!");
    }
}
=====群聊信息=====

安迪发送一条消息:今晚去看复仇者联盟4吧!
Ben哥收到一条消息:今晚去看复仇者联盟4吧!
猫猫收到一条消息:今晚去看复仇者联盟4吧!
-----——分割线——-----
Ben哥发送一条消息:好啊好啊~我期待了很久!
安迪收到一条消息:好啊好啊~我期待了很久!
猫猫收到一条消息:好啊好啊~我期待了很久!
-----——分割线---——--
猫猫发送一条消息:我来负责买票!!!
安迪收到一条消息:我来负责买票!!!
Ben哥收到一条消息:我来负责买票!!!

每个用户直接调用sendMessage()的方法就可以完成通讯了,就算是一个100人的大群每个用户也不用改动代码~

总结:
• 中介者模式大大的好处就是降低类的关系复杂度,使对象可以更好地维护和扩展。将多对多的“网状结构”转化成一对多的“星型结构”,复杂的交互逻辑交给了中介者了。

• 这个模式就是迪米特原则的具体体现。复习一下迪米特原则:

迪米特原则(Law Of Demeter,LOD),也称最少知识原则。定义一个对象应该对其他对象有最少的了解。

意思是只与朋友通讯(关联度很高的类)。每个类都会必然用到其它类的属性和方法,这称为耦合。设计类的时候要把功能拆分,尽可能使用一个第三者的朋友来进行两者间的通讯。

• 另外,新手写代码很容易出现一个类文件有上千行代码,N个成员变量放在一起相互调用。所以也不用急于使用中介者模式优化代码,需要考虑整个设计上是不是存在不合理的地方。

感谢您的阅读~

推荐阅读

基础篇:
设计模式前篇之——UML类图必会知识点
设计模式前篇之——一起过一下面向对象的概念
创建型模式:
简易理解设计模式之:简单工厂模式——来试试接入支付功能
简易理解设计模式之:工厂方法模式——数据存储例子
简易理解设计模式之:抽象工厂模式——更换数据库例子
简易理解设计模式之:建造者模式——学习使用“链式调用”
简易理解设计模式之:原型模式——深、浅拷贝的概念
简易理解设计模式之:单例模式——单例模式的几种常用写法
结构型模式:
简易理解设计模式之:适配器模式——Android列表视图控件设计方式
简易理解设计模式之:桥接模式——穿衣服经典案例2
简易理解设计模式之:组合模式——实现View中的树状结构
简易理解设计模式之:装饰模式——穿衣服经典案例
简易理解设计模式之:外观模式——第三方SDK的帮助类
简易理解设计模式之:享元模式——五子棋游戏例子
简易理解设计模式之:代理模式——iOS视图控件设计方式
行为型模式:
简易理解设计模式之:策略模式——优化一下支付功能
简易理解设计模式之:模板方法模式——Android中的BaseActivity基类
简易理解设计模式之:观察者模式——监听与回调
简易理解设计模式之:状态模式——优化登录操作
简易理解设计模式之:备忘录模式——Word文档的工作原理
简易理解设计模式之:迭代器模式——遍历对象的好帮手
简易理解设计模式之:命令模式——实现命令的参数化配置
简易理解设计模式之:责任链模式——OA中请假流程示例
简易理解设计模式之:中介者模式——多人聊天室例子
简易理解设计模式之:解释器模式——语言和文法
简易理解设计模式之:访问者模式——员工考核例子

posted @ 2022-11-21 18:56  TwcatL_tree  阅读(42)  评论(0编辑  收藏  举报