Thanks Norman, I will look into extends.
I completely agree that a subject should have no knowledge of its observers (encapsulation).
However, for me my notification system should be scaleable and that means not sending notifications to objects that don’t want them. It’s a good idea to take a model to extremes and stress test it at design time to evaluate scalability…
Lets say we have a Clock class. Its instances notify observers every time a minute has passed. It also has a property of timezone. Then we create a view that displays the hours:minutes of a clock. It does this for every timezone (about 25 of them), so there are 25 instances of Clock.
Now we create a subclass of Clock called AccurateClock. Its fundamentally the same but its accuracy goes down to milliseconds.
We also enhance our view so the user can opt to see milliseconds and/or seconds for each timezone. The user opts to make one timezone display seconds and another timezone to display both seconds and milliseconds. The remaining 23 continue to display hours:minutes.
If our clock simply broadcasts an update notification, all the clocks in our view would receive millisecond updates, when only one of them needed this level of notification granularity. When timezones receive all these notifications they either have to refresh the view regardless or work out if it is interested in the update - perhaps by holding state between updates for comparison. Thats a lot of processing to handle unwanted notifications.
With 25 timezones * (1000 milliseconds per second * 60 seconds per minute) that’s 1,500,000 notification per minute.
It would be far better and more scaleable if observers were only notified about things they are interested in. In our example, 23 timezones are only interested when the minute changes, 1 is interested when the seconds change and 1 is interested when the milliseconds change.
To get this event granularity, our AccurateClock would need to trigger separate notifications for minutesChanged, secondsChanged and millisecondsChanged.
This would dramatically reduce the unnecessary notifications and their subsequent processing…
(23 timezones with minute accuracy: 231 = 23 per minute) + (1 timezone with second accuracy: 60 per minute) + (1 timezone with millisecond accuracy: 100060= 60,000 minute) = 60,083 notifications per minute. That’s a saving of 14,939,917 notifications per minute.
You could argue this is an extreme or impractical example, but I can’t see the point of having one notification system then another when it has to be scaleable. Simple code today might have to be scalable tomorrow, patricianly in code reuse.
[quote]Personally I’d use an interface, or several, and skip introspection entirely.
I think you’d find it a lot less frustrating trying to figure out how to marshall any parameters to methods to be invoked.
And overall you’d be less tightly coupled.[/quote]
Unless I am missing something (quite possible), it seems interfaces can only declare instance methods and not class (shared) methods. “suportedNotifications” feels more like a class thing. I think I will look into using inheritance and polymorphism instead. If extends works out, Object could define a single supportedNotifications declaration of “changed”. That way all classes will respond to supportedNotifications without having to implement it. Of course they don’t need to trigger any notifications, but they could if they wanted to. Classes could extend or override supportedEvents for more notification granularity, subclasses will inherit their super classes supportedNotifications and notification would all flow though one, scalable solution.
Along the way I will drop references to event and use notification instead, to avoid confusion.
Thanks for all your help!
I will post whatever I produce here in case someone else finds it useful.