前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简易理解设计模式之:中介者模式——多人聊天室例子

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

作者头像
Twcat_tree
发布2022-11-29 17:05:49
4300
发布2022-11-29 17:05:49
举报
文章被收录于专栏:二猫の家

介绍:

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

类图:

中介者模式UML类图.png
中介者模式UML类图.png

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

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

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

从“网状结构”到“星型结构”.png
从“网状结构”到“星型结构”.png

例子: 日常生活中,我们经常会用社交工具(QQ、微信)进行聊天。在这其中,群组聊天的设计正是中介者模式的例子,我们下面模拟一下:

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

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

代码语言:javascript
复制
public abstract class ChatMediator {
    public abstract void register(ChatClient client);
    public abstract void notice(ChatClient client,String message);
}

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

2、实现具体中介者角色

代码语言:javascript
复制
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、创建抽象同事类

代码语言:javascript
复制
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、实现具体同事类

代码语言:javascript
复制
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、测试与运行结果

代码语言:javascript
复制
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("我来负责买票!!!");
    }
}
代码语言:javascript
复制
=====群聊信息=====

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

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

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

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

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

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

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

感谢您的阅读~

推荐阅读

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档