The Observer design pattern in .NET, part 2

This is part 2 in a series about the Observer design pattern in .NET. In part one, we saw how to implement the pattern using the “classical” approach. In this part, we’ll see how to implement the Observer design pattern “the .NET way” using events. The use of .NET events allows us to reduce the amount of code, simplifying the SubjectPublisher class significantly. You can download the Observer design pattern example if you want to see the code in action.

What remains unchanged

First, let’s start with what remains the same: the IObserver interface and the ObserverSubscriber class remain unchanged. They still define the single Update() method.

What changes

The IObservable interface is totally changed. The former Subscribe(), Unsubscribe(), and NotifySubscriber() methods are gone, replaced by a single Update event that corresponds nicely with the Update() sub in ObserverSubscriber, which we’ll use as an event handler. Now the IObservable interface looks like this:

Public Interface IObservable
    Event Update(ByVal subject As IObservable)
End Interface

As mentioned earlier, in SubjectPublisher the Subscribe(), Unsubscribe(), and NotifySubscribers() methods are all gone. The Subscribe() and Unsubscribe() methods will be replaced by the AddHandler and RemoveHandler statements built into VB. The NotifySubscribers() method will be replaced by the Raiseevent statement built into VB. These changes cause a significant code reduction in SubjectPublisher, which now looks like this:

Public Class SubjectPublisher
    Implements IObservable
    Public Event Update(ByVal subject As IObservable) Implements IObservable.Update
    Private _headline As String = ""
    Public Property Headline() As String
        Get
            Return _headline
        End Get
        Set(ByVal value As String)
            If _headline <> value Then
                _headline = value
                RaiseEvent Update(Me)
            End If
        End Set
    End Property
End Class

Notice that there is no need to manage a list of subscribers anymore, all of that is handled by the .NET event handling mechanisms. This is what makes it possible to eliminate the Subscribe() and Unsubscribe() methods and replace the NotifySubscribers with a Raiseevent.

The test form

The test form was changed to use AddHandler/RemoveHandler instead of Subscribe/Unsubscribe, otherwise it is the same. Here’s the code:

Public Class Form1
    Private _subject As New SubjectPublisher
    Private _observer1 As New ObserverSubscriber
    Private _observer2 As New ObserverSubscriber
    Private _observer3 As New ObserverSubscriber
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub
    Private Sub uxSaveHeadline_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxSaveHeadline.Click
        _subject.Headline = uxHeadline.Text
        uxHeadline1.Text = _observer1.Headline
        uxHeadline2.Text = _observer2.Headline
        uxHeadline3.Text = _observer3.Headline
    End Sub
    Private Sub uxSubscribed1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxSubscribed1.CheckedChanged
        If uxSubscribed1.Checked Then
            AddHandler _subject.Update, AddressOf _observer1.Update
        Else
            RemoveHandler _subject.Update, AddressOf _observer1.Update
        End If
    End Sub
    Private Sub uxSubscribed2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxSubscribed2.CheckedChanged
        If uxSubscribed2.Checked Then
            AddHandler _subject.Update, AddressOf _observer2.Update
        Else
            RemoveHandler _subject.Update, AddressOf _observer2.Update
        End If
    End Sub
    Private Sub uxSubscribed3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles uxSubscribed3.CheckedChanged
        If uxSubscribed3.Checked Then
            AddHandler _subject.Update, AddressOf _observer2.Update
        Else
            RemoveHandler _subject.Update, AddressOf _observer2.Update
        End If
    End Sub
End Class

That’s it for today. Tune in later when we discuss how the .NET framework makes use of the Observer design pattern.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • bodytext
  • del.icio.us
  • Facebook
  • Google
  • Reddit
  • StumbleUpon
  • Technorati

Leave a Reply