您现在的位置是:首页 > 文章详情

观察者模式

日期:2019-02-26点击:336

定义

定义对象的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者模式是行为型模式之一。包含观察者模式包括观察者与被观察者两个基本元素,观察者会注册到被观察者中,而被观察者会保持和观察者的对应关系。

如果被观察的对象产生一些观察者感兴趣的变更,则观察者会得到通知从而去执行相关的操作。

常见的观察者模式

提到观察者模式,首先会想到前端中常用的事件机制。例如为dom元素绑定事件:

$(document).click(function (e) { console.dir(e); });

这里的匿名function就是观察者,而document则是被观察者,.click(function)则是观察者注册的过程,此后document发生click事件时,被观察者则会收到通知,从而执行自己的逻辑console.dir(e)。

使用观察者模式

现在我们使用Java来模拟观察者模式。

先创建事件,包含事件源,通知目标,回调方法以及触发者等属性。

/** * 事件 */ public class Event { private Object source; // 事件源 private Object target; // 通知目标 private Method callback; // 回调方法名称 private String trigger; // 触发者 private long time; public Event(Object target, Method callback) { this.target = target; this.callback = callback; } // 省略getter、setter }

定义事件类型,此处定义添加、删除两种类型。

/** * 事件类型 */ public enum EventType { /** * 添加 */ ADD, /** * 删除 */ RMOVE }

定义抽象被观察者(主题),包含主题名称,保持与观察者引用映射的容器,以及事件触发的方法。

import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * 抽象主题 * 定义主题通用的容器、事件注册及事件触发 */ public class AbstractSubject { protected String name; protected Map<Enum,Event> eventMap = new HashMap<>(); // 注册容器 public AbstractSubject() {} protected AbstractSubject(String name) { this.name = name; } /** * 事件注册 * @param eventType * @param target * @param callback */ public void addLisenter(Enum eventType, Object target, Method callback) { eventMap.put(eventType, new Event(target, callback)); } /** * 事件触发 * @param eventType */ protected void trigger(Enum eventType) { Event event = this.eventMap.get(eventType); if(null == event) { return; } event.setSource(this); event.setTrigger(eventType.toString()); event.setTime(System.currentTimeMillis()); try { event.getCallback().invoke(event.getTarget(), event); } catch (Exception e1) { e1.printStackTrace(); } } // 省略getter、setter }

定义具体主题:

/** * 主题,被观察者 */ public class Subject extends AbstractSubject { public Subject(String name) { super.name = name; } public void add() { trigger(EventType.ADD); } public void remove() { trigger(EventType.RMOVE); } }

定义观察者,包含添加、删除事件对应的回调方法。

/** * 观察者 */ public class Observer { public void onAdd(Event event) { System.out.println("收到" + event.getTrigger() + "的添加事件"); } public void onRemove(Event event) { System.out.println("收到" + event.getTrigger() + "的删除事件"); } }

测试类:

/** * 测试类 */ public class Test { public static void main(String[] args) throws NoSuchMethodException { // 观察者 Observer observer = new Observer(); // 观察者收到通知后执行的方法 Method onAdd = Observer.class.getMethod("onAdd", Event.class); Method onRemove = Observer.class.getMethod("onRemove", Event.class); // 被观察者 Subject subject = new Subject("目标1号"); // 事件绑定 subject.addLisenter(EventType.ADD, observer, onAdd); subject.addLisenter(EventType.RMOVE, observer, onRemove); // 被观察者触发事件 subject.add(); subject.remove(); } }

其中,得到观察者和主题对象后,进行观察者的注册,然后主题执行动作触发事件,这是整个流程。

如果需要做成主题和观察者一对多的映射,则将Event的target改成集合类型,如下:

private List<Object> targets; // 通知目标
原文链接:https://yq.aliyun.com/articles/691667
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章