>> I attempted to design a generic ListenerManager that could be used to manage 
>> listeners
>> for any interface. There are definitely a few drawbacks (which I listed in 
>> the paste bin) but
>> I would just like to open up the discussion for creating something like 
>> this. Feedback please!
> 
> I think your implementation is fine -- I've written essentially the same 
> myself, in fact -- but I also think you've exposed the fact that expressing 
> this thought in Java ends up looking like a bad expression of the thought.  
> Fennec, Android Background Services, and even Android itself, have all 
> elected to make interfaces one-shot deals.  In the end, the abstraction does 
> not win enough to make it worthwhile.

Further to this (I also didn't want this to get zero responses, but I've been 
mulling, and you beat me to it!):

"Listener" is kind of a bad name for the thing under consideration. Those are 
typically really *delegates*: an extension point, an individual thing that 
provides functionality according to a specified interface.

That doesn't really generically generalize to having multiple instances, at 
least not without getting into absurdly powerful Common Lisp-style generic 
functions and method combinations.

Consider: if one of these calls returns a result, which listener's result do 
you take? Can the same listener register with multiple 'talkers'? Pretty soon 
things get "Java silly": ReturnValueSummingListenerManagerFactory.

So I don't think the delegate pattern itself is something that needs to be 
fixed -- it's just being abused to achieve something that's better suited to a 
different pattern.

Instead, the leap is usually to an uncoupled system with either 
compile-time-checked or ad hoc string messages.

Senders broadcast messages along some bus, explicit (named channels) or implied 
(sendMessageToJava).

Listeners get handed messages asynchronously, based on some topic. If they wish 
they can take some action based on the contents, including sending their own 
messages. Listener registration is typically only loosely coupled with the 
sender lifecycle, and they typically don't return a value (because that's too 
much coupling).

We have this already, of course, because of our integration with Gecko, but we 
don't really use it for this.

In my experience, large compartmentalized systems (and the alternative to a 
large compartmentalized system is a horror show!) tend to grow some kind of 
internal messaging bus, for several reasons: lifecycle difficulty issues; 
interface coupling; difficulties in distributing an application across multiple 
processes or machines; and exactly this multiple-listener problem.

Eventually two or three components all want to know when a log file rotates, or 
a call starts, or an order is finished, and then you get an Enterprise Service 
Bus. In Android's case, you get LocalBroadcast and broadcast intents.

Which brings me to my conclusion: if we're reaching Peak Listener -- that is, 
if we're starting to roll up ad hoc notification systems, considering abusing 
sendMessageToJava, or discussing consistent listener implementations on the 
mailing list -- then perhaps it's time to start thinking about consistent use 
of messaging for inter-component communication.

-R
_______________________________________________
mobile-firefox-dev mailing list
mobile-firefox-dev@mozilla.org
https://mail.mozilla.org/listinfo/mobile-firefox-dev

Reply via email to