观察者模式
参考:https://refactoringguru.cn/design-patterns/observer
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。(又被称为发布订阅模式)
![观察者设计模式](https://raw.githubusercontent.com/Zeng-QiHong/markdown/master/imageobserver.png)
观察者模式结构
- 发布者 (Publisher) 会向其他对象发送值得关注的事件。 事件会在发布者自身状态改变或执行特定行为后发生。
发布者中包含一个允许新订阅者加入
和当前订阅者离开列表的订阅构架
。(这相当于一个主题,允许关注,和取关) - 当新事件发生时, 发送者会遍历订阅列表并调用每个订阅者对象的通知方法。 该方法是在订阅者接口中声明的。
- 订阅者 (Subscriber) 接口声明了通知接口。 在绝大多数情况下, 该接口仅包含一个
update
更新方法。 该方法可以拥有多个参数, 使发布者能在更新时传递事件的详细信息。 - 具体订阅者 ( Subscribers) 可以执行一些操作来回应发布者的通知。 所有具体订阅者类都实现了同样的接口, 因此发布者不需要与具体类相耦合。
- 订阅者通常需要一些上下文信息来正确地处理更新。 因此, 发布者通常会将一些上下文数据作为通知方法的参数进行传递。 发布者也可将自身作为参数进行传递, 使订阅者直接获取所需的数据。
Java代码实现
抽象发布者类
public interface Subject {
//添加订阅者
void attach(Observer observer);
//删除订阅者
void detach(Observer observer);
//通知订阅者(消息发布)
void notify(String msg);
}
发布者类
public class SubscribeSubject implements Subject {
//定义一个集合,用来装观察者
private List<Observer> observerList = new ArrayList<>();
@Override
public void attach(Observer observer) {
observerList.add(observer);
}
@Override
public void detach(Observer observer) {
observerList.remove(observer);
}
@Override
public void notify(String msg) {
for (Observer observer : observerList) {
observer.update(msg);
}
}
}
抽象订阅者类
public interface Observer {
//更新通知
void update(String msg);
}
具体观察者类
public class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String msg) {
System.out.println(name + "收到了订阅信息...." + msg);
}
}
客户端Client
public class Client {
public static void main(String[] args) {
//创建发布者对象
SubscribeSubject subscribeSubject = new SubscribeSubject();
//创建订阅者对象
Observer concreteObserver1 = new ConcreteObserver("张三");
Observer concreteObserver2 = new ConcreteObserver("李四");
//添加订阅
subscribeSubject.attach(concreteObserver1);
subscribeSubject.attach(concreteObserver2);
//发布者发布消息,订阅者收到消息
subscribeSubject.notify("开饭啦!!");
}
}
代码执行结果
张三收到了订阅信息....开饭啦!! 李四收到了订阅信息....开饭啦!! Process finished with exit code 0
使用场景
优点:
降低了目标对象和观察者之间的耦合关系,
被观察者发送通知,所有注册的观察者都会收到消息
缺点:
如果观察者非常多的话,所有的观察者收到通知会很耗时
如果被观察者有循环依赖的话,那么会被循环调用,导致系统崩溃