• Post Reply Bookmark Topic Watch Topic
  • New Topic

Subclassing Observable  RSS feed

 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am working on a Document/View set of classes. My Document is a subclass of another class, so it can't be a subclass of Observable. This creates a problem addressed in "Head First Design Patterns," (1st ed.), on page 71:

If you look at the Observable API, the setChanged() method is protected. So what? Well, this means you can't call setChanged() unless you've subclassed Observable. This means you can't even create an instance of the Observable class and compose it with our own objects, you have to subclass. The design violates a second design principle here...favor composition over inheritance.


However, it seems to me that I can do both. I can subclass Observable and then compose an instance of the subclass on my Document, like this:



In my Document, I have this:



In my View, I register an Observer with the Document's subclassed Observable (the one in its cameraChange member):



By creating an inner class of View (the CameraChange class), I am not limited to one implementation of the Observer update() method. I can have as many inner classes as I want, each with its own update() method, each able to manage a different kind of notification from the Document.

This seems to cope with the problematic aspects "Head First Design Patterns" described regarding Observable being a class, not an interface. My Document no longer has to extend Observable, nor is it precluded from composing on an instance of Observable (by virtue of having it compose on a subclass of Observable). My View class can define as many subclasses as it wants, each with its own update() method, and register instances of those subclasses with each of the Document's Observer subclasses.

Which I would think was all pretty sweet, but for the fact that I thought it up within about ten minutes of reading page 71 of "Head First Design Patterns," and it is a long-standing belief of mine that any "solution" I think of in the first ten minutes after learning of a problem is probably crap.

I would welcome any critical comments others might have.
 
Stephan van Hulst
Saloon Keeper
Posts: 7991
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have taken this approach in the past, I wouldn't say it's crap.

These days I just prefer to roll my own listener interfaces though, because I think Observable is too generic. I don't like passing Objects around, you end up with a dynamically typed language.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I have taken this approach in the past, I wouldn't say it's crap.

Thanks, Stephan. That's reassuring.
These days I just prefer to roll my own listener interfaces though, because I think Observable is too generic. I don't like passing Objects around, you end up with a dynamically typed language.

Yeah, I noticed that too. The Observable class and Observer interface go back to JDK 1.0, which pre-dates generics. Seems like a modernized version of those two could use generics to solve that problem.

I'm rather new to this style of coding (to Document/Observer and Model/View/Controller, that is). I could imagine rolling my own stuff, but not until after I've grown more accustomed to it. So long as it isn't an outright waste of time, starting with Observer and Observable seems like it might be the right thing for me to do.
 
Ulf Dittmer
Rancher
Posts: 42972
73
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think along the same lines to Stephan. Observer/Observable are leftovers from the early days of Java. Defining and implementing your own listener interface, possibly along with an event class, is a pretty easy task, so I think that's preferable. Or you could go with a ready-made solution like EventBus.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I too normally implement my own listener interfaces. In my current app I decided to write an Observer<T> and Observable<T> interfaces, and produced an AbstractObservable<T> to encapsulate the boilerplate. That does suffer from the same problem mentioned in HeadFirst Java if you intend it to be a generic solution. It serves my purpose well though, as the superclass of my DAO's so other classes can observe database changes.

With Java 8 you can do away with the Observer<T> interface altogether. Use Consumer<T> and then use lambda expressions or method references to register observers.*

* Idea unashamedly lifted from Richard Warburton's conference talk today.
 
Stevens Miller
Bartender
Posts: 1445
30
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, fellows. That is very useful feedback and guidance. Much appreciated.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!