Search code examples
javaeventsarchitectureevent-driven

Creating a simple event driven architecture


Having a bit of trouble with a project at the moment. I am implementing a game and I'd like to have it event-driven.

So far I have an EventHandler class which has an overloaded method depending on what type of event is generated(PlayerMove, Contact, Attack, etc)

I will have either the game driver or the class generate the events. My question is how can I efficiently handle the events without tightly coupling the event generating classes to the event handler and making the use of EDA redundant?

I want to design my own simple handler and not use the built-in Java one for this


Solution

  • If you want to have a single EventHandler class with overloaded methods and your event types do not have any subclasses, then this simple code, which uses reflection, should work:

    public class EventHandler {
        public void handle (final PlayerMove move) {
           //... handle
        }
    
        public void handle (final Contact contact) {
           //... handle
        }
    
        public void handle (final Attack attack) {
           //... handle
        }
    }
    
    public void sendEvent (final EventHandler handler, final Object event) {
        final Method method = EventHandler.class.getDeclaredMethod ("handle", new Class[] {event.getClass ()});
        method.invoke (handler, event);
    }
    

    However, if you want to have seperate EventHandlers for different events, the following would be better.

    public interface EventHandler<T extends Event> {
        void handle (T event);
    }
    
    public class PlayerMoveEventHandler implements EventHandler<PlayerMove> {
        @Override
        public void handle (final PlayerMove event) {
            //... handle
        }
    }
    
    public class EventRouter {
        private final Map<Class, EventHandler> eventHandlerMap = new HashMap<Class, EventHandler> ();
    
        public void sendEvent (final Event event) {
            eventHandlerMap.get (event.getClass ()).handle (event);
        }
    
        public void registerHandler (final Class eventClass, final EventHandler handler) {
            eventHandlerMap.put (eventClass, handler);
        }
    }