Introduction
The observer design pattern defines a one to many dependency between an object and its dependents.
The dependency is created in order to inform the dependants that the object changed its state and therefore the dependants can react to the change.
A very good example of such behavior is the blogging systems were subscribers are notified whenever a blogger published a new post. Another real world example can be the MVC architecture pattern which uses the pattern.
Use Cases for the Observer Pattern
You should use the pattern in the following cases:
- You have a publisher/subscriber model.
- Objects need to be notified of a change in another objects.
- You need that the object that notify its state change would not know about its subscribers.
Observer using .NET Built in Features
Check this really cool Patterns and Practices article Implementing Observer in .NET.
UML Diagram
Example in C#
The following code is an example of how to implement the pattern:
#region Subject
public abstract class Subject
{
#region Members
private List<IObserver> _observers;
#endregion
#region Ctor
public Subject()
{
_observers = new List<IObserver>();
}
#endregion
#region Methods
public void Attach(IObserver observer)
{
_observers.Add(observer);
}
public void Detach(IObserver observer)
{
_observers.Remove(observer);
}
public void Notify()
{
foreach (IObserver observer in _observers)
{
observer.Update();
}
}
#endregion
}
#endregion
#region Concrete Subject
public class ConcreteSubject<T> : Subject
{
#region Properties
public T SubjectState { get; set; }
#endregion
}
#endregion
#region Observer
public interface IObserver
{
void Update();
}
#endregion
#region Concrete Observer
public class ConcreteObserver<T> : IObserver
{
#region Properties
public ConcreteSubject<T> Subject { get; set; }
private T _observerState;
#endregion
#region Ctor
public ConcreteObserver(ConcreteSubject<T> subject)
{
Subject = subject;
}
#endregion
#region IObserver Members
public void Update()
{
_observerState = Subject.SubjectState;
Console.WriteLine("The new state of the observer:{0}", _observerState.ToString());
}
#endregion
}
#endregion
The example is simple to follow.
We have an IObserver
interface and a Subject
abstract
class. The observers are registered in the subject with the Attach
method and also can be detached. The subject implements the Notify
method that notifies every observer when the subject state was changed.
When the state changes, the observer makes an update which is the main method of the IObserver
interface.
The following code is an example scenario of how to run the pattern in console application:
ConcreteSubject<string> subject = new ConcreteSubject<string>();
subject.Attach(new ConcreteObserver<string>(subject));
subject.Attach(new ConcreteObserver<string>(subject));
subject.SubjectState = "Hello World";
subject.Notify();
Console.Read();
Summary
To sum up, the observer pattern is widely used and it is very helpful.
You can see the uses of the pattern in the MVC framework for example or in the Microsoft blogs when you subscribe to a blog in order to be notified of new blogger posts. The next post in the design patterns series will be the last pattern post and it will include the interpreter pattern.