Very typically I have a situation where a given object will need to have many listeners. For instance, I might have
class Elephant { public void addListener( ElephantListener listener ) { ... } }
but I'll have many such situations. That is, I'll also have a Tiger
object that'll have TigerListener
s. Now, TigerListener
s and ElephantListener
s are quite different:
interface TigerListener { void listenForGrowl( Growl qrowl ); void listenForMeow( Meow meow ); }
while
interface ElephantListener { void listenForStomp( String location, double intensity ); }
I find that I always have to keep re-implementing the broadcasting mechanism in each animal class, and the implementation is always the same. Is there a preferred pattern?
Listener methods are the main approach by which you add application-specific behavior to your application. Listener methods are a kind of call back; they are triggered when a form is submitted or a link is clicked. The listener methods exist within your page and component classes.
Instead of each Listener
having specific methods for every event type you can send it, change the interface to accept a generic Event
class. You can then subclass Event
to specific subtypes if you need, or have it contain state such as double intensity
.
TigerListener and ElephentListener then become
interface TigerListener { void listen(Event event); }
In fact, you can then further refactor this interface into a plain Listener
:
interface Listener { void listen(Event event); }
Your Listener
implementations can then contain the logic that they need for the specific events they care about
class TigerListener implements Listener { @Overrides void listen(Event event) { if (event instanceof GrowlEvent) { //handle growl... } else if (event instance of MeowEvent) { //handle meow } //we don't care about any other types of Events } } class ElephentListener { @Overrides void listen(Event event) { if (event instanceof StompEvent) { StompEvent stomp = (StompEvent) event; if ("north".equals(stomp.getLocation()) && stomp.getDistance() > 10) { ... } } } }
The key relationship between the subscriber and the publisher is that the publisher can send events to the subscribers, it isn't necessarily that it can send it certain types of events - this type of refactoring pushes that logic from the interface down into the specific implementations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With