【设计模式-4.8】行为型——中介者模式

说明:本文介绍行为型设计模式之一的中介者模式

定义

中介者模式(Mediator Pattern)又叫作调节者模式或调停者模式。用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地互相作用,从而使其耦合松散,而且可以独立地改变它们之间的交互,属于行为型设计模式。

(引自《设计模式就该这样学》P376)

中介者模式简单来说,就是引入中间层,让多对多关系,转为多个一对多关系,图示如下:

(多对多场景)

在这里插入图片描述

(引入中间层,转为多个一对多)

在这里插入图片描述

这样符合迪米特法则(指一个软件实体应当尽可能少地与其他实体发生相互作用),这样,当一个模块修改时,就会尽量少地影响其他的模块。

通讯交友

以两人通讯为例,如下,

(用户类,User)

/**
 * 用户类
 */
public class User {

    /**
     * 自己的名字
     */
    private String name;

    /**
     * 定义通话对方
     */
    private User friend;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /**
     * 建立连接
     */
    public void connect(User friend) {
        this.friend = friend;
    }

    /**
     * 说话
     * 我方说话,调用对方的listen方法
     */
    public void talk(String msg) {
        friend.listen(msg);
    }

    /**
     * 接听
     */
    private void listen(String msg) {
        System.out.println(friend.name + " 对 " + name + " 说:" + msg);
    }
}

(客户端使用,进行聊天)

public class Client {
    public static void main(String[] args) {
        User zhangsan = new User("zhangsan");
        User lisi = new User("lisi");

        zhangsan.connect(lisi);
        lisi.connect(zhangsan);

        zhangsan.talk("hello,四哥,我是三哥啊,您最近挺好的啊?");
        lisi.talk("哦,三哥啊,我以为谁呢,我挺好的,您呢?");
    }
}

开始通话

在这里插入图片描述

现在只有两个人,这种设计看起来没有问题,但如果有十个人,开一场多人会议,就要在对象内维护一个User集合,而会议人数新增或减少时,要同时改动每个对象中的User集合,这非常繁琐还容易出问题。

聊天室

基于上面代码的问题,我们引入一个中间层(聊天室),如下:

(用户类,User,定义一个所属聊天室)

/**
 * 用户类
 */
public class User {

    /**
     * 自己的名字
     */
    private String name;

    /**
     * 所属聊天室
     */
    private Chatroom chatRoom;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /**
     * 加入群聊
     */
    public void login(Chatroom chatRoom) {
        this.chatRoom = chatRoom;
        chatRoom.register(this);
    }

    /**
     * 群内发言
     */
    public void talk(String msg) {
        chatRoom.sendMsg(this, msg);
    }

    /**
     * 接收消息
     */
    public void listen(User fromUser, String msg) {
        System.out.println("【" + this.name + "】的聊天框 【" + fromUser.getName()  + "】说:" + msg);
    }
}

(聊天室,用来管理群成员,发消息等操作)

import java.util.ArrayList;
import java.util.List;

/**
 * 聊天室
 */
public class Chatroom {

    /**
     * 群名称
     */
    private String name;

    public Chatroom(String name) {
        this.name = name;
    }

    /**
     * 群内好友
     */
    private List<User> users = new ArrayList<>();

    /**
     * 好友加入群聊
     */
    public void register(User user) {
        this.users.add(user);
        System.out.println("【系统消息】" + user.getName() + "进入群聊");
    }

    /**
     * 群内发消息
     */
    public void sendMsg(User fromUser, String msg) {
        users.stream().forEach(user -> user.listen(fromUser, msg));
        System.out.println("-------------------------------------------------");
    }
}

(客户端测试,Client)

public class Client {
    public static void main(String[] args) {
        // 创建群,好友
        Chatroom chatroom = new Chatroom("各位IT界的大佬们");
        User zhangsan = new User("zhangsan");
        User lisi = new User("lisi");
        User wangwu = new User("王五");

        // 好友加入群聊
        zhangsan.login(chatroom);
        lisi.login(chatroom);

        // 发消息
        zhangsan.talk("hello,四哥,群里就你一个人啊");
        lisi.talk("是啊,把五哥拉进来");

        // 拉人进群
        wangwu.login(chatroom);

        // 发消息
        zhangsan.talk("哇,五哥来了");
        wangwu.talk("哥几个,怎么说");
    }
}

怎么样,这样设计是不是好多了,结构一下就稳定了,无论群成员增加还是减少,现有代码都不用改动。

在这里插入图片描述

使用场景

在《设计模式就该这样学》(P378)这本书中,提到状态模式适用于以下场景:

(1)系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。

(2)交互的公共行为,如果需要改变行为,则可以增加新的中介者类。

中介者模式,在Java三层结构开发中就有体现,Service层不会直接访问数据库,而是抽出DAO层,使用DAO对象访问数据库,就是中介者模式的一种体现,还有Spring IOC容器也是,将Bean的创建使用抽离出来统一管理。

还有,有时我们业务中,有种业务场景,没有与之对应的实体(像User对应UserService、UserDAO),而是业务逻辑中产生的对象,如CheckService(检查服务,根据日志表、用户表,检查用户状态是否正常),我们不直接在UserService里实现,而是抽出一个CheckService,这也是中介者模式的一种实现。

总结

本文介绍了行为型设计模式中的中介者模式,参考《设计模式就该这样学》、《秒懂设计模式》两书,通讯交友、聊天室场景是《秒懂设计模式》中的举例。

### 如何在 Ubuntu 系统中安装 gcc-4.8 和 g++-4.8 编译器 为了在较新的 Ubuntu 版本中成功安装特定版本的 `gcc` 和 `g++` 编译器(如 4.8),可以按照以下方法操作。需要注意的是,某些新版本的 Ubuntu 可能不再官方支持旧版本的 GCC/G++,因此可能需要手动配置 PPA 或者从源码编译。 #### 方法一:通过 PPA 安装 PPA (Personal Package Archive) 提供了一种简单的方式来获取更新或者更早版本的软件包。对于安装 `gcc-4.8` 和 `g++-4.8`,可以执行如下命令: ```bash sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-4.8 g++-4.8 ``` 上述命令会添加工具链测试仓库并安装所需的编译器版本[^3]。 #### 方法二:设置默认编译器版本 如果系统已经存在多个版本的 GCC/G++ 并希望切换到 `gcc-4.8` 和 `g++-4.8`,可以通过 `update-alternatives` 命令实现: ```bash sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 20 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 20 sudo update-alternatives --config gcc sudo update-alternatives --config g++ ``` 这一步骤允许用户选择当前系统的默认编译器版本[^5]。 #### 方法三:从源码构建 当无法通过标准包管理器获得所需版本时,可以从源代码自行编译和安装。具体步骤如下: 1. **安装必要的依赖项** ```bash sudo apt-get update sudo apt-get install build-essential libmpfr-dev libmpc-dev libgmp-dev texinfo bison flex ``` 2. **下载 GCC 源码** 访问 [GCC 官方网站](https://gcc.gnu.org/) 获取对应版本的压缩文件,并解压: ```bash wget https://ftp.gnu.org/gnu/gcc/gcc-4.8.5/gcc-4.8.5.tar.gz tar -xf gcc-4.8.5.tar.gz cd gcc-4.8.5 ``` 3. **准备环境变量** 配置路径以便于后续编译过程顺利运行: ```bash export PREFIX="/usr/local" export PATH="$PREFIX/bin:$PATH" ``` 4. **编译与安装** 创建单独目录用于存储编译产物,随后启动编译流程: ```bash mkdir objdir && cd objdir ../configure --prefix=$PREFIX --enable-languages=c,c++ --disable-multilib make -j$(nproc) sudo make install ``` 此方法适用于任何 Linux 发行版,但需注意其复杂性和潜在错误风险较高[^4]。 --- ### 注意事项 - 如果目标平台为最新版本的 Ubuntu,则可能存在兼容性问题,建议查阅发行说明确认是否仍可使用此类低版本编译器。 - 使用过时的编译器可能导致安全漏洞或缺乏对现代 C/C++ 标准的支持,应谨慎评估需求后再决定采用何种方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何中应

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值