Observer patterns is one of the core design patterns that every developer should know and use. It let’s you create components with low coupling and adhere to Hollywood principle.

Some pseudo-code for adding new observer might look like this:

void addObserver(String ev, Observer ob);
producer.addObserver("myEventName", new Observer(){public void observe(Producer producer){}});

But there are at least 2 issues with this design:

  • You have to explicitly define event name
  • You can only pass reference to a producer object.
You could of course decide that a producer can only dispatch one type of events and we don’t need to explicitly name them, but usually that’s not the case.

So what if you wanted to define your events using some kind of interface, eg:

public interface MyEvent{}
producer.addListener("myEventName", new Observer<MyEvent>(){public void observe(MyEvent me){}});

So this is a little bit better but you still need to pass name of event as String.

So maybe we could use java generics to use power of type-safety at compile time and still have all the benefits of low-coupling. Something that could look like this:

public <T> void addListener(Class<T> e, Observer<T> o);
producer.addListener(MyEvent.class, new Observer<MyEvent>(){public void observe(MyEvent me){}});

Where first parameter could be used as EventType declaration.

This is very close but has still one flaw – it forces redundant code:

  • once event type is passed explicitly as event definition
  • second during observer creation – template parameter

So maybe it could be somehow simplified into something like this:

producer.addListener(new Observer<MyEvent>(){public void observe(MyEvent me){}});

Some of you might say that this is impossible in Java due to type-erasure. This is all true – but there’s second part of it – generic types are available at runtime through getGenericSuperClass/getGenericInterfaces methods.

You can see source code for my type-safe event system on github but I think it needs just some clarification – why do you need that ugly MethodProxy class.
So after writing DefaultImplementation of event dispatcher interface I found out that compiler would not allow call to Listener’s on method with passed event instance. So I decided to find proper method using reflection and only internally resign of type-safety.
MethodProxy class creates proxy upon instantiation so it will report any problems very close to their cause.

So here’s what you can find already in the repo:

  1. Dispatcher interface with default implementation
  2. Simple event interface used as entry point for all events
  3. Simple listener interface used as entry point for all listeners
I guess there might be sample usage scenario:
Declare your event:
public class MyEvent implements ProcessorLifecycleEvent{}
Create event dispatcher and register your listener:
ProcessorLifecycleEventDispatcher eventDispatcher = new DefaultProcessorLifecycleEventDispatcher();
eventDispatcher.registerListener(new ProcessorLifecycleEventListener<MyEvent>(){
public void on(MyEvent e) {
// some logic here

Publish new event:

eventDispatcher.dispatch(new MyEvent(){});
In the sample above MyEvent is very simple but it could take some data through constructor and act as full-blown DTO which simplifies greatly interactions beacause listener code doesn’t have to do any runtime casts – see example.
The whole project is part of another thing – Liferay service without service builder, which I’m going to describe soon 🙂

So enjoy.