Java design replaces if else and instanceof
Our Java application uses Google guava eventbus to communicate on the back end Some of these events are sent to the client using Jersey's server send events support to enable notification The client is only interested in certain types of events, and these events are sent to the client in JSON format
At present, we are using if else and instanceof to deal with JSON body generation in giant methods Uievent is just a tag interface used as a filter
@Subscribe public void handleEvent(final UIEvent event) { if (event instanceof A) { A a = (A) event; } else if (event instance B) { B b = (B) event; } ... }
As more and more events are added to the system, the code becomes chaotic After some research, there are some alternatives, but they are not good enough
1) Think
Using reflection means that we can retrieve data from event objects declaratively without knowing the exact type However, using reflection is not type safe and can be cumbersome when dealing with nested paths, such as a.b.c
2) Polymorphism
Polymorphism seems to be a good alternative to instanceof, but it does work in this case Using polymorphism means adding tojson - like methods to the uievent interface But this restores the dependency flow and exposes the UI details to the event bus
3) Packaging
I'm also considering using event wrapper classes to encapsulate JSON body building logic in different classes Then, in the handleevent method of the event bus, I can get the type of the event object and use the naming convention to find the wrapper class, then construct the wrapper class instance and call the tojson method to get the JSON body
public class AWrapper { public AWrapper(A a) { } public Object toJson() { } }
This is the most reasonable method I can think of so far
Need advice and ideas
Solution
I believe Google guava eventbus is precisely designed, so you don't have to use many if else if to define such methods:
By creating your own tags, you will recreate the problems they are trying to avoid
For me, this is how guava suggests using it:
EventBus eventBus = new EventBus(); eventBus.register(new Object(){ @Subscribe public void handleEvent(A a) { System.out.println("a"); } }); eventBus.register(new Object(){ @Subscribe public void handleEvent(B b) { System.out.println("b"); } }); ... eventBus.post(new A()); eventBus.post(new B());
There is one handler method for each event type. Obviously, the subscriber does not need to be in an anonymous class like this example
Other examples
http://tomaszdziurko.pl/2012/01/google-guava-eventbus-easy-elegant-publisher-subscriber-cases/