观察者模式
观察者模式(Observer Pattern),又叫发布-订阅(Publisher/Subscribe)模式,模型-视图模式,源-监听器模式或从属者模式。定义一种一对多的依赖关系,一个主题对象可以同时被多个监听者同时监听,使得每当主题对象状态发生变化时,所有依赖于它的对象都会得到通知并被自动更新。属于行为型模式。
应用场景
- 当一个抽象模型包含两个方面内容,其中一个方面依赖于另一个方面
- 一个或多个对象的变化依赖于另一个对象的变化
- 实现类似广播机制的功能,无需知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。
- 多层级嵌套使用,形成一种链式触发机制。使得事件具备跨域通知
角色
- 抽象主题(Subject):指被观察的对象。该角色是一个抽象类或接口,定义了增加,删除,通知观察者对象的方法
- 具体主题(ConcreteSubject):具体被观察者,当其内部状态发生变化时,会通知已注册的观察者
- 抽象观察者(Observer):定义了响应通知的更新 方法
- 具体观察者(ConcreteObserver):在得到状态更新时,会自动做出响应
使用
一般很少自己去实现,当然真的要去实现,可以在被观察者中维护一份观察者列表,支持注册注销等操作,有一个通知方法即可
JDK本身也提供了该模式的API,将类继承Observeble即可作为被观察者,实现接口Observer,并重写update方法即可作为观察者。使用时只需要将观察者通过addObserver注册进去即可
当然也可以使用谷歌提供的工具,需要引入依赖:
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>20.0</version></dependency>
然后通过注解标明监听者即可。
代码如下:
创建Vo 与 PoJo模拟两种类型的事件,只会监听对应的事件
package com.caozz.demo2.observer.guava;public class Pojo {private String name;public Pojo(String name) {this.name = name;}@Overridepublic String toString() {return "Pojo{" +"name='" + name + '\'' +'}';}
}
package com.caozz.demo2.observer.guava;public class Vo {private String name;public Vo(String name) {this.name = name;}@Overridepublic String toString() {return "Vo{" +"name='" + name + '\'' +'}';}
}
package com.caozz.demo2.observer.guava;import com.google.common.eventbus.Subscribe;public class PojoEvent {@Subscribepublic void observer(Pojo pojo){System.out.println("执行PojoEvent方法,传参为:" + pojo);}}
package com.caozz.demo2.observer.guava;import com.google.common.eventbus.Subscribe;public class VoEvent {@Subscribepublic void observer(Vo arg){
// if(arg instanceof Vo){System.out.println("执行VoEvent方法,传参为:" + arg);
// }}}
package com.caozz.demo2.observer.guava;import com.google.common.eventbus.EventBus;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);eventBus.post(new Pojo("Tom"));eventBus.post(new Vo("Jerry"));}
}