The references (GOF Design Patterns, Head First Design Patterns, http://www.dofactory.com/Patterns/PatternObserver.aspx) that I've read regarding the observer design pattern stipulate that the concrete subject holds a reference to the concrete observer. Much like this:
class ConcreteObserver : IObserver
{
ConcreteSubject concreteSubjectInstance;
//other code, etc.
}
Now, if the concrete Subject is itself implements a Subject interface (or derives from some abstract Subject class) why not make the type in the ConcreteObserver be of that abstract/interface? I.e.
class ConcreteObserver : IObserver
{
ISubject concreteSubjectInstance;
//other code, etc.
}
Moreover, why not just make it a field in the (e.g.) IObserver
interface?
Ultimately, given that the pattern itself seems to loosen the coupling of the Subject to its Observers, why does this appear not to be promoted when coupling an Observer to its subject?
Or is it? I am only basing this on examples that I have read.
Concrete observer - implements the interface for responding to change using information about the change obtained from the concrete subject.
In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
The Observer Pattern provides an object design where subjects and observers are loosely coupled. They are loosely coupled in ways, The subject and observer does not need to know the concrete implementations of each other.
The Observer Pattern is useful in cases where there are multiple objects (or modules, or components) that are dependent on a single piece of state.
From your picture, your "update()" method does not receive any information about the state of the Subject, so, if the Observer needs information about this state (as usual in the observer pattern), then it must retrieve it from the ConcreteSubject invoking to the "GetState()" method (not present in ISubject).
An alternative to this schema, would be to pass the state (or a reference to the whole ConcreteSubject) as parameter of "update()" method.
Other general explanations to having a reference to ConcreteSubject instead of ISubject can be that you may want to interact with the ConcreteSubject to invoke business logic (of course not exposed in the ISubject interface).
Just because the definition you read states subject holds a reference to the concrete observer
doesn't mean you have to read it literally.
As long as the subject has a reference/link to the observer whether concrete or via an interface/class the statement remains true.
Its very common to see an interface on both side IObserver and IObservable. I think the issue you are going to find is that when you make subject abstract you are going to really have to try hard and find how to make your state generic.
Concrete Observer, and Concrete Subject implementation have state too. When state of subject is changes, state of concrete observer is updating too. But sometimes, you might need to see the state of subject, which you do not have, for this, you had better have reference to subject. In the other words, in order to see the state of concrete subject.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With