The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.
- A one-to-many dependency between objects should be defined without making the objects tightly coupled.
- It should be ensured that when one object changes state an open-ended number of dependent objects are updated automatically.
- It should be possible that one object can notify an open-ended number of other objects.
- Define
SubjectandObserverObjects - When a subject changes state, all registered observers are notified and updated automatically.
Subject (IObservable)
- provides an interface for attaching and detaching Observer objects.
ConcreteSubject (WeatherData)
- knows its observers.
- sends a notification to its observers when its state changes
Observer (IObserver)
- defines an updating interface for objects that should be notified of changes in a subject.
ConcreteObserver (CurrentConditionDisplay)
- maintains a reference to a ConcreteSubject object
- implements the Observer updating interface to keep its state consistent with the subject's.
ConcreteSubject notifies its observers whenever a change occurs.
After being notified, a ConcreteObserver object may query the subject for information.
The Observer object that initiates the change request postpone its update until it gets a notification from the subject to avoid redundant updates.
- Notify can be called by Subject, Observer or by any other object.
- Abstract coupling between Subject and Observer.
- Subject is not coupled to concrete classes. All a subject knows is that it has a list of observers, each conforming to abstract
Observerinterface.
- Subject is not coupled to concrete classes. All a subject knows is that it has a list of observers, each conforming to abstract
- Observers can be attached and detached dynamically.
- Support for broadcast communication
- The subject doesn't care how many interested objects exist. The notification is broadcast automatically to all of them. It's up to the observer to handle or ignore a notification.
- Observers are notified in random order.
- Unexpected updates
- A seemingly innocuous operation on the subject may cause a cascade of updates to observers and their dependent objects.
- If dependency criteria aren't well-defined or maintained, it can lead to spurious updates, which can be hard to track down.
Definition
// Observable / SubjectpublicinterfaceIObservable<T>{voidaddObserver(IObserver<T>observer);voidremoveObserver(IObserver<T>observer);voidnotifyObservers();}// ObserverpublicinterfaceIObserver<T>{voidUpdate(Tdata);}Usage
WeatherDatadata=newWeatherData(13);CurrentConditionDisplaydisplay1=newCurrentConditionDisplay("Display1",data);// OUTPUT --> Display1 - Temperature: 13CurrentConditionDisplaydisplay2=newCurrentConditionDisplay("Display2",data);// OUTPUT --> Display2 - Temperature: 13// update the temperature.data.Temperature=14;// Display 1 and 2 show the new temperature// OUTPUT: /* Weather data is updated Display1 - Temperature: 14 Weather data is updated Display2 - Temperature: 14 */data.removeObserver(display2);data.Temperature=15;// Only Display 1 shows the new temperature// OUTPUT: /* Weather data is updated Display1 - Temperature: 15 */Console.ReadLine();Checkout built-it Observer Pattern in .NET - Observer Design Pattern Best Practices
Define update method as a delegate.
publicdelegatevoidTemperatureChanged(WeatherDataWithEventweatherData);ConcreateSubject/Observable creates an event with the defined delegate method above.
publicclassWeatherDataWithEvent{privatefloattemperature;// declare event OnTemperatureChangedpubliceventTemperatureChangedOnTemperatureChanged;publicfloatTemperature{get{returnthis.temperature;}set{this.temperature=value;// event subscribers will be notifiedOnTemperatureChanged?.Invoke(this);}}}
```
Observerscan register themselves as follows
```cs
// Class: CurrentConditionDisplayWithEvent// subscribeweatherData.OnTemperatureChanged +=this.OnTemperatureChanged;// unsubscribeweatherData.OnTemperatureChanged-=this.OnTemperatureChanged;- Mediator - By encapsulating complex update semantics, the ChangeManager acts as mediator between subjects and observers.
- Singleton: The ChangeManager may use the Singleton pattern to make it unique and globally accessible.

