模式说明
对于观察者模式定义是对象之间存在一对多的依赖关系,当一个对象的状态发生变化时,其所有依赖的对象会被自动通知和更新。观察者模式分了被观察者和观察者,而一个被观察者对应多个观察者,当被观察者的状态发生变化时则会通知或更新所有的观察者。
应用场景
在 JavaScript 中存在大量的事件监听,如点击按钮、右键、鼠标在某元素上方悬停事件等,一般可以为这些事件增加多个监听方法,只要存在事件被触发,那么监听的方法就会被调用,在这里,事件就称为了被观察者,所监听的方法就成为了观察者。
有时候我们登录应用的时候会收到登录通知,这是因为我们的这个成功登录的事件触发的消息通知,常见的有微信通知,短信通知等,还有邮件的来信通知也是一样,收到邮件的这个事件触发了来信通知。在这里,登录及来信就是被观察者,而通知则是观察者。
如果一个接口支持异步调用的方式,同样适合使用观察者模式实现。因为客户端调用异步处理的接口时无法确认该接口的处理是否结束,所以在调用异步接口中可以增加回调地址,在异步处理结束后被请求,不管成功还是失败,那么这里的接口处理情况就是被观察者,而回调的地址就是观察者了,只不过这里的观察者只有一个。
代码实现
现在比较有影响力的微信开发者中心、腾讯开发者中心、钉钉开发者中心都具备大量的事件回调通知设置,以下是通过用户的创建、更新、删除进行通知触发,其中 CallbackManager
是观察者,UserAction
是被观察者。
// 观察者
public class CallbackManager {
Map<String, Runnable> callbacks = new HashMap<>();
public void register(String name, Runnable runnable) {
Objects.requireNonNull(runnable);
callbacks.put(name, runnable);
}
public void remove(String name) {
Objects.requireNonNull(runnable);
callbacks.remove(name);
}
public void notify(String name) {
Objects.requireNonNull(name);
CompletableFuture.runAsync(callbacks.get(name));
}
public void notifyAll() {
for (Runnalbe runnalbe : callbacks.values()) {
CompletableFuture.runAsync(runnalbe);
}
}
}
// 被观察者
public class UserAction {
CallbackManager callbackManager ...;
public void createUser() {
// ...
callbackManager.notify("CreateUser");
}
public void updateUser() {
// ...
callbackManager.notify("UpdateUser");
}
public void deleteUser() {
// ...
callbackManager.notify("DeleteUser");
}
}