中介模式Mediator

一 概述

中介,是作为多个事物之间充当交互沟通的媒介,在程序也是这样的,对象与对象之间不需要持有对方引用,而是通过中介相互连接;

二 使用示例

使用聊天室作为中介,支持用户登录、用户注销、用户发言;

package cn.hello;

/**
 * 聊天室里的用户
 *
 * @author:wjm
 * @date:2020/6/23 22:41
 */
public class User {

    /**
     * 用户名字
     */
    private String name;

    /**
     * 聊天室引用
     */
    private ChatRoom chatRoom;

    /**
     * 限制创建用户时必须起名字
     *
     * @param name
     */
    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }

    /**
     * 用户登陆
     *
     * @param chatRoom
     */
    public void login(ChatRoom chatRoom) {
        //连接到聊天室
        chatRoom.connect(this);
        //注入聊天室引用
        this.chatRoom = chatRoom;
    }

    /**
     * 用户注销
     *
     * @param chatRoom
     */
    public void logout(ChatRoom chatRoom) {
        //连接到聊天室
        chatRoom.disconnect(this);
        //销毁聊天室
        this.chatRoom = null;
    }

    /**
     * 用户发言
     *
     * @param msg
     */
    public void talk(String msg) {
        if (chatRoom == null) {
            System.out.println("用户" + this.name + "已退出,无法继续发言");
            return;
        }
        //给聊天室发消息(绑定了用户与信息)
        chatRoom.sendMsg(this, msg);
    }

    /**
     * 接收信息
     *
     * @param fromWhom
     * @param msg
     */
    public void receive(User fromWhom, String msg) {
        System.out.println("【" + this.name + "的对话框】" + fromWhom.getName() + " 说: " + msg);
    }
}
package cn.hello;

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

/**
 * 聊天室
 *
 * @author:wjm
 * @date:2020/6/23 22:47
 */
public class ChatRoom {
    /**
     * 聊天室名字
     */
    private String name;

    /**
     * 聊天室里的用户们
     */
    List<User> userList = new ArrayList<>();

    /**
     * 限制创建聊天室时必须起名字
     *
     * @param name
     */
    public ChatRoom(String name) {
        this.name = name;
    }

    /**
     * 连接聊天室,用户加入
     *
     * @param user
     */
    public void connect(User user) {
        //将用户加入聊天室列表
        userList.add(user);
        System.out.println("欢迎【" + user.getName() + "】加入聊天室【" + this.name + "】");
    }

    /**
     * 离开聊天室,用户退出
     *
     * @param user
     */
    public void disconnect(User user) {
        //将用户从聊天室列表移出
        Iterator<User> iterator = userList.iterator();
        while (iterator.hasNext()) {
            User userInChatRoom = iterator.next();
            if (userInChatRoom == user) {
                iterator.remove();
            }
        }
        System.out.println("【" + user.getName() + "】离开聊天室【" + this.name + "】");
    }

    /**
     * 发送信息 给 聊天室里 除了发送方之外的 其他所有用户
     *
     * @param fromWhom
     * @param msg
     */
    public void sendMsg(User fromWhom, String msg) {
        userList.stream().filter(user ->
                //过滤掉发送方fromWhom
                !user.equals(fromWhom))
                //发送消息给剩下的所有人
                .forEach(toWhom -> toWhom.receive(fromWhom, msg));
    }
}
package cn.hello;

/**
 * 应用
 *
 * @author:wjm
 * @date:2020/6/23 22:56
 */
public class Test {
    public static void main(String[] args) {
        ChatRoom chatRoom = new ChatRoom("聊天室1");
        User user1 = new User("小明1");
        User user2 = new User("小明2");
        User user3 = new User("小明3");
        User user4 = new User("小明4");
        User user5 = new User("小明5");
        User user6 = new User("小明6");
        User user7 = new User("小明7");
        User user8 = new User("小明8");
        User user9 = new User("小明9");

        user1.login(chatRoom);
        user2.login(chatRoom);
        user3.login(chatRoom);
        user4.login(chatRoom);
        user5.login(chatRoom);
        user6.login(chatRoom);
        user7.login(chatRoom);
        user8.login(chatRoom);
        user9.login(chatRoom);

        System.out.println();

        user1.talk("大家好,我来了");

        System.out.println();

        user3.logout(chatRoom);
        user4.logout(chatRoom);
        user5.logout(chatRoom);
        user6.logout(chatRoom);
        user7.logout(chatRoom);
        user8.logout(chatRoom);
        user9.logout(chatRoom);

        System.out.println();

        //测试注销是否生效
        user3.talk("大家好,我来了");

        /*************************以下为输出************************/
        /*
        欢迎【小明1】加入聊天室【聊天室1】
        欢迎【小明2】加入聊天室【聊天室1】
        欢迎【小明3】加入聊天室【聊天室1】
        欢迎【小明4】加入聊天室【聊天室1】
        欢迎【小明5】加入聊天室【聊天室1】
        欢迎【小明6】加入聊天室【聊天室1】
        欢迎【小明7】加入聊天室【聊天室1】
        欢迎【小明8】加入聊天室【聊天室1】
        欢迎【小明9】加入聊天室【聊天室1】

        【小明2的对话框】小明1 说: 大家好,我来了
        【小明3的对话框】小明1 说: 大家好,我来了
        【小明4的对话框】小明1 说: 大家好,我来了
        【小明5的对话框】小明1 说: 大家好,我来了
        【小明6的对话框】小明1 说: 大家好,我来了
        【小明7的对话框】小明1 说: 大家好,我来了
        【小明8的对话框】小明1 说: 大家好,我来了
        【小明9的对话框】小明1 说: 大家好,我来了

        【小明3】离开聊天室【聊天室1】
        【小明4】离开聊天室【聊天室1】
        【小明5】离开聊天室【聊天室1】
        【小明6】离开聊天室【聊天室1】
        【小明7】离开聊天室【聊天室1】
        【小明8】离开聊天室【聊天室1】
        【小明9】离开聊天室【聊天室1】

         用户小明3已退出,无法继续发言
         */
    }
}

以上只是最简单的聊天室发言方式,如果需求变得复杂,例如有了不同的用户,或是聊天室也各不相同并加入了各自的特性,那我们就需要继续重构,抽象聊天室类,抽象用户类,读者可以灵活运用等;

三 总结

中介模式不止是在生活中广泛应用,在软件架构中也非常常见,如微服务分布式软件架构所用到的注册中心Eureka,其作用就是为众多分布式服务提供注册发现服务,它充当了像中介一样的角色;

组合模式属于树型结构:它主要描述的是子节点与父节点的关系:
![组合模式树形结构]
中介模式属于网络拓扑中的星型结构,它描述了众节点与中心点的关系:
![中介模式星形结构]

对像之间显式地互相引用越多,意味着依赖性越强,独立性越差,不利于代码维护与扩展,同时多方沟通的任务也应交由中间平台来完成,每个类应只具备各自该有的功能,这便是高内聚低耦合的设计标准;
中介模式符合迪米特法则,它解决了对象间过度耦合、复杂频繁交互的问题,打破了你中有我,我中有你的相互依赖,第三方的介入有助于双方调停,打破如胶似漆、纠缠不休的关系,让他们之间变得松散、自由、独立;

四 类UML图

中介模式

源码地址:我的GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值