设计模式之观察者模式
2014-06-02 10:39
155 查看
观察者模式:定义对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖于他的对象都将得到通知并自动更新。
下面通过该模式思想来实现一个事件机制。某个业务状态变更时发出具体事件,有需要的业务监听该业务事件,并在监听到事件时做出反应处理。
首先定义抽象事件接口,包括发布事件、注册事件监听器、注销事件监听器等事件操作,并发布服务。
其中,Event是抽象事件类,包含基本的事件id,事件资源等属性,所有具体事件继承该类;EventListener为抽象事件监听器接口,所有具体事件监听器继承该接口;EventFilter为事件过滤接口。
EventListener定义如下:
然后,发布事件的业务可以定义自己的具体事件对象,如下,
并在状态发生变更的时候,发布事件
然后,和该业务相关的业务监听该业务事件,定义一个抽象事件类,通过一个事件队列,在业务内部管理事件,当监听到事件时,加入事件队列,并为每个事件建立线程任务,通过该队列将事件分发出去处理。
其中,IEventListener是该业务自己的监听接口,继承自基本监听接口EventListener
当然,该业务还没有注册事件监听器,这样当发布事件的业务发布事件时候,你也是收不到的,定义一个事件管理类,负责注册事件
通过spring.xml中配置服务监听,绑定EventService服务,在系统启动是回调绑定方法bindService,并注册事件监听器,具体配置如下:
事件监听器如下:
通过以上操作,就说明整个事件机制,在自己的业务中可以注册所有需要的事件,而发布事件的业务只需要将自己的状态变换通过事件发布出去,很好的实现了模块之间的解耦。
下面通过该模式思想来实现一个事件机制。某个业务状态变更时发出具体事件,有需要的业务监听该业务事件,并在监听到事件时做出反应处理。
首先定义抽象事件接口,包括发布事件、注册事件监听器、注销事件监听器等事件操作,并发布服务。
/** * 事件抽象接口 * && * 提供事件发布以及事件监听器的注册、删除方法 * @author xx */ public interface EventService { /** * 发布事件 * @param event 事件 */ public void publish(Event event); /** * 批量发布事件 * @param collection 事件集合 */ public void publish(Collection<Event> collection); /** * 注册事件监听 * @param eventListener 事件监听器 * @param eventID 事件ID */ public void addEventListener(EventListener eventListener, String eventID); /** * 注册事件监听,根据 filter 过滤 * @param eventListener 事件监听器 * @param filter 过滤器 * @param eventID 事件ID */ public void addEventListener(EventListener eventListener, EventFilter filter, String eventID); /** * 注销事件监听 * @param eventListener 事件监听器 */ public void removeEventListener(EventListener eventListener); }
其中,Event是抽象事件类,包含基本的事件id,事件资源等属性,所有具体事件继承该类;EventListener为抽象事件监听器接口,所有具体事件监听器继承该接口;EventFilter为事件过滤接口。
EventListener定义如下:
/** * 事件监听器抽象接口,所有具体事件监听器继承该接口 * @author xx * */ public interface EventListener { /** * 事件监听器处理方法 * @param event 事件 */ public void onEvent(Event event); }
然后,发布事件的业务可以定义自己的具体事件对象,如下,
/** * 测试事件,继承自抽象事件 * @author xx * */ public class TestEvent extends Event { /** * 序列号 */ private static final long serialVersionUID = 2107606925118238578L; /** * 事件类型,可以是个枚举,这里测试不再具体定义 */ private String eventType; /** * 事件数据列表,测试,不再具体定义 */ private List<Object> objList = new ArrayList<Object>(); public String getEventType() { return eventType; } public void setEventType( String eventType) { this.eventType = eventType; } public List<Object> getObjList() { return objList; } public void setObjList(List<Object> objList) { this.objList = objList; } }
并在状态发生变更的时候,发布事件
/** * 测试事件发布类 * @author xx * */ public class TestEventPublisher { private EventService eventService; public void publicTestEvent() { TestEvent event = new TestEvent(); event.setEventType("testType"); //构造数据等代码省略 eventService.publish(event); } public EventService getEventService() { //测试代码,省掉具体获取服务方法 return eventService; } public void setEventService(EventService eventService) { this.eventService = eventService; } }
然后,和该业务相关的业务监听该业务事件,定义一个抽象事件类,通过一个事件队列,在业务内部管理事件,当监听到事件时,加入事件队列,并为每个事件建立线程任务,通过该队列将事件分发出去处理。
/** * 业务事件监听器抽象类 * @author xx * */ public abstract class AbstractEventListener implements IEventListener { /** * 事件队列 */ private BlockingQueue<Event> eventQueue = new LinkedBlockingQueue<Event>(); /** * 事件监听状态 */ private AtomicBoolean isRunning = new AtomicBoolean(true); /** *启动事件监听 */ @Override public void start() { ThreadFactory.getInstance().startThread(new EventHandler()); } public void onEvent(Event event) { try { //新增事件加入事件队列 eventQueue.put(event); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 停止事件监听 */ @Override public void stop() { isRunning.compareAndSet(true, false); } private class EventHandler implements Runnable { @Override public void run() { try { while(isRunning.get()) { //从事件队列取出事件执行 process(eventQueue.take()); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
其中,IEventListener是该业务自己的监听接口,继承自基本监听接口EventListener
/** * 业务事件监听接口,继承自基本事件监听接口 * @author xx * */ public interface IEventListener extends EventListener { /** * 事件处理方法 * @param event 事件 */ public void process(Event event); /** * 启动事件监听 */ public void start(); /** * 停止事件监听 */ public void stop(); }
当然,该业务还没有注册事件监听器,这样当发布事件的业务发布事件时候,你也是收不到的,定义一个事件管理类,负责注册事件
/** * 业务事件监听管理类 * @author xx * */ public class EventMonitor { /** * 事件管理服务 */ private EventService eventService; /** * 测试用事件监听器 */ private IEventListener testEventListener; private void registerListeners() { //注册测试事件监听器 eventService.addEventListener(testEventListener, "testEventId"); } private void unregisterListeners() { //注销事件监听器 eventService.removeEventListener(testEventListener); } /** * 绑定服务 * @param service 服务 * @param properties 属性 */ public void bindService(Object service, Map<Object, Object> properties) { if(service instanceof EventService) { eventService = (EventService)service; registerListeners(); } else { ; } } /** * 解绑定服务 * @param service 服务 * @param properties 属性 */ public void unbindService(Object service, Map<Object, Object> properties) { if(service instanceof EventService) { eventService = null; unregisterListeners(); } else { ; } } public EventService getEventService() { return eventService; } public void setEventService( EventService eventService) { this.eventService = eventService; } public IEventListener getTestEventListener() { return testEventListener; } public void setTestEventListener(IEventListener testEventListener) { this.testEventListener = testEventListener; } }
通过spring.xml中配置服务监听,绑定EventService服务,在系统启动是回调绑定方法bindService,并注册事件监听器,具体配置如下:
<!--监听EventService服务,并通过绑定的方式注入服务--> <oms:reference id="eventService" interface="base.event.EventService" wait="false"> <oms:listener ref="Event_Service" bind-method="bindService" unbind-method="unbindService"/> </oms:reference> <!--通过依赖注入实例化EventMonitor中的具体监听器属性--> <bean id="Event_Service" class="service.event.EventMonitor"> <property name="testEventListener" ref="Test_Event_Service"> </bean> <!--注册实例化回调方法来启动监听器--> <bean id="Test_Event_Service" class="service.event.TestEventListener" init-method="start" destroy-method="stop"> </bean>
事件监听器如下:
/** * 一个具体的事件监听器 * @author xx * */ public class TestEventListener extends AbstractEventListener { @Override public void process(Event event) { //非指定具体事件不处理 if(event instanceof TestEvent) { return; } final TestEvent testEvent = (TestEvent)event; //过滤事件类型 if(testEvent.getEventType().equals("testType")) { //处理事件 processEvent(event); } } private void processEvent(Event event) { // TODO Auto-generated method stub } }
通过以上操作,就说明整个事件机制,在自己的业务中可以注册所有需要的事件,而发布事件的业务只需要将自己的状态变换通过事件发布出去,很好的实现了模块之间的解耦。
相关文章推荐
- 设计模式与泡mm的关系之Observer观察者模式及再思考
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
- 设计模式随笔系列:气象站的故事-观察者模式(Observer)[原]
- 利用观察者模式设计仿真器内核接口
- .NET中的设计模式五:观察者模式
- 设计模式之Observer观察者模式
- 认识观察者模式(设计模式)[转载]
- 设计模式学习笔记(二十一)——Observer观察者
- 用 spring 实现观察者设计模式
- .NET中的设计模式五:观察者模式 选择自 lane_cn 的 Blog
- 设计模式之观察者模式 (原创)
- 设计模式之观察者模式(Observer Pattern)(一)
- 设计模式之观察者模式
- IssueVision 学习笔记(三)-----设计模式之OBSERVER(观察者)模式
- 设计模式之观察者模式(Observer Pattern)(二)
- 探究观察者设计模式
- GEF框架中的设计模型(观察者模式)
- C#设计模式-观察者observer模式实现
- AspectJ实现设计模式(一)——观察者模式