Comments

2008-02-27
Frank
"I couldn’t figure out how to restrict the generic type to be a supertype of the class implementing the Observer/Observable-interface. (Read: I cannot force the writer of the OnlineJobDatabase-class to subtype JobDatabase, when he implements Observable.)" Maybe I'm missing something, but is that desirable, anyway? Whether an Observable is itself a T or just forwards notifications for a T (or multiple T's) shouldn't matter to the outside world, should it? A notifier for T's must not be itself a T. The "Favor composition over inheritance" rule comes to mind. The name "Observable" is a bit misleading then though, as the Observable implementor is not necessarily itself the observed object. Also the attach/detach/notify implementations could be done generically in a class Notifier implements Observable
2008-02-28
Günther
That's a good point. Is there a case where it may be desirable to put the notifying code into a different class than the Subject (in the GoF sense) class? I would think that the observed object itself is supposed to trigger notifications when it's modified... Speaking of doing a pre-implementation of attach/detach/notify; when you stick to the "composition over inheritance" rule, you'll end up with something like the <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html" rel="nofollow">Cocoa NSNotificationCenter</a> class. This classes concern is purely to keep a list of "observing"-relations and to dispatch notifications to observers. You can also tell it which method to call on each observer. Amazing stuff, but it probably doesn't play too well with statically typed languages like Java... :-)
2009-05-20
Farzanegan
I like the concept, but I'm having trouble grasping how you're really going to avoid the equivalent of a bunch of 'instance-ofs' when you're processing your observed events (assuming that Unemployed is also observing other producers such as 'RecruiterSeminar').
2009-05-20
Günther
There are actually two answers to that question. The first is concerning the "instanceof" that I also refer to in the article (this could have been much more explicit though): 1. When just using the "Standard" Observer class that you can find in the Java class library, observers implement the interface method "void update(Observable o, Object arg)". Even though a program may be designed so that a *specific* implementation only gets notifications from a *specific* Observable implementation, the type of the argument given in "update" is still "Observable". Thus, a cast is needed to do something more specific, therefore most programmers would use instanceof to check whether that cast will work first. Using generics, the correct type is given directly to the update method and both the cast and this instanceof aren't needed any more. 2. The second part of the answer is concerned with the case that the observers observe a larger class hierarchy and thus more actual types can be passed to update(). (You won't like this answer. ;-)) I believe this problem is completely independent of the observer pattern in that the question is actually "what to do when different things must be done for different subclasses". The basic answer is: Starting from a switch statement or multiple if-constructs, move the code for the different cases into the relevant class hierarchy and use Polymorphism instead. There are people who say that instanceof is generally to be avoided, and when working in an Object Oriented context, it probably makes sense. Here's a bigger discussion on that topic: http://c2.com/cgi/wiki?InstanceofInConditionals http://c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism I hope I could help you a bit. If not, feel free to ask. :)
2009-05-20
Farzanegan
So what you're doing really just bypasses the 'instanceof/cast'. There's still got the same underlying problem of only being able to observe one 'class' of object for an observable. I assume what you were saying in the 2nd part was that I could compose an object which could listen to the different classes from different producers. I'm playing around with an application that listens to a controller- the controller needs to send messages, which I thought would be straightforward. But each message could have different components (from states to actual data), which mean different objects. So I guess I'm stuck with the 'instanceof' model. I guess an improvement would be if Observer could have method signatures with the desired class instead of passing 'Object'. That's an old beaten horse, since Observer/Observable have been around since 1.0.
2009-05-22
Günther
Yes, it just bypasses the <code>instanceof</code> and the cast. It's also true that an observer can only observe one kind of class (plus subclasses) now. I also identified this in the article itself (the first bullet point), but the language is probably a bit too technical there. When you want to make you object both a subclass of <code>Observer&lt;A&gt;</code> and <code>Observer&lt;B&gt;</code> (A and B being unrelated classes), it's not possible in Java as far as I know. (This has to do with byte code compatibility to earlier versions where generics were not possible yet.) However, if the object in the Observer role registers itself at the observable object, it may be possible to use inner classes that implement <code>Observer&lt;A&gt;</code> and <code>Observer&lt;B&gt;</code>. (The inner classes' instances can only be created by an instance of the surrounding class and can also access private methods and fields of that object.) Unfortunately, avoiding <code>instanceof</code> is usually not straightforward. Here's the bird view on that issue: When implementing some functionality in a method, you can usually choose into which class that method belongs. (For the other related objects, it may be unavoidable to use <code>instanceof</code>.) A simple heuristic would be to identify of which of used argument objects (also the receiver object [1]) the most instance variables need to be used (or simply "which is the most important object in this piece of code?"). Another concern is that you usually want to be able to use polymorphism (so that subclasses can override methods), but it only works on the receiver argument. To choose, which of the used objects is the receiver, there needs to be some kind of imbalance between all the argument objects. However, in some cases, the imbalance is not always given and all argument objects are equally important. If that happens, I usually try the following: (1) Building an additional layer of abstraction around one or more of these arguments, so that they are used in a less direct way. As a result, an imbalance can be established, thereby marking the "most important" object's class as the class, where the method fits into best. Another result of an additional layer of abstraction is often that the use of <code>instanceof</code> "moves into the implementation of that layer". When applying this technique recursively, it ultimately usually disappears. :) (2) If this doesn't work, you need something called "multiple dispatch". This means that the question, which method is to be executed when a call is made, is answered not only using the type of the receiver object, but instead using the types of *all objects* handed as arguments. (Note that you can directly use this to avoid <code>instanceof</code>s! :-)) Java doesn't support this as a language feature, but the visitor pattern does exactly that. (I just recently wrote a blog entry about it, where I talk about that pattern, but the best resource on the topic probably is the classic "Gang of Four" design patterns book. http://home.earthlink.net/~huston2/dp/visitor.html looks good, too. Be careful about the sources you use here, because many people see the visitor pattern very much from a "walking tree structures" angle, which is a very related idea that can be done easily using it, but which leads many people into the mistaken belief that this is all the pattern does.) To sum up, I have made the experience that (1) <code>instanceof</code> usage often disappears by adding more layers of abstraction and (2) if this makes difficulties, the visitor pattern can be used as last escape. :-) I'm afraid this may have been even more confusing than the previous comment I wrote. I hope it still helps. In doubt, don't trust me but trust the Gang of Four book. :-) Also don't take patterns too dogmatic. It's not so important to use the exact same names as in the books, but if you know a pattern and you have thought about its advantages and disadvantages, it often helps to explore the design space faster or in a more efficient manner. If you have some new insights, I'd be happy to hear about it. :-) [1] Small example for terminology: In the following code snippet, "taxi" is the receiver object, "memphis" and "driver" are arguments to the method: taxi.drive(driver, memphis); When considering the order of these arguments, it makes sense to see all three "taxi", "driver" and "memphis" as plain arguments first and later decide which of the classes Car, Person and City is imporant enough to host the "drive" method.
2010-01-11
Matthew Huntbach
I've just hit this issue myself, and wondered if anyone else had noticed it. When generics were added to Java, a lot of classes were made generic. The problem of compatibility with earlier code was got round by allowing "raw types", which counts for quite a big bit of the mess of generics. It seems to me that Observer ought to have been one of those classes. It seems to me it would be in the spirit of generics to make Observer generic so you could have an Observer object checked at compile time to stop it ever being made to observe Observables of a type it cannot handle. Does anyone know of any good reason why this wasn't done?
2010-01-12
Günther
Good question. I don't have a good answer to this yet.
2010-05-05
Steven Jeuris
Recently I stumbled upon the same problem. I found a nice concept on: http://www.machete.ca/2009/03/java-observer-pattern-woes/comment-page-1/#comment-217 ... and implemented it in a generic way. Source can be found here: http://pastebin.com/VmWdGrDw The concept is simple and strong typed! - extend a class with Observable - call getEventDispatcher(). .... append with any method of the interface from argument - observers simply have to implement the interface you created. Dynamic proxy's are used to trigger all observers. Reflection is used to find out the passed generic type argument. Only problem I see is if you implement two overlapping interfaces, you don't know where it came from. Could be solved quickly/ugly by passing an argument though.

New comment