设计模式-观察者模式
前言
在 Java 开发中,设计模式是常用的一种编码方式,合理使用设计模式可以帮助开发人员更快地编写出高效、可靠和可维护的代码。本期继续撰写设计模式系列文章,总共 23 种设计模式将以一篇一篇文章讲解,代码笔记已开源至:Gitee点击跳转。
在上一篇《Java设计模式(17)备忘录模式》文章中,我们介绍了备忘录模式。本文是这个系列的第十八篇章,我们将讲解一下观察者模式的实现方式、应用场景以及它的用途。
观察者模式
观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系。当一个对象的状态发生变化时,所有依赖它的对象都会收到通知并自动更新。
在观察者模式中,被观察的对象通常称为主题或被观察者(Subject),接收通知的对象称为观察者(Observer)。Subject 负责维护观察者列表,并在需要的时候统一通知所有观察者。
这种模式可以让被观察者和观察者之间保持低耦合。被观察者不需要关心观察者具体做了什么,只需要调用统一的通知方法即可。
使用场景
- 需要一个对象状态变化后通知多个对象的场景,如用户订阅消息、系统通知、商品降价提醒
- 需要实现事件监听机制的场景,如按钮点击事件、监听器回调
- 需要解耦消息发布者和接收者的场景,如消息订阅、发布通知
- 需要动态添加或移除通知对象的场景,如用户订阅和取消订阅
代码实现
以下是一个简单的示例。我们将创建一个被观察者对象 ConcreteSubject,并创建多个观察者 ConcreteObserver。当被观察者发送消息时,所有已注册的观察者都可以收到通知。
/**
观察者接口
@author Jensen
@date 2024-01-18
*/
public interface Observer {
void update(String msg);
}
/**
被观察者接口
@author Jensen
@date 2024-01-18
*/
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers(String message);
}
public class ConcreteSubject implements Subject {
private final List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
observers.forEach(observer -> observer.update(message));
}
}
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);
}
}解释
观察者接口(Observer):定义了观察者接收消息的方法 update。所有具体观察者只要实现这个接口,就可以接收被观察者发送的消息。
被观察者接口(Subject):定义了注册观察者、移除观察者和通知观察者的方法。这样可以统一管理观察者对象。
具体被观察者类(ConcreteSubject):内部维护了一个 observers 集合,用于保存所有注册进来的观察者。当调用 notifyObservers 方法时,会遍历 observers 集合,并调用每个观察者的 update 方法。
具体观察者类(ConcreteObserver):保存了观察者名称,并实现了 update 方法。当收到消息时,会打印当前观察者收到的消息内容。
通过这种方式,ConcreteSubject 不需要知道每个观察者的具体业务逻辑,只需要负责通知即可。如果后续需要增加新的观察者类型,只要实现 Observer 接口即可,不需要修改 ConcreteSubject 的核心逻辑。
测试
System.out.println("------------------------------观察者模式-----------------------------");
ConcreteSubject concreteSubject = new ConcreteSubject();
ConcreteObserver zhangSan = new ConcreteObserver("张三");
ConcreteObserver liSi = new ConcreteObserver("李四");
ConcreteObserver wangWu = new ConcreteObserver("王五");
concreteSubject.registerObserver(zhangSan);
concreteSubject.registerObserver(liSi);
concreteSubject.registerObserver(wangWu);
concreteSubject.notifyObservers("你好");
concreteSubject.removeObserver(liSi);
concreteSubject.notifyObservers("悄悄话,不要让李四看到");输出结果
------------------------------观察者模式-----------------------------
张三 收到的消息是:你好
李四 收到的消息是:你好
王五 收到的消息是:你好
张三 收到的消息是:悄悄话,不要让李四看到
王五 收到的消息是:悄悄话,不要让李四看到结语
观察者模式通过注册、移除和通知观察者的方式,实现了对象之间的一对多通知关系。被观察者只负责维护观察者列表并发送通知,观察者只负责接收消息并处理自己的逻辑。
在实际开发中,观察者模式常用于消息通知、事件监听、订阅发布等场景。合理使用观察者模式,可以降低对象之间的耦合度,也能让系统在新增通知对象时更加灵活。