你的位置:首页 > ASP.net教程

[ASP.net教程]业务事件模型的实现


  在实际业务开发过程中,很经常应用到观察者模式。大致的处理流程是说在模块初始化的时候,注册若干观察者,然后它们处理自己感兴趣的内容。当某一个具体的事件发生的时候,遍历观察者队列,然后”观察者“们就根据之前约定的具体情况,处理自己关注的事件。其实观察者模式本人认为更确切的说法应该是:事件通知模型。那么现在,我们就用传统的Java语言来实现一下。(具体可以查看代码的注释,写的挺详细了)

 

  业务事件定义如下:

/** * @filename:BusinessEvent.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件定义 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;public class BusinessEvent {  // 某种具体的业务事件的数据内容  private Object businessData;  // 某种具体的业务事件的事件类型  private String businessEventType;  public BusinessEvent(String businessEventType, Object businessData) {    this.businessEventType = businessEventType;    this.businessData = businessData;  }  public Object getBusinessData() {    return this.businessData;  }  public String getBusinessEventType() {    return this.businessEventType;  }}

  接着就是业务事件监听器的定义了

/** * @filename:BusinessEventListener.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件监听器定义 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;public interface BusinessEventListener {    //事件接口定义  public void execute(BusinessEvent event);}

  业务事件,总要有个管理者吧,那现在就实现一个

/** * @filename:BusinessEventManagement.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件管理器定义 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;//业务事件管理器public class BusinessEventManagement {  private Map<String, List<BusinessEventListener>> map = new HashMap<String, List<BusinessEventListener>>();  public BusinessEventManagement() {  }  // 注册业务事件监听器  public boolean addBusinessEventListener(String BusinessEventType,      BusinessEventListener listener) {    List<BusinessEventListener> listeners = map.get(BusinessEventType);        if (null == listeners) {      listeners = new ArrayList<BusinessEventListener>();    }        boolean result = listeners.add(listener);        map.put(BusinessEventType, listeners);        return result;  }  // 移除业务事件监听器  public boolean removeBusinessEventListener(String BusinessEventType,      BusinessEventListener listener) {    List<BusinessEventListener> listeners = map.get(BusinessEventType);    if (null != listeners) {      return listeners.remove(listener);    }    return false;  }  // 获取业务事件监听器队列  public List<BusinessEventListener> getBusinessEventListeners(      String BusinessEventType) {    return map.get(BusinessEventType);  }}

  再来一个事件的发送者,来负责事件的派发

/** * @filename:BusinessEventNotify.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件发送者 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;import java.util.List;public class BusinessEventNotify {  private BusinessEventManagement businessEventManagement;;  public BusinessEventNotify(BusinessEventManagement businessEventManagement) {    this.businessEventManagement = businessEventManagement;  }  // 事件派发  public void notify(BusinessEvent BusinessEvent) {        if (null == BusinessEvent) {      return;    }    List<BusinessEventListener> listeners = businessEventManagement        .getBusinessEventListeners(BusinessEvent.getBusinessEventType());    if (null == listeners) {      return;    }    for (BusinessEventListener listener : listeners) {      listener.execute(BusinessEvent);    }  }}

  关键的来了,下面可以根据自己的业务规定,注册若干个事件的监听器。下面我们就先注册两个监听器,分别是短信监听器、彩铃监听器,然后执行自己对“感兴趣”事件进行的操作。

/** * @filename:SendSmsListener.java * * Newland Co. Ltd. All rights reserved. * * @Description:短信消息监听器 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;public class SendSmsListener implements BusinessEventListener {  @Override  public void execute(BusinessEvent event) {    System.out.println("监听器:" + this + "接收到业务事件,业务事件类型是["        + event.getBusinessEventType() + "] ## 业务事件附带的数据["        + event.getBusinessData() + "]");  }}

/** * @filename:ColorRingListener.java * * Newland Co. Ltd. All rights reserved. * * @Description:彩铃消息监听器 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;public class ColorRingListener implements BusinessEventListener {  @Override  public void execute(BusinessEvent event) {    System.out.println("监听器:" + this + "接收到业务事件,业务事件类型是["        + event.getBusinessEventType() + "] ## 业务事件附带的数据["        + event.getBusinessData() + "]");  }}

  好了,全部的框架都完成了,那现在我们把上述模块完整的调用起来。

/** * @filename:Main.java * * Newland Co. Ltd. All rights reserved. * * @Description:主函数 * @author tangjie * @version 1.0 * */package newlandframework.businessevent;public class Main {  /**   * @param args   */  public static void main(String[] args) {        // 注册监听器    BusinessEventManagement businessEventManagement = new BusinessEventManagement();        businessEventManagement.addBusinessEventListener("彩铃监听器",        new ColorRingListener());    businessEventManagement.addBusinessEventListener("短信监听器",        new SendSmsListener());    // 业务事件触发    BusinessEventNotify sender = new BusinessEventNotify(        businessEventManagement);        sender.notify(new BusinessEvent("彩铃监听器", "ReadBusinessEvent"));    sender.notify(new BusinessEvent("短信监听器", "WriteBusinessEvent"));  }}

  彩铃监听器感兴趣的事件是读事件(ReadBusinessEvent),短信监听器感兴趣的事件是写事件(WriteBusinessEvent)。运行起来之后,发现果然组织的很好。当然有人会说,上面的情况JDK里面已经有现成的类(java.util.EventObject、java.util.EventListener)支持了。那下面我们就根据上面的例子,利用Spring框架来模拟一下事件模型是如何更优雅的应用的。

  在Spring里面,所有事件的基类是ApplicationEvent,那我们从这个类派生一下,重新定义一下我们的业务事件。代码如下

/** * @filename:BusinessEvent.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件定义 * @author tangjie * @version 1.0 * */package newlandframework.spring;import org.springframework.context.ApplicationEvent;public class BusinessEvent extends ApplicationEvent {    // 某种具体的业务事件的数据内容  private Object businessData;  // 某种具体的业务事件的事件类型  private String businessEventType;  public BusinessEvent(String businessEventType, Object businessData) {    super(businessEventType);    this.businessEventType = businessEventType;    this.businessData = businessData;  }  public Object getBusinessData() {    return this.businessData;  }  public String getBusinessEventType() {    return this.businessEventType;  }}

  同样的,事件的发送者也要进行一下调整,代码如下

/** * @filename:BusinessEventNotify.java * * Newland Co. Ltd. All rights reserved. * * @Description:业务事件发送者 * @author tangjie * @version 1.0 * */package newlandframework.spring;import java.util.List;import newlandframework.spring.BusinessEvent;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class BusinessEventNotify implements ApplicationContextAware {  private List<String> businessListenerList;    private ApplicationContext ctx;  public void setBusinessListenerList(List<String> businessListenerList) {this.businessListenerList = businessListenerList;  }  public void setApplicationContext(ApplicationContext applicationContext)      throws BeansException {    this.ctx = applicationContext;  }  public void notify(BusinessEvent businessEvent) {    if (businessListenerList.contains(businessEvent.getBusinessEventType())) {      BusinessEvent event = new BusinessEvent(          businessEvent.getBusinessEventType(),          businessEvent.getBusinessData());      ctx.publishEvent(event);      return;    }  }}

  下面我们就来注册一下Spring方式的短信、彩铃监听器:

/** * @filename:SendSmsListener.java * * Newland Co. Ltd. All rights reserved. * * @Description:短信消息监听器 * @author tangjie * @version 1.0 * */package newlandframework.spring;import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;public class SendSmsListener implements ApplicationListener {    final String strKey = "SMS";  public void onApplicationEvent(ApplicationEvent event) {    // 这里你可以截取刚兴趣的实际类型    if (event instanceof BusinessEvent) {      BusinessEvent businessEvent = (BusinessEvent) event;      if (businessEvent.getBusinessEventType().toUpperCase().contains(strKey)) {                System.out.println("监听器:" + this + "接收到业务事件,业务事件类型是["            + businessEvent.getBusinessEventType()            + "] ## 业务事件附带的数据[" + businessEvent.getBusinessData()            + "]");      }    }  }}

/** * @filename:ColorRingListener.java * * Newland Co. Ltd. All rights reserved. * * @Description:彩铃消息监听器 * @author tangjie * @version 1.0 * */package newlandframework.spring;import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;public class ColorRingListener implements ApplicationListener {  public void onApplicationEvent(ApplicationEvent event) {    if (event instanceof BusinessEvent) {      BusinessEvent businessEvent = (BusinessEvent) event;      System.out.println("监听器:" + this + "接收到业务事件,业务事件类型是["          + businessEvent.getBusinessEventType() + "] ## 业务事件附带的数据["          + businessEvent.getBusinessData() + "]");    }  }}

  最后我们编写一下Spring的依赖注入的配置文件spring-event.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"  default-autowire="byName">  <bean id="smsListener" class="newlandframework.spring.SendSmsListener" />  <bean id="ringListener" class="newlandframework.spring.ColorRingListener" />  <bean id="event" class="newlandframework.spring.BusinessEventNotify">    <property name="businessListenerList">      <list>        <value>DealColorRing</value>        <value>DealSms</value>      </list>    </property>  </bean></beans>

  一切准备就绪,现在我们把上面Spring方式实现的事件模型,完整的串起来,代码如下:

/** * @filename:Main.java * * Newland Co. Ltd. All rights reserved. * * @Description:主函数 * @author tangjie * @version 1.0 * */package newlandframework.spring;import newlandframework.spring.BusinessEvent;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathpublic class Main {  public static void main(String[] args) {    ApplicationContext ctx = new ClassPath"newlandframework/spring/spring-event.);    BusinessEventNotify sender = (BusinessEventNotify) ctx.getBean("event");    sender.notify(new BusinessEvent("DealColorRing", "ReadBusinessEvent"));
sender.notify(new BusinessEvent("DealSms", "ReadBusinessEvent")); }}

  运行的结果如下,非常完美,不是么?