设计模式-观察者模式

观察者模式

定义

  • 观察者模式( Observer Pattern),

    • 又叫

      • 发布-订阅( Publish/ Subscribe)模式

      • 模型-视图( Model/View)模式

      • 源监听器( Source,/ Listener)模式

      • 从属者( Dependents)模式

定义- 种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听,使得每当主题对象状态变化时,所有依赖于它的对象都会得到通知并被自动更新。属于行为型模式。

观察者模式的核心是将观察者与被观察者解耦,以类似于消息/广播发送的机制联动两者,使被观察者的变动前能通知到感兴趣的观察者们,从而做出相应的响应

应用场景

  • 起床闹钟设置

  • APP角标通知

  • 邮件通知

  • 广插通知

  • 桌面程序的事件响应

适用场景

  1. 当一个抽象模型包含两个方面内容,其中一个方面依赖于另一个方面

  2. 其他一个或多个对象的变化依赖于另一个对象的变化

  3. 实现类似广播机制的功能,无需知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播

  4. 多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。

使用

JDK自带的观察者实现方式

guava提供的观察者模式

public class Pojo {
  private String name;

  public Pojo(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return "Pojo{" +
      "name='" + name + '\'' +
      '}';
  }
}
public class PojoEvent {

  @Subscribe
  public void observer(Pojo pojo){
    //        if(arg instanceof Pojo){
    System.out.println("执行PojoEvent方法,传参为:" + pojo);
    //        }
  }

}
public class Test {

  public static void main(String[] args) {
    EventBus eventBus = new EventBus();


    PojoEvent guavaEvent = new PojoEvent();
    VoEvent voEvent = new VoEvent();
    eventBus.register(guavaEvent);
    eventBus.register(voEvent);

    //先执行这个方法,再事件回调<br>
    eventBus.post(new Pojo("Tom"));
  }
}

JWT的EVENT

Hystrix RXJAVA

源码的使用

Spring ContextLoaderListener

​ Spring中的 Contextloaderlistener实现了 Servlet Contextlistener接口Servlet Contextlistener接口又继承了 Eventlistener,在JDK中 Eventlistener有非常广泛的应用。 我们可以看一下源代码, Contextloaderlistener

ApplicationContextAware

ContextLoader内部有容器存储了对应的事件信息

ServletListener

总结

优点

  • 观察者和被观察者是松耦合(抽象耦合)的,符合依赖倒置原则

  • 分离了表示层(观察者)和数据逻辑层(被观察者),并且建立了ー套触发机制,使得数据的变化可以响应到多个表示层上

  • 实现了一对多的通讯机制,支持事件注册机制,支持兴趣分发机制,当被观察者角触发事件时,只有感兴趣的观察者可以接收到通知。

缺点

循环触发事件一直在内部触发

  • 如果观察者数虽过多,则事件通知会耗时较长

  • 事件通知呈线性关系,如果其中一个观察者处理事件卡壳,会影向后续的观察者接收该事件

  • 如果观察者和被观察者之间存在循环依赖,则可能造成两者之间的循环调用,导致系统崩溃。

Last updated