您的位置:首页 > 编程语言 > Java开发

设计模式之观察者模式

2014-06-02 10:39 155 查看
           观察者模式:定义对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,所有依赖于他的对象都将得到通知并自动更新。

    下面通过该模式思想来实现一个事件机制。某个业务状态变更时发出具体事件,有需要的业务监听该业务事件,并在监听到事件时做出反应处理。

    首先定义抽象事件接口,包括发布事件、注册事件监听器、注销事件监听器等事件操作,并发布服务。

                

/**
* 事件抽象接口
* &&
* 提供事件发布以及事件监听器的注册、删除方法
* @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

}

}

    通过以上操作,就说明整个事件机制,在自己的业务中可以注册所有需要的事件,而发布事件的业务只需要将自己的状态变换通过事件发布出去,很好的实现了模块之间的解耦。

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息