Design patterns: Observer

The Observer design pattern is used when you want to define a one-to-many dependency between objects. In case one object changes its state, all its dependents are notified and updated automatically.

In this design pattern you have two participants. The first one is the observable object, which knows his observers and provides an interface for attaching, detaching and notifying observer objects. The second participant or group of participants is the objects which want to be informed. These observer objects will implement a notification interface which is called by the observable object.

Following I want to show a simple implementation if this design pattern which is not thread-safe. In our example we want to create database connection which has status information. To keep it simple the status information is a string only.  Furthermore we want to create a user interface which shall show the database connection status within the main view and within a status bar. Therefore we have an observable object: the database connection, and several observers: the views.

The notification between the participants is done by events. So we start with an EventArgs class and an interface for the observer classes which contain the event receiver definition.

public class StatusChangedEventArgs : EventArgs
{
    public string Status { get; set; }        
}

public interface IStatusObserver
{
    void StatusChanged(object sender, StatusChangedEventArgs e);
}

At next we can implement a base class for the observable database connection class. As we implement it as abstract base class it can be reused for other observable classes to.

public abstract class StatusObservable
{
    private event EventHandler<StatusChangedEventArgs> _statusChanged;

    public void AttachObserver(IStatusObserver observer)
    {
        _statusChanged += observer.StatusChanged;
    }

    public void DetachObserver(IStatusObserver observer)
    {
        _statusChanged -= observer.StatusChanged;
    }
        
    public void NotifyAllObserver(StatusChangedEventArgs e)
    {
        if (_statusChanged != null)
        {
            _statusChanged(this, e);
        }
    }
}

Based on the observable class we will implement the database connection class. It contains two template methods to connect and disconnect the database. These methods will execute a status change which will trigger the observer notification process.

public class DatabaseConnection : StatusObservable
{
    public void Connect()
    {
        //todo: connect to database

        //change status            
        ChangeStatus("connected");
    }

    public void Disconnect()
    {
        //todo: disconnect from database

        //change status            
        ChangeStatus("disconnected");
    }

    private void ChangeStatus(string status)
    {
        NotifyAllObserver(new StatusChangedEventArgs() { Status = status });
    }
}

Now we can create the two view classes which will observe the database connection. To keep it simple these classes contain the interface implementation only and write the received status update to the console.

public class MainView : IStatusObserver
{
    public void StatusChanged(object sender, StatusChangedEventArgs e)
    {
        Console.WriteLine("MainView - StatusChanged received - new status: " + e.Status);
    }
}

public class StatusBar : IStatusObserver
{
    public void StatusChanged(object sender, StatusChangedEventArgs e)
    {
        Console.WriteLine("StatusBar - StatusChanged received - new status: " + e.Status);
    }
}

To test the implementation we can create a little console application. Within this application we will attach the observers to the observable database connection and execute some methods of this class. The according notifications will be send and shown as output in the console. Before the application gets closed, the observers will be detached from the observable class.

static void Main(string[] args)
{
    //create objects
    DatabaseConnection databaseConnection = new DatabaseConnection();
    MainView mainView = new MainView();
    StatusBar statusBar = new StatusBar();

    //attach observer
    databaseConnection.AttachObserver(mainView);
    databaseConnection.AttachObserver(statusBar);

    //change status in observable object
    databaseConnection.Connect();
    databaseConnection.Disconnect();

    //detach observer
    databaseConnection.DetachObserver(mainView);
    databaseConnection.DetachObserver(statusBar);

    Console.ReadKey();
}
Advertisements
Dieser Beitrag wurde unter .NET, C#, Design Pattern veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Eine Antwort zu Design patterns: Observer

  1. dvb t2 schreibt:

    Grüß Gott. Ich bin per Zufall hier gelandet. Aber trotzdem möchte ich ihnen ein Kommentar da
    lassen, da ich ihren Weblog sehr interessant finde.

    Auch ihr Entwurf ist sehr sympathisch.

    MfG

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s