一 概述
中介,是作为多个事物之间充当交互沟通的媒介,在程序也是这样的,对象与对象之间不需要持有对方引用,而是通过中介相互连接;
二 使用示例
使用聊天室作为中介,支持用户登录、用户注销、用户发言;
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