Saturday, November 3, 2012

Observer Design Pattern

Although they are lots of books and articles about Design Patterns, yet I like to share my point of view about common design patterns with you, and would be happy to have your thoughts or questions on comments. This post introduces GoF Observer design pattern.

Definition
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. (dofactory) 


  • Subject knows its observers and provides an interface for attaching and detaching Observer objects. Any number of Observer objects may observe a subject
  • ConcreteSubject stores state of interest to ConcreteObserver and sends a notification to its observers when its state changes.
  • Observer defines an updating interface for objects that should be notified of changes in a subject.
  • ConcreteObserver maintains a reference to a ConcreteSubject object, stores state that should stay consistent with the subject's and implements the Observer updating interface to keep its state consistent with the subject's


  • The efficiency can be improved by specifying which are the events on which each observer is interested. This can be realized by adding a new class defining an aspect. When an observer is registering it will provide the aspects in which it is interested.
  • The subject state should be consistent when the notify operation is triggered. If changes are made in the subject state after the observer is notified, it will will be refreshed with an old state.
Applicability
  •  If you have an object that needs to share it's state with others, without knowing who those objects are, the Observer is exactly what you need. In other words, The change of a state in one object must be reflected in another object without keeping the objects tight coupled.
  • Model View Controller Pattern - The observer pattern is used in the model view controller (MVC) architectural pattern. In MVC this pattern is used to decouple the model from the view. View represents the Observer and the model is the Observable object.
  • Event management - This is one of the domains where the Observer patterns is extensively used. Swing and .Net are extensively using the Observer pattern for implementing the events mechanism. Usually, you wouldn't really implement the observer pattern in a language which supports events as they already provide what you are looking for. On the other hand, you can write event-driven in languages which lack events by using the observer pattern. The C# implementation of multicast delegates is observer or publish-subscribe pattern , it represents scenarios where notifications of single events, such as a change in object state, are broadcast to multiple subscribers.

Consequences
  • Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
  • Encapsulate the core (or common or engine) components in a Subject abstraction, and the variable (or optional or user interface) components in an Observer hierarchy.
  • Allows the number and “type” of observer objects to be configured dynamically, instead of being statically specified at compile-time.
  •  Observer pattern specifies a “pull” interaction model. Instead of the Subject “pushing” what has changed to all Observers, each Observer is responsible for “pulling” its particular “window of interest” from the Subject. 
  • Support for broadcast communication. The notification is broadcast automatically to all interested objects that subscribed to it.
  • Observes have no knowledge of each other and blind to the cost of changing in subject. With the dynamic relationship between subject and observers, the update dependency can be hard to track down.

Downsides
  • Side-effects: Observers promote side-effects. Since observers are stateless, we often need several of them to simulate a state machine as in the drag example. We have to save the state where it is accessible to all involved observers such as in the variable path above.
  • Composability: Multiple observers form a loose collection of objects that deal with a single concern (or multiple, see next point). Since multiple observers are installed at different points at different times, we can’t, for instance, easily dispose them altogether.
  • There is no guarantee for data consistency in the observer pattern.
  • The code is hard to understand because the control flow is inverted which results in too much boilerplate code that increases the semantic distance between the programmers intention and the actual code.
  • the separate observers needing to synchronize with each other ("Since observers are stateless, we often need several of them to simulate a state machine as in the drag example. We have to save the state where it is accessible to all involved observers such as in the variable path above.")
  • Watch out for memory leaks as the subject will hold a reference to the observer unless it has unregistered. Martin Fowler has a good list of gotchas for the observer. 

Sample Code
Sample 1 - Classic observer pattern


Sample 2 - Observer pattern using .NET event mechanism


Sample 3 - Observer pattern using .NET 4 IObserver and IObservable

Sample 4 - Observer pattern using INotifyPropertyChanged
Comment: CallerMemberName is supported in .NET 4.5


Related Patterns
  • Chain of Responsibility, Command, Mediator, and Observer, address how you can decouple senders and receivers, but with different trade-offs. Chain of Responsibility passes a sender request along a chain of potential receivers. Command normally specifies a sender-receiver connection with a subclass. Mediator has senders and receivers reference each other indirectly. Observer defines a very decoupled interface that allows for multiple receivers to be configured at run-time.
  • Mediator and Observer are competing patterns. The difference between them is that Observer distributes communication by introducing “observer” and “subject” objects, whereas a Mediator object encapsulates the communication between other objects. We have found it easier to make reusable Observers and Subjects than to make reusable Mediators. On the other hand, Mediator can leverage Observer for dynamically registering colleagues and communicating with them.

References
http://en.wikipedia.org/wiki/Observer_pattern
http://www.dofactory.com/Patterns/PatternObserver.aspx
http://sourcemaking.com/design_patterns/observer
http://www.oodesign.com/observer-pattern.html
http://java.dzone.com/articles/design-patterns-uncovered
http://lampwww.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf
http://msdn.microsoft.com/en-us/library/dd990377.aspx

Futher readings
http://msdn.microsoft.com/en-us/data/gg577609.aspx
http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
http://martinfowler.com/eaaDev/MediatedSynchronization.html
http://people.cs.clemson.edu/~malloy/courses/patterns/observer.html
http://msdn.microsoft.com/en-us/library/ff519622.aspx
http://msdn.microsoft.com/en-us/library/ff649664.aspx
http://msdn.microsoft.com/en-us/library/ee850490.aspx


No comments :

Post a Comment