In our code base here, we have a utility class called Observable that makes it easy to apply the observer pattern to a class.
I was using it, and in the process (having been bitten by this in NetBeans), I wrote a unit test to see what would happen if a user of this class added Observers and then dereferenced them without removing them. I used a form of memory leak testing described here.
Sure enough, there was a memory leak, because the underlying list of observers in the Observable class was still hanging on to the observers.
So I modified the class to use WeakReference and ReferenceQueue to detect when an observer was no longer strongly referenced, and then removed "stale" references from the observer list.
When I submitted the code for review, our technical director here, who had written the original Observable code, pushed back, saying it was adding unnecessary complexity to the class.
I argued that my experience with listeners/observers was that people often did not do the right thing and forgot to remove their observers, and Evil Things ensued.
He pointed me to this wonderful, hilarious, incredibly well-written article by Joel Spolsky about (among other things) Martian headsets, the problem of standards, and the disaster caused by Jon Postel's robustness principle ("“Be conservative in what you do, be liberal in what you accept from others.”) I highly recommend you read it, but in case you don't, the point was, this principle encouraged sloppy and incorrect web pages to proliferate, which has put us into a terrible compatibility mess today.
I argued that although this made a lot of sense, we weren't building a standard or pseudo-standard with lots of implementations, and look what Java did to ease programmer's lives by introducing garbage collection to the masses.
He made an interesting point that services should probably follow the robustness principle, but lower-level building blocks, where implementation is more transparent, should expect users to use them correctly and not adapt to incorrect use.
I finally relented because (a) he's the boss, and at some point just to make progress you let the boss make the call :) and (b) I had to admit that we had never actually encountered this problem after being in the field for many years, so perhaps I was inventing a dragon where none existed.
It still makes me nervous. I saw nasty problems with zombie observers in NetBeans. But I'm willing to give it a shot. In general I am happier with code that is simpler and cleaner and only complicate it if you have to. I think we'll just have to see how it goes.
I'm curious, what do you think?
No comments:
Post a Comment