In my experience in supporting users of the EventBus, in both the open
source world and in professional teams, weak references are not something to
be feared.  This is because:
1) Weak references fail fast.
2) Weak reference semantics can be documented.  Make the API's clear, make
the doc clear, make the examples clear.  Document the anti-pattern, put it
in the FAQ.
3) Assume your users are smarter than you might think.  WeakReferences are
pretty easy to understand.  Even if a rookie doesn't understand them, you
can make it a teachable moment.
4) WeakReferences are clean and simple.  Managaging listener lifecycle is
like managing memory in C- it a buggy job that sucks productivity and bloats
code.
5) In the 6 years of the EventBus' life, only one user posted a "this
doesn't work" question because they didn't RTFM.

Greg, you didn't detail many of the "number of issues" with WeakReferences,
so I'm not sure what the perception is, but in my experience WeakReferences
are better since the lifecycle of the listener is generally (90%+)
equivalent to the lifecycle of the component that defines the listener.

One issue mentioned is the use of an anonymous inner class (a questionable
pattern anyway), but when annotations are available users generally use that
more terse route rather than using an anonymous class.  When developers use
the anonymous class anti-pattern, it fails quickly and they change it -
often forcing them to think about garbage collection in their apps, which is
a great thing.  The corollary of using .subscribe(new XXXSubscriber()) is
even worse when using strong references - without a reference it's
impossible to clean up.

I think the encapsulation argument  is extremely weak.  Firstly, most UI
developers don't care too much about building extensible classes, but even
when they do, I prefer the opposite effect: Each method that is annotated as
a subscriber becomes part of the contract of the component.  This is a form
of programming by contract that is very powerful.  It says, "whenever this
event is fired, I'm going to call this method."  Derived classes can
manipulate the behavior as needed.  Hiding it is equivalent to the static
final listeners that are all over the Swing framework - it stops extension
and customization in it's tracks. I went into this pub/sub
programming-by-contract method quite a bit in the
article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
wrote on the EventBus+Pivot.  Lastly, if you don't like that idea, you
can
easily create private fields that are listeners.

The best argument for weak references is that strong references generally
suck.   Strong references have the opposite effects listed above:
1) Strong references cause memory "leaks" that don't fail fast.  They fail
very slowly and insiduously.  They are often not caught until production.
2) Strong reference issues are hard to document.
3) Even smart, experienced developers wind up wasting hours or days tracking
down memory leaks before they find the culprit.
4) Lifecycle management of listeners is not always easy.  It is error prone
and bloats code.  Even in the easy cases, it's easily forgotten and
difficult to test for.

Note: The Spring ActionScript EventBus shifted (is shifting?) from
defaulting to strong to defaulting to weak.

I look forward to seeing how the MessageBus API develops.

Michael Bushe
Principal
Bushe Enterprises, Inc.
[email protected]
www.bushe.com
www.mindfulsoftware.com
www.eventbus.org

On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv <[email protected]> wrote:

> I think that's fair to do.
>
> -----Original Message-----
> From: Greg Brown [mailto:[email protected]]
> Sent: Monday, June 21, 2010 2:11 PM
> To: [email protected]
> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> annotation
> and an annotation processor for application context message listener
>
> It doesn't necessarily need to be used by other parts of the framework to
> go
> in pivot-core. It just needs to be generally useful and not have any
> dependencies on the other libraries.
>
> I'm not sure what else, if anything, I would want it to do - it is really
> only meant to provide simple intra-application messaging services without a
> lot of overhead or the need for an external library.
>
> One advantage to moving it to org.apache.pivot.util is that listener
> implementations would not require so much typing (MessageBusListener is
> shorter than ApplicationContextMessageListener). Also, since (like
> WTKXSerializer) it isn't strictly dependent on WTK, it probably does not
> belong there.
>
> G
>
> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>
> > Yes. But I would leave it there for now. For simple messaging it is
> > sufficient. More thought is needed. My current thinking is that unless it
> > used by pivot internally, and hence drives need & evolution, it could be
> > better to use something else.
> >
> >
> > -----Original Message-----
> > From: Greg Brown [mailto:[email protected]]
> > Sent: Monday, June 21, 2010 9:52 AM
> > To: [email protected]
> > Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> annotation
> > and an annotation processor for application context message listener
> >
> >> One thing I am finding is for annotations and auto-registering, that the
> >> machinery dominates the actual messaging code in ApplicationContext.
> >
> > ApplicationContext is large, but the message handling code itself is
> pretty
> > small - it is just a few methods:
> >
> > subscribe()
> > unsubscribe()
> > sendMessage()
> > queueMessage()
> >
> > I have actually been wondering if it might make sense to move it to a
> core
> > class, such as org.apache.pivot.util.MessageBus so that non-UI
> applications
> > can also use it. The only thing specific to WTK is queueMessage(), but
> that
> > could either remain in ApplicationContext and be implemented in terms of
> > MessageBus, or it could potentially be eliminated - the code in that
> method
> > could easily be implemented at the application level.
> >
>
>

Reply via email to