0

I'm reading about Observer Pattern of GoF, the UML in the book: UML of Observer Pattern

From the above diagram, how many Observer interface are there in a system if I have two different ConcreteSubject classes? Would they share the same Observer interface? Or is that each (Concrete)Subject classes should have its corresponding Observer interface for which those ConcreteObserver classes interested in it can subscribe?

If entire system share only one Observer interface, as the diagram expressed, then how can a class subscribe(i.e. implement) for many different ConcreteSubject classes? Wouldn't all the code for different ConcreteSubject classes lumped into the same ConcreteObserver class?

Could anyone point out which part(s) is(are) incorrect?

4
  • 7
    You seem to be misunderstanding - a design pattern is just a concept; it's not a set of rules which dictate how to implement your code. If you are trying to implement the pattern exactly as described in the GoF book then you're missing the point. You should implement your code in whatever way actually meets your requirements, Therefore, if you need multiple Subjects or multiple Observers then that is a matter for your specific implementation; there's no right or wrong way to use the pattern as long as you aren't attempting to fit a square peg into a round hole. Apr 1 '19 at 11:49
  • @BenCottrell: I'm trying to verify my concept about it through the diagram it provided. My current understanding from this pattern is that the subject shouldn't assume much about its observers' actual types and this is done by an abstract interface Observer, and my question is that whether each subject has its own Observer interface.
    – NingW
    Apr 1 '19 at 11:58
  • 6
    What you're asking here is really an implementation detail which depends upon your requirements. If you have a requirement which means that each of your subjects need to expose a different interface for each subject (because you are observing different things) then there's nothing wrong with that. Similarly, if you don't need multiple different interfaces then you gain no benefit by creating additional redundant interfaces. Apr 1 '19 at 12:36
  • @BenCottrell: Thank you, I thought only one would be correct...
    – NingW
    Apr 1 '19 at 12:43
5

I'm trying to verify my concept about it through the diagram it provided. My current understanding from this pattern is that the subject shouldn't assume much about its observers' actual types and this is done by an abstract interface Observer, and my question is that whether each subject has its own Observer interface.

Comment by Niing

The abstract Subject and the abstract Observer have no knowledge of the concrete details. They only know enough to let the Subject control when updates happen. Not how.

ConcreteObservers may be many different types but they all must know enough about the ConcreteSubject to request and use subjectState. ConcreteSubjects can be different types as well provided requesting and using their subjectState is identical. A different interface could be created to ensure this if needed but that's not usually part of whats called the observer pattern.

I think I still can't understand about how one observer subscribe for multiple subjects, but I appreciate your current answer

Comment by Niing

One observer subscribing to multiple subjects isn't the usual pattern but it's possible, in two different ways:

First we should be clear if we're talking about classes or objects. What you've been looking at above is a class diagram. One class can be used to create multiple objects configured in different ways. That can cause confusion with this question so let me address both.

In the case where there are many different classes talking to many other and different classes all of the above still works provided you allow for polymorphism in some way. Whatever defines the getState() method signature, and so the subjectState returned, needs to hide the differences in the different ConcreteSubjects from the ConcreteObserver.

In other words ConcreteObserver doesn't need to know what it's talking to. Just how to talk to it. So long as it doesn't know what exactly it's talking to, it can talk to anything that speaks it's language. Polymorphism in a nutshell.

In the case where they are simply different objects but always of the same types (classes or interfaces) the polymorphism requirement can be lessened since the only difference between the objects is their state and reference address.

However, if your issue is actually that you want one observer object to be able to track multiple subject objects at the same time there is a minor tweak that helps. In this situation it's easy to get confused and ask for getState() from the wrong subject. A nifty trick is to have your subject send a this or self (depending on language) reference back with the update(). This way you know exactly which subject to call getState() on.

When there's only one subject this is sometimes left out of the pattern because they can reuse the reference that was used to subscribe. Why not do it every time? YAGNI.

And as Caleth points out you don't have to use a getter at all. You can have the subject send subjectState as a parameter of Update.

On the issue of using getter vs parameter you wont find many observer pattern text authors commenting. You will find plenty of tell, don't ask authors commenting.

If you want to go down that road I highly advise you be sure you know the difference between an event and a command because you're creating an event and should treat it as such.

9
  • I think I still can't understand about how one observer subscribe for multiple subjects, but I appreciate your current answer...
    – NingW
    Apr 1 '19 at 13:08
  • @Niing In the above diagram, it doesn't. If you leave off the subject member, and instead pass the state as a parameter to Notify, then you can easily have an Observer watching multiple Subjects
    – Caleth
    Apr 1 '19 at 13:36
  • Sorry I don't understand your "In the case where there are many different classes with different types...", I used the word type in your first quoted description but I actually regarded it the same as class, could you elaborate more about "classes with different types"? (And many thanks for helpful edit!)
    – NingW
    Apr 1 '19 at 18:12
  • @Niing better now? Apr 1 '19 at 18:33
  • "In other words ConcreteObserver doesn't need to know what it's talking to. Just how to talk to it.": so ConcreteObserver should use Subject interface to talk to those different ConcreteSubjects, but Subject interface don't define getState()? (Sorry if this is too implementation details but I would like to implement it after all...)
    – NingW
    Apr 1 '19 at 19:03
0

The Observer interface should be 1 and so should be the Subject. This is done for decoupling. The actual concrete observer(s) and subject(s) will implement these interfaces.

In your ConcreteSubject you ll maintain a list of Observer and you can have there different classes of ConcreteObserver. So, the relationship of ConcreteObserver and ConcreteSubject is not 1-1 (or else we wouldn't need the interfaces).

4
  • Suppose a Person interested in BookStore's weekly news, and Library's weekly news, so the person will subscribe for both subjects, then if only one interface BookReader, a Person class will contain two unrelated implementation in it, wouldn't this cause any problem?
    – NingW
    Apr 1 '19 at 12:19
  • you will have 1 class implemenring observer, Person and 2 implementing observables, BooStore and Library, if i get it right. The person will be injected in constructor a list of observables. This way person subscribes where u want and stays decoupled. Am i missing something on your question? Apr 1 '19 at 16:42
  • Since only 1 class Person implements the observer interface(BookReader), it will have only one update() method from this interface, but this person subscribes to two observables, which means this single update() method have to contain two segments of code dealing with two different observables. So wouldn't this be a problem?
    – NingW
    Apr 1 '19 at 17:47
  • i think this pattern focuses on how, many observers can subscribe to one observable. if 1 observable notifies observers calling update(x, y) then an observer can use abstracrion in its 'update' and the other division. Not on how one observer can subscribe with the same method in 2 observables. then u might need 2 implementations of the pattern, with 2 'update' methods etc. But u can even subscribe to 2 subjects, if they are handled similarly, if you pass the proper params in 'update'. So if the latter is the case, u have the pattern and the concepts behind it. Try to use it for your own case Apr 1 '19 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.