1
//欢迎您的点评
2
3 import java.lang.reflect.Method;
4 import java.util.ArrayList;
5 import java.util.Hashtable;
6 import java.util.Iterator;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10
11 /** */ /**
12 * 事件基类
13 * @author Richard Lee
14 * 子类必须创建两个构造函数,一个为默认构造函数,一个为override受保护构造函数EventBase(Class handlerType)
15 */
16 public abstract class EventBase {
17 ////////////////////////////////////////////
18 // 类常量
19
20 // StringBuffer初始大小
21 private static final int StringBufferInitSize = 256 ;
22
23 private static final Log log = LogFactory.getLog(EventBase. class );
24
25 ////////////////////////////////////////////
26 // 成员变量,在创建对象时赋值,以后不可以改变。
27
28 // 同步根对象
29 public final Object SyncRoot = new Object();
30
31 // 事件监听者列表
32 private final ArrayList listeners = new ArrayList();
33
34 // 事件方法缓存
35 private final Hashtable eventMethodCache = new Hashtable();
36
37 // 事件处理对象(接口)类型
38 private final Class handlerType;
39
40 ////////////////////////////////////////////
41 // 私有方法
42
43 /** */ /**
44 * 检查事件处理对象的类型是否符合要求
45 * @param handler
46 * @return
47 */
48 private boolean checkHandlerType(Object handler) {
49 return this .handlerType.isInstance(handler);
50 }
51
52 /** */ /**
53 * 根据事件方法的名称查找事件函数
54 * 约束:事件函数不能够重载(overload)
55 * @param eventMethodName
56 * @return
57 */
58 private Method getEventMethodByName(String eventMethodName) {
59 if (eventMethodCache.containsKey(eventMethodName)) {
60 return (Method)eventMethodCache.get(eventMethodName);
61 }
62 throw new RuntimeException( " There is no ' " + eventMethodName + " ' event. " );
63 }
64
65 ////////////////////////////////////////////
66 // 受保护方法
67
68 /** */ /**
69 * 受保护构造函数,创建处理接口方法缓存
70 * @param handlerType
71 */
72 protected EventBase(Class handlerType) {
73 this .handlerType = handlerType;
74 Method [] ms = handlerType.getMethods();
75 for ( int i = 0 ; i < ms.length; i ++ ) {
76 eventMethodCache.put(ms[i].getName() , ms[i]);
77 }
78 }
79
80 /** */ /**
81 * 抛出事件
82 * @param eventMethodName
83 * @param args
84 */
85 protected void fireEvent(String eventMethodName , Object [] args) {
86 Iterator it = this .listeners.iterator();
87 while (it.hasNext()) {
88 Object handler = it.next();
89 if ( null == handler) {
90 continue ;
91 }
92 try {
93 Method m = getEventMethodByName(eventMethodName);
94 m.invoke(handler , args);
95 } catch (Throwable e) { // 捕捉所有的异常,统一通过onError方法处理。
96 onError(eventMethodName , handler , e);
97 }
98 }
99 }
100
101 /** */ /**
102 * 事件执行过程出错的处理, 子类根据不同的异常类型进行处理
103 * @param eventName
104 * @param eventHandler
105 * @param e
106 */
107 protected void onError(String eventName , Object eventHandler, Throwable e) {
108 try {
109 if (log.isErrorEnabled()) {
110 StringBuffer msg = new StringBuffer(StringBufferInitSize);
111 msg.append( " Event class: \ "" ).append(this.getClass().getName());
112 msg.append( " \ " , \ "" ).append(eventName).append( " \ " event execute failed. Event handler: \ "" );
113 if ( null != eventHandler) {
114 msg.append(eventHandler.toString());
115 } else {
116 msg.append( " null reference " );
117 }
118 msg.append( ' " ' );
119 log.error(msg , e);
120 }
121 } catch (Throwable ex) {
122 log.error( " onError execute failed. " , ex);
123 }
124 }
125
126 ////////////////////////////////////////////
127 // 公共护方法
128
129 public boolean addHandler(Object handler) {
130 if (checkHandlerType(handler)) {
131 return listeners.add(handler);
132 }
133 throw new IllegalArgumentException( " Handler type is invalid, addHandler method failed. " );
134 }
135
136 public boolean removeHandler(Object handler) {
137 if (checkHandlerType(handler)) {
138 return listeners.remove(handler);
139 }
140 throw new IllegalArgumentException( " Handler type is invalid, removeHandler method failed. " );
141 }
142
143 public void removeAllHandler() {
144 this .listeners.clear();
145 }
146
147 public boolean hasHandler() {
148 return ! listeners.isEmpty();
149 }
150 }
151
152
2
3 import java.lang.reflect.Method;
4 import java.util.ArrayList;
5 import java.util.Hashtable;
6 import java.util.Iterator;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10
11 /** */ /**
12 * 事件基类
13 * @author Richard Lee
14 * 子类必须创建两个构造函数,一个为默认构造函数,一个为override受保护构造函数EventBase(Class handlerType)
15 */
16 public abstract class EventBase {
17 ////////////////////////////////////////////
18 // 类常量
19
20 // StringBuffer初始大小
21 private static final int StringBufferInitSize = 256 ;
22
23 private static final Log log = LogFactory.getLog(EventBase. class );
24
25 ////////////////////////////////////////////
26 // 成员变量,在创建对象时赋值,以后不可以改变。
27
28 // 同步根对象
29 public final Object SyncRoot = new Object();
30
31 // 事件监听者列表
32 private final ArrayList listeners = new ArrayList();
33
34 // 事件方法缓存
35 private final Hashtable eventMethodCache = new Hashtable();
36
37 // 事件处理对象(接口)类型
38 private final Class handlerType;
39
40 ////////////////////////////////////////////
41 // 私有方法
42
43 /** */ /**
44 * 检查事件处理对象的类型是否符合要求
45 * @param handler
46 * @return
47 */
48 private boolean checkHandlerType(Object handler) {
49 return this .handlerType.isInstance(handler);
50 }
51
52 /** */ /**
53 * 根据事件方法的名称查找事件函数
54 * 约束:事件函数不能够重载(overload)
55 * @param eventMethodName
56 * @return
57 */
58 private Method getEventMethodByName(String eventMethodName) {
59 if (eventMethodCache.containsKey(eventMethodName)) {
60 return (Method)eventMethodCache.get(eventMethodName);
61 }
62 throw new RuntimeException( " There is no ' " + eventMethodName + " ' event. " );
63 }
64
65 ////////////////////////////////////////////
66 // 受保护方法
67
68 /** */ /**
69 * 受保护构造函数,创建处理接口方法缓存
70 * @param handlerType
71 */
72 protected EventBase(Class handlerType) {
73 this .handlerType = handlerType;
74 Method [] ms = handlerType.getMethods();
75 for ( int i = 0 ; i < ms.length; i ++ ) {
76 eventMethodCache.put(ms[i].getName() , ms[i]);
77 }
78 }
79
80 /** */ /**
81 * 抛出事件
82 * @param eventMethodName
83 * @param args
84 */
85 protected void fireEvent(String eventMethodName , Object [] args) {
86 Iterator it = this .listeners.iterator();
87 while (it.hasNext()) {
88 Object handler = it.next();
89 if ( null == handler) {
90 continue ;
91 }
92 try {
93 Method m = getEventMethodByName(eventMethodName);
94 m.invoke(handler , args);
95 } catch (Throwable e) { // 捕捉所有的异常,统一通过onError方法处理。
96 onError(eventMethodName , handler , e);
97 }
98 }
99 }
100
101 /** */ /**
102 * 事件执行过程出错的处理, 子类根据不同的异常类型进行处理
103 * @param eventName
104 * @param eventHandler
105 * @param e
106 */
107 protected void onError(String eventName , Object eventHandler, Throwable e) {
108 try {
109 if (log.isErrorEnabled()) {
110 StringBuffer msg = new StringBuffer(StringBufferInitSize);
111 msg.append( " Event class: \ "" ).append(this.getClass().getName());
112 msg.append( " \ " , \ "" ).append(eventName).append( " \ " event execute failed. Event handler: \ "" );
113 if ( null != eventHandler) {
114 msg.append(eventHandler.toString());
115 } else {
116 msg.append( " null reference " );
117 }
118 msg.append( ' " ' );
119 log.error(msg , e);
120 }
121 } catch (Throwable ex) {
122 log.error( " onError execute failed. " , ex);
123 }
124 }
125
126 ////////////////////////////////////////////
127 // 公共护方法
128
129 public boolean addHandler(Object handler) {
130 if (checkHandlerType(handler)) {
131 return listeners.add(handler);
132 }
133 throw new IllegalArgumentException( " Handler type is invalid, addHandler method failed. " );
134 }
135
136 public boolean removeHandler(Object handler) {
137 if (checkHandlerType(handler)) {
138 return listeners.remove(handler);
139 }
140 throw new IllegalArgumentException( " Handler type is invalid, removeHandler method failed. " );
141 }
142
143 public void removeAllHandler() {
144 this .listeners.clear();
145 }
146
147 public boolean hasHandler() {
148 return ! listeners.isEmpty();
149 }
150 }
151
152
使用范例:
首先定义一个事件处理器的接口
public
interface
ITestEventHandler
{
void onEnter(Object sender, Object arg);
void onExit(Object sender, Object arg);
}
void onEnter(Object sender, Object arg);
void onExit(Object sender, Object arg);
}
接着我们就编写一个类作为事件源(Observerable)
/** */
/**
* 活动的事件
* @author Richard Lee
* 非线程安全,需要使用者自行手工同步
*/
public class TestEvents extends EventBase implements ITestEventHandler {
public TestEvents(){
this(ITestEventHandler.class);
}
protected TestEvents(Class handlerType) {
super(handlerType);
}
public void onEnter(Object sender, Object arg) {
fireEvent("onEnter" , new Object[]{sender, arg});
}
public void onExit(Object sender, Object arg) {
fireEvent("onExit" , new Object[]{sender, arg});
}
}
* 活动的事件
* @author Richard Lee
* 非线程安全,需要使用者自行手工同步
*/
public class TestEvents extends EventBase implements ITestEventHandler {
public TestEvents(){
this(ITestEventHandler.class);
}
protected TestEvents(Class handlerType) {
super(handlerType);
}
public void onEnter(Object sender, Object arg) {
fireEvent("onEnter" , new Object[]{sender, arg});
}
public void onExit(Object sender, Object arg) {
fireEvent("onExit" , new Object[]{sender, arg});
}
}
接着我们就编写一个类作为事件处理器:
public
class
TestEventHandler
implements
ITestEventHandler
{
public void onEnter(Object sender, Object arg) {
System.out.println("OnEnter, sender: " + sender + ", arg: " + arg);
}
public void onExit(Object sender, Object arg) {
System.out.println("onExit, sender: " + sender + ", arg: " + arg);
}
}
public void onEnter(Object sender, Object arg) {
System.out.println("OnEnter, sender: " + sender + ", arg: " + arg);
}
public void onExit(Object sender, Object arg) {
System.out.println("onExit, sender: " + sender + ", arg: " + arg);
}
}
OK,这样就可以了,当然我们还需要一些客户端的代码来将TestEventHandler的实例注册到TestEvents的实例中监听事件,然后我们就可以在TestEvents 类中需要的地方调用onEnter或者onExit,EventBase会自动的调用监听器的相应方法。
对Observer/Observable的优点:1.类型安全。2.可以有多个事件函数(在接口中任意定义)而不像Observer只有一个。
缺点:1.编写子类略现复杂。2.未做到线程安全。
欢迎评论和建议,谢谢。