Design Patterns: Observer Pattern

By | 2015-11-17

In our look at Design Patterns, our next pattern is the Observer Pattern. The Observer Pattern creates a one-to-many relationship between the Observable and the Observers. This enables one part of your code to update or notify another part of code that something has happened. There are a few different ways to go about setting up the Observer Pattern in C#. We will look at the most traditional way of doing this. The model we will be updating and observing on will be a simple Alert class:

public class Alert
{
    public string Message { get; set; }
}

In the Observer Pattern you have two main types of classes. You have an Observable class and then one or more Observer classes. For our Observable class let’s create a class called MessageCenter that inherits from System.IObservable. For now, we will look at using the traditional System.IObservable instead of IObservable<T> to show the basics. You can press Ctrl+. over System.IObservable and select “Generate Interface for IObservable…” to generate a blank interface.
Generate Interface

Interfaces
Our IObservable interface will have three methods, a Subscribe and an Unsubscribe that will take an argument of System.IObserver (we will create this interface, too), and a NotifyObservers method. Our IObserver interface will contain one method for Notify. Here are our two interfaces:

public interface IObservable
{
    void Subscribe(System.IObserver observer);
    void Unsubscribe(System.IObserver observer);
    void NotifyObservers();
}

public interface IObserver
{
    void Notify();
}

Observable
Back to our MessageCenter class, we will implement our interface and fill in Subscribe, Unsubscribe, and NotifyObservers methods. We will also create a field to hold our list of Observers and a full property for our Alert class. Our Subscribe method will simply add Obsevers to the Observer List, the Unsubscribe method will remove an Observer from the list if it exists, and the NotifyObservers method will call the Notify method on each Observer. In our Alert property the setter will contain a call to this.NotifyObservers() to notify all observers the value has been updated. Here is what our class should look like:

public class MessageCenter : System.IObservable
{
    private List<IObserver> _observers;

    public MessageCenter()
    {
        _observers = new List<IObserver>();
    }
    public void NotifyObservers()
    {
        _observers.ForEach(x => x.Notify());
    }

    public void Subscribe(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void Unsubscribe(IObserver observer)
    {
        if (_observers.Contains(observer))
            _observers.Remove(observer);
    }

    private Alert _alert;
    public Alert Alert
    {
        get { return _alert; }
        set { _alert = value; this.NotifyObservers(); }
    }
}

Observers
No we must build our observers. The Observers will get notified every time the value changes for the Observable’s Alert property. Create a class that implements the System.IObserver interface. The constructor will take a instance of the MessageCenter class and save it to a private field before calling the MessageCenter’s Subscribe method to subscribe to notifications by default. Then in the Notify method we will retrieve the value of the MessageCenter instance’s Alert values and then call a method to act upon that value. For sake of example we will write out to the console window. The Observer class should look like this:

public class Observer1 : System.IObserver
{
    private MessageCenter _msgCenter;
    private string _message;
    public Observer1(MessageCenter msgCenter)
    {
        _msgCenter = msgCenter;
        _msgCenter.Subscribe(this);
    }

    public void Notify()
    {
        _message = _msgCenter.Alert.Message;
        WriteOutput();
    }

    private void WriteOutput()
    {
        Console.WriteLine("Observer1 received the message: {0}", _message);
    }
}

Now make two more Observer classes(can be Observer2 and Observer3) and change the string in the WriteOutput method.

Implementation
Implementing these classes are as simple as 1, 2, 3. First, create an instance of the MessageCenter class. Secondly, create instances of the Observer classes, passing the MessageCenter instance to the constructors. Thirdly, change the value of the MessageCenter‘s Alert property to kick off a notification to the Observers. In our simple console app it should look like:

static void Main(string[] args)
{

    MessageCenter msgCenter = new MessageCenter();
    Observer1 o1 = new Observer1(msgCenter);
    Observer2 o2 = new Observer2(msgCenter);
    Observer3 o3 = new Observer3(msgCenter);

    msgCenter.Alert = new Alert { Message = "NEW ALERT!!!  OBSERVER PATTERN IN USE!" };

    while(Console.ReadLine() != "quit") { }
}

Our output should look like:
Observer1 received the message: NEW ALERT!!! OBSERVER PATTERN IN USE!
Observer2 received the message: NEW ALERT!!! OBSERVER PATTERN IN USE!
Observer3 received the message: NEW ALERT!!! OBSERVER PATTERN IN USE!

This completes the example to setting up the Observer Pattern from scratch the traditional way. In .Net4 there is an IObservable<T> and IObserver<T> and these are setup a little differently. An example of that method can be found here.