设计模式之观察者模式

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

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

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

                

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

}

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

 



 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值