每个事件是否有特定的侦听器接口。每个事件都可以发出侦听器调用。然后,调度程序的作用是识别目标侦听器并在其上触发事件通知。
例如,通用事件定义可以是:
public interface GameEvent<L> { public void notify( final L listener);}如果您的CollisionListener是:
public interface CollisionListener { public void spaceshipCollidedWithMeteor( Spaceship spaceship, Meteor meteor );}然后,相应的事件可以是:
public final class Collision implements GameEvent<CollisionListener> { private final Spaceship ship; private final Meteor meteor; public Collision( final Spaceship aShip, final Meteor aMeteor ) { this.ship = aShip; this.meteor = aMeteor; } public void notify( final CollisionListener listener) { listener.spaceshipCollidedWithMeteor( ship, meteor ); }}您可以想象一个调度程序,它能够像以下情况一样在目标侦听器上传播此事件(Events是调度程序类):
// A unique dispatcherfinal static Events events = new Events();// Somewhere, an observer is interested by collision events CollisionListener observer = ...events.listen( Collision.class, observer );// there is some moving parts Spaceship aShip = ...Meteor aMeteor = ...// Later they collide => a collision event is notified trough the dispatcherevents.notify( new Collision( aShip, aMeteor ) );
在这种情况下,调度程序不需要任何有关事件和侦听器的知识。它仅使用GameEvent接口触发向每个侦听器的单独事件通知。每个事件/侦听器对都选择自己的对话方式(如果需要,它们可以交换许多消息)。
这种调度程序的典型实现应类似于:
public final class Events { private final HashMap<Class,ArrayList> map = new HashMap<Class,ArrayList >( 10 ); public <L> void listen( Class<? extends GameEvent<L>> evtClass, L listener) { final ArrayList<L> listeners = listenersOf( evtClass ); synchronized( listeners ) { if ( !listeners.contains( listener ) ) { listeners.add( listener ); } } } public <L> void mute( Class<? extends GameEvent<L>> evtClass, L listener) { final ArrayList<L> listeners = listenersOf( evtClass ); synchronized( listeners ) { listeners.remove( listener ); } } private <L> ArrayList<L> listenersOf(Class<? extends GameEvent<L>> evtClass) { synchronized ( map ) { @SuppressWarnings("unchecked") final ArrayList<L> existing = map.get( evtClass ); if (existing != null) { return existing; } final ArrayList<L> emptyList = new ArrayList<L>(5); map.put(evtClass, emptyList); return emptyList; } } public <L> void notify( final GameEvent<L> evt) { @SuppressWarnings("unchecked") Class<GameEvent<L>> evtClass = (Class<GameEvent<L>>) evt.getClass(); for ( L listener : listenersOf( evtClass ) ) { evt.notify(listener); } }}我想它可以满足您的要求:
- 很轻,
- 快速,
- 没有强制转换(使用时),
- 在编译时检查所有内容(没有可能的错误),
- 侦听器没有API约束(每个事件选择它自己的消息),
- 进化(不同事件和/或侦听器之间没有依赖关系),
- 调度员是一个通用的黑匣子,
- 消费者和生产者不需要彼此了解。



