中介者模式
中介模式的英⽂翻译是 Mediator Design Pattern。
在 GoF 中的《设计模式》⼀书中,它是这样定义的:
Mediator pattern defines a separate (mediator) object that encapsulates the interaction between a set of objects and the objects delegate their interaction to a mediator object instead of interacting with each other directly.
中介模式定义了⼀个单独的(中介)对象,来封装⼀组对象之间的交互。将这组对象之间的交互委派给中介对象,来避免对象之间的直接交互。属于行为型模式
通过引⼊中介这个中间层,将⼀组对象之间的交互关系(或者说依赖关系)从多对多(⽹状关系)转换为⼀对多(星状关系)
我们的注册中心就是中介者模式的典型应用场景,比方说朋友圈,QQ群, 淘宝商城都是中介者模式在生活上的应用
中介者模式主要有四个角色:
Mediator: 抽象中介者
ConcreteMediator: 具体中介者
Colleague: 抽象同事类
ConcreteColleague: 具体同事类
在一些简单场景下,可以不设计抽象中介者和抽象同事类,具体看你的使用场景
代码示例
我们用代码实现下QQ群的场景,每个QQ号都可以在群里发送内容,QQ群就承担着一个中介者的作用
public class QQ {
private String name;
public void setName(String name) {
this.name = name;
}
public QQ(String name) {
this.name = name;
}
public void sendMessage(QQGroup qqGroup, String message) {
if (qqGroup.getMembers().contains(this)) {
System.out.println("[" + this.name + "]:" + message + "in qq group " + qqGroup.getName());
} else {
System.err.println("你不在群里,不能说话");
}
}
}
public class QQGroup {
private List<QQ> members;
private String name;
public List<QQ> getMembers() {
return members;
}
public void addMember(QQ qq) {
if (members == null) {
members = new ArrayList<>();
}
members.add(qq);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
QQ member1 = new QQ("小明");
QQ member2 = new QQ("小一");
QQ member3 = new QQ("小花");
QQGroup group = new QQGroup();
group.setName("私人聊天群");
group.addMember(member1);
group.addMember(member2);
member1.sendMessage(group, "明天我们去逛街");
member2.sendMessage(group, "好啊");
member3.sendMessage(group, "我也去");
}
}
观察者模式
观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)。
在 GoF 的《设计模式》⼀书中,它的定义是这样的:
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
在对象之间定义⼀个⼀对多的依赖,当⼀个对象状态改变的时候,所有依赖的对象都会⾃动收到通知。属于行为型模式。
⼀般情况下,被依赖的对象叫作被观察者(Observable),依赖的对象叫作观察者(Observer)。不过,在实际的项⽬开发中,这两种对象的称呼是⽐较灵活的,有各种不同的叫法,⽐如:Subject-Observer、Publisher-Subscriber、Producer-Consumer、EventEmitter-EventListener、Dispatcher-Listener等。
观察者模式主要包含4种角色
抽象被观察者(Subject):被观察的对象,被观察者提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
具体被观察者:在被观察者内部状态改变时,给所有注册过的观察者发出通知。
抽象观察者:为所有具体的观察者定义一个响应通知的接口
具体观察者:实现抽象观察者角色所要求的更新接口
代码示例
public class MyObservable {
List<MyObserver> observerList;
public void addObserver(MyObserver observer) {
if (observerList == null) {
observerList = new ArrayList<>();
}
observerList.add(observer);
}
public void notifyAllObserver(Object arg) {
if (observerList == null) {
return;
}
for (MyObserver observer : observerList) {
observer.update(this, arg);
}
}
}
public class OrderCompleted extends MyObservable {
private Long orderId;
public OrderCompleted(Long orderId) {
this.orderId = orderId;
}
public void notifyObservers() {
//如果是使用的jdk自带的Observable类,要先设置changed标识,后续才可以发送成功
super.notifyAllObserver(orderId);
}
}
public interface MyObserver {
void update(MyObservable observable, Object arg);
}
public class SmsNotification implements MyObserver {
@Override
public void update(MyObservable o, Object arg) {
Long orderId = (Long) arg;
System.out.println("您已下单成功,订单号为:" + orderId);
}
}
public class EmailNotification implements MyObserver {
@Override
public void update(MyObservable o, Object arg) {
Long orderId = (Long) arg;
System.out.println("您已下单成功,升级为白金用户,订单号为:" + orderId);
}
}
public class Test {
public static void main(String[] args) {
OrderCompleted orderCompleted = new OrderCompleted(9888121L);
SmsNotification sms = new SmsNotification();
EmailNotification email = new EmailNotification();
orderCompleted.addObserver(sms);
orderCompleted.addObserver(email);
orderCompleted.notifyObservers();
}
}
中介者模式和观察者模式对比
观察者模式和中介模式都是为了实现参与者之间的解耦,简化交互关系。
两者的不同在于应⽤场景上。在观察者模式的应⽤场景中,参与者之间的交互⽐较有条理,⼀般都是单向的,⼀个参与者只有⼀个⾝份,要么是观察者,要么是被观察者。
⽽在中介模式的应⽤场景中,参与者之间的交互关系错综复杂,既可以是消息的发送者、也可以同时是消息的接收者。
中介者模式和代理模式对比:
代理模式重点在代理,会对原对象做功能增强;但是中介者模式就是一个转发的作用,实际的工作还是要你自己去完成