上一篇文章中,我们介绍了事件驱动的基础组件。本文,我们将开发一个事件驱动的框架。
事件驱动框架参照一些消息系统中的模式。我们将进行如下类比。 事件与消息,事件处理器与通道,事件转发器与路由。
一个实例是邮递系统。邮递员有一个背包里面有若干信件,上面有要寄送的地址,邮递员必须将信件寄送到相应的地址。这个过程可以按如下形式描述?
procedure deliver_letters(satchel):
repeat
letter := next_letter(satchel)
for home in homes do:
if letter.destination == home:
deliver_letter(home)
end if
end for
until satchel is empty
end procedure
这个例子可以使用事件驱动编程建模。接下来我们将以最抽象的形式来开发一个框架,来对系统建模。
每个消息有一个具体的类型,通过类型将消息与处理器相关联。消息接口定义如下。
public interface Message {
public Class extends Message> getType();
}
管道与某种类型的消息关联。我们将消息派发给每种消息各自的管道进行处理。
public interface Channel<E extends Message> {
public void dispatch(E message);
}
消息系统的交互是通过路由完成。路由负责将给定的消息转发到具体的通道上。初始化阶段,路由会注册消息与其关联的通道。随后,由路由转发的消息会自动匹配消息类型及关联的管道,并将消息路由到关联的管道中。
public interface DynamicRouter<E extends Message> {
public void registerChannel(Class extends E> contentType,
Channel extends E> channel);
public abstract void dispatch(E content);
}
接下来将实现这些接口以便创建一个完整的框架。
我们将事件定义为消息的子类。
import Message;
public class Event implements Message {
@Override
public Class extends Message> getType() {
return getClass();
}
}
处理器最终接收事件,并处理,这里将实现管道接口。
import Channel;
public class Handler implements Channel<Event> {
@Override
public void dispatch(Event message) {
System.out.println(message.getClass());
}
}
事件转发器用来注册消息与通道。本例中,我们注册处理器及其关联的事件类。我们使用HashMap将这件与处理器关联。
import java.util.HashMap;
import java.util.Map;
import edu.giocc.util.router.Channel;
import edu.giocc.util.router.DynamicRouter;
public class EventDispatcher implements DynamicRouter<Event> {
private Map<Class extends Event>, Handler> handlers;
public EventDispatcher() {
handlers = new HashMap<Class extends Event>, Handler>();
}
@Override
public void registerChannel(Class extends Event> contentType,
Channel extends Event> channel) {
handlers.put(contentType, (Handler)channel);
}
@Override
public void dispatch(Event content) {
handlers.get(content.getClass()).dispatch(content);
}
}
基本框架完成,接下来进行行测。
public class Program {
public static void main(String[] args) {
EventDispatcher dispatcher = new EventDispatcher();
dispatcher.registerChannel(Event.class, new Handler());
dispatcher.dispatch(new Event());
}
}
现在框架已经建立,通用框架一般应具备下列特征。
上述提到的属性解释了应用如何与框架连接。框架仅仅是架构的一个抽象。
Handler和Event类是framework层的类。基于框架开发的代码应该位于应用层。框架职责是抽象并提供事件驱动架构的基础工具。
现在我们可以继承Handler类,来创建我们的事件处理器,继承Event类来创建我们的事件。此外,我们在派发器中注册这些事件处理器与事件。
下一篇文章中将展示一个框架的具体实现,以便模拟事件驱动系统。
http://www.giocc.com/writing-an-event-driven-framework-with-java.html