tags:

views:

96

answers:

2

I want to implement the observer pattern and I want class X to observe updates in classes A and B.

X is derived from the abstract base class XObs which has the update() function taking an enum as parameter of what has happened.

The logical problem here is that X needs to know which of A and B sent the update and X cannot determine that from the enum parameter.

What are the pros/cons of adding another parameter to update() which tells which of A and B sent the update? What other ways are possible to solve this? (I rather not create a base class for A and B and send a this pointer in the update() as A and B are quite different.)

Thanks,

Tomas

+1  A: 

The common base class for a and b doesnt have to have any distinct functionality - it just needs to be used to express the fact that A and B are Observable. In this sense A and B are not 'quite different', they are the same.

Visage
Good point, I guess you want me to send a 'this' pointer along with the enum in the update function then? Or does the Observable base class solve how X can separate A and B in another way?
Tomas
Generally the observable base class also provides the notification functionality, as well as keeping track of who is watching. (See http://www.codeguru.com/cpp/tic/tic0290.shtml for an overview), but yes, if the management of the notifications was done by a distinct class you could just pass a pointer in the update method to indicate the object that has changed.
Visage
The drawback of this is that you need to downcast in `update()` to determine the concrete class of the observable. This makes the implementation fragile and harder to maintain.
Péter Török
True. But if A and B are as different as the OP suggests then it seems unlikely that whatever the observer wishes to do with them can be acheived without some kind of donw cast. Unless, of course, A and B could be made to inherit from a second class that encapsulates whatever functionality the Observer would wish to call.
Visage
I believe templates offer a better solution.
Péter Török
Thanks for all your help with this. Really appreciated.
Tomas
A: 

I see the following options:

  • make both A and B implement a common Observable base class (and pass them as parameters to update() - the problem is, you need to downcast in update() to detect whether the parameter is of A or B, which makes the solution fragile
  • add some sort of type flag parameter to update() - this is fairly similar to the previous one, only less object oriented
  • templatize the Observer / Observable implementation - I haven't worked this out fully in my head (and I don't have a C++ IDE to verify it), but I believe this way you can have two overloads of update() with different (A and B) type parameters, thus the handling is separated and straightforward, so this would be my preferred option
Péter Török