中介者模式
概述
以微信聊天为例,可以用户与用户直接聊天,也可以通过微信群聊天。前者的话,用户要和别的用户加为好友,即用户和用户之间存在多对多关系,一个用户如果要将相同的信息发送给所有其他用户,必须一个一个发送。而如果使用群聊天,一个用户可以向多个用户发送相同信息而无须一一进行发送,只需将信息发送到群中即可,群的作用就是将发送者所发送的信息转发给每一个接收者用户
一个由很多对象构成的模块,为了减少对象两两之间复杂的引用关系,需要使用中介者模式,通过引入一个中介者,将原本对象之间的两两交互转化为每个对象与中介者之间的交互
中介者承担了以下两方面的职责:
- 中转作用:通过中介者提供的中转作用,各个对象不需要显式引用其他对象,当需要和其他对象进行通信时,通过中介者即可
- 协调作用:中介者可以更进一步对对象之间的关系进行封装,对象一致和中介者进行交互,而不需要指明中介者具体怎么做。中介者根据封装在自身内部的逻辑协调,对对象的请求进行进一步处理,将对象之间的关系行为进行分离和封装
模式实例
某论坛会员通过聊天室进行信息交流,普通会员(CommonMember)可以发送文本信息,钻石会员(DiamondMember)既可以发送文本信息,还可以发送图片信息。聊天室可以对不雅字符进行过滤,可以对发送图片的大小进行控制。
抽象中介者类 AbstractChatroom(抽象聊天室类)
public abstract class AbstractChatroom {
// 注册对象的方法
public abstract void register(Member member);
// 对象文本信息方法
public abstract void sendText(String from, String to, String message);
// 对象图片信息
public abstract void sendImage(String from, String to, String image);
}
Member(抽象会员类)
public abstract class Member {
// 维持一个抽象中介者的引用,用于调用中介者的方法
protected AbstractChatroom chatroom;
protected String name;
public Member(String name) {
this.name = name;
}
public AbstractChatroom getChatroom() {
return chatroom;
}
public void setChatroom(AbstractChatroom chatroom) {
this.chatroom = chatroom;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 由于不同类型会员发送文本信息和图片信息的方式不同
// 因此对这两个方法进行抽象声明
public abstract void sendText(String to, String message);
public abstract void sendImage(String to, String image);
public void receiveText(String from, String message) {
System.out.println(from + "发送文本给" + this.name + ",内容为:" + message);
}
public void receiveImage(String from, String image) {
System.out.println(from + "发送图片给" + this.name + ",内容为:" + image);
}
}
具体中介者类 ChatGroup(具体聊天室类)
import java.util.Hashtable;
public class ChatGroup extends AbstractChatroom {
// 定义一个集合对象存储需要发生交互的对象
private Hashtable<String, Member> members = new Hashtable<String, Member>();
// 提供注册方式,将对象加入集合中
@Override
public void register(Member member) {
if (!members.contains(member)) {
members.put(member.getName(), member);
member.setChatroom(this);
}
}
@Override
public void sendText(String from, String to, String message) {
Member member = members.get(to);
String newMessage = message;
// 模拟不雅字符过滤
newMessage = message.replace("日", "*");
// 调用会员接收方法
member.receiveText(from, newMessage);
}
@Override
public void sendImage(String from, String to, String image) {
Member member = members.get(to);
// 模拟图片大小判断
if (image.length() > 5) {
System.out.println("图片太大,发送失败");
} else {
// 调用会员接收方法
member.receiveImage(from, image);
}
}
}
- 具体成员类 CommonMember(普通会员类)
public class CommonMember extends Member {
public CommonMember(String name) {
super(name);
}
@Override
public void sendText(String to, String message) {
System.out.println("普通会员发送信息:");
chatroom.sendText(name, to, message);
}
@Override
public void sendImage(String to, String image) {
System.out.println("普通会员不能发送图片!");
}
}
具体同事类 DiamondMember(钻石会员类)
public class DiamondMember extends Member {
public DiamondMember(String name) {
super(name);
}
@Override
public void sendText(String to, String message) {
System.out.println("钻石会员发送信息:");
chatroom.sendText(name, to, message);
}
@Override
public void sendImage(String to, String image) {
System.out.println("钻石会员发送图片");
chatroom.sendImage(name, to, image);
}
}
测试类 Client
public class Client {
public static void main(String[] args) {
AbstractChatroom happyChat = new ChatGroup();
Member member1, member2, member3, member4, member5;
member1 = new DiamondMember("张三");
member2 = new DiamondMember("李四");
member3 = new CommonMember("王五");
member4 = new CommonMember("小芳");
member5 = new CommonMember("小红");
happyChat.register(member1);
happyChat.register(member2);
happyChat.register(member3);
happyChat.register(member4);
happyChat.register(member5);
member1.sendText("李四", "李四,你好");
member2.sendText("张三", "张三,你好");
member1.sendText("李四", "今天天气不错,有日");
member2.sendImage("张三", "一个很大很大的太阳");
member2.sendImage("张三", "太阳");
member3.sendText("小芳", "还有问题吗?");
member3.sendText("小红", "还有问题吗?");
member4.sendText("王五", "没有了,谢谢");
member5.sendText("王五", "我也没有了");
member5.sendImage("王五", "谢谢");
}
}