观察者模式 是一种行为设计模式,允许定义一种订阅通知机制,可以在对象(被观察者)事件发生时通知多个 “观察” 该对象的观察者对象,所以也被称为 发布订阅模式
其实我个人而言,不太喜欢使用文字去定义一种设计模式的语义,因为这样总是难以理解。所以就有了下面生活中的例子,来帮助读者更好的去理解模式的语义。类图如下所示:
在举例说明前,先让我们熟悉下观察者模式中的 角色类型 以及代码示例。观察者模式由以下几部分角色组成,可以参考代码示例去理解,不要被文字描述带偏
- 主题(被观察者)(Subject):抽象主题角色把所有观察者对象保存在一个容器里,提供添加和移除观察者接口,并且提供出通知所有观察者对象接口(也有作者通过 Observable 描述)
- 具体主题(具体被观察者)(Concrete Subject):具体主题角色的职责就是实现抽象目标角色的接口语义,在被观察者状态更改时,给容器内所有注册观察者发送状态通知
- public interface Subject {
- void register(Observer observer); // 添加观察者
- void remove(Observer observer); // 移除观察者
- void notify(String message); // 通知所有观察者事件
- }
- public class ConcreteSubject implements Subject {
- private static final List<Observer> observers = new ArrayList();
- @Override
- public void register(Observer observer) { observers.add(observer); }
- @Override
- public void remove(Observer observer) { observers.remove(observer); }
- @Override
- public void notify(String message) { observers.forEach(each -> each.update(message)); }
- }
- 抽象观察者(Observer):抽象观察者角色是观察者的行为抽象,它定义了一个修改接口,当被观察者发出事件时通知自己
- 具体观察者(Concrete Observer):实现抽象观察者定义的更新接口,可以在被观察者发出事件时通知自己
- public interface Observer {
- void update(String message); // String 入参只是举例, 真实业务不会限制
- }
- public class ConcreteObserverOne implements Observer {
- @Override
- public void update(String message) {
- // 执行 message 逻辑
- System.out.println("接收到被观察者状态变更-1");
- }
- }
- public class ConcreteObserverTwo implements Observer {
- @Override
- public void update(String message) {
- // 执行 message 逻辑
- System.out.println("接收到被观察者状态变更-2");
- }
- }
我们跑一下上面的观察者模式示例,如果不出意外的话会将两个观察者执行逻辑中的日志打印输出。如果是平常业务逻辑,抽象观察者定义的入参是具有业务意义的,大家可以类比项目上使用到的 MQ Message 机制