The Observer pattern is intended to provide you with a means to present data in several different forms at once so that when one object changes state, all its dependents are notified and updated automatically.

observer-pattern

The Observer pattern can be found everywhere. Mostly it is used when you have more than one view on the same data. For example, a list view and a detail view.

In the client, a couple of observers are attached to their subject of interest. As soon as the state of the subject changes, all observers are notified that there is a change of state.

class Client
{
    static void Main()
    {
        ConcreteSubject subject = new ConcreteSubject();

        ConcreteObserver observer1 = new ConcreteObserver(subject, "A");
        subject.Attach(observer1);

        ConcreteObserver observer2 = new ConcreteObserver(subject, "B");
        subject.Attach(observer2);

        subject.SubjectState = "NEW_SUBJECT_STATE";
        subject.Notify();

        Console.ReadKey();
    }
}

The abstract parent class Subject contains a list of observers and methods necessary for attaching and detaching observers. Most important method is notify which traverses the list and notifies all attached observers.

abstract class Subject
{
    private List m_Observers = new List();
    public void Attach(Observer observer)
    {
        m_Observers.Add(observer);

    }
    public void Detach(Observer observer)
    {
        m_Observers.Remove(observer);

    }
    public void Notify()
    {
        foreach (Observer o in m_Observers)
        {
               o.Update();
         }
    }
}

The concrete child class contains a certain state, which can be virtually anything. In this example, something simple. Just a string containing im-por-tant information.

class ConcreteSubject : Subject
{
    public string SubjectState { get; set; }
}

All observers need some way to update their state when they are notified. This is done by implementing the Update method of abstract class Observer.

abstract class Observer
{
    public abstract void Update();
}

The concrete observer implements the abstract update method, plus its own methods.

class ConcreteObserver : Observer
{
    private string m_Name;
    private string m_ObserverState;

    public ConcreteObserver(ConcreteSubject subject, string name)
    {
        this.Subject = subject;
        this.m_Name = name;
    }

    public override void Update()
    {
        m_ObserverState = Subject.SubjectState;
        Console.WriteLine("Observer {0}'s new state is {1}", m_Name, m_ObserverState);
    }

    public ConcreteSubject Subject { get; set; }
}

When you think about the problem this pattern solves, you probably agree with me that this is a relatively simple but powerful pattern.

This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.