Click here to Skip to main content
13,248,343 members (58,809 online)
Click here to Skip to main content
Add your own
alternative version


28 bookmarked
Posted 1 Jan 2004

Implementing Observer Pattern in VB.NET

Rate this:
Please Sign up or sign in to vote.
This article shows an easy way of implementing the Observer pattern in VB.NET

Observer pattern demystified

The Observer pattern is useful when you need to present data in several different forms at once. The Observer is intended to provide you with a means to define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. The object containing the data is separated from the objects that display the data and the display objects observe changes in that data.

There are basically two different types of objects: a Subject and an Observer. The Subject corresponds to the data object whose state you want to track. The Observer is the object that is interested in changes in the Subject's data. To set up the pattern, Subject classes implement a method for registering Observers and for attaching and detaching them from a collection object.

You also need a Notify(...) method to notify all registered Observers when the data has changed. For Observers, you define a custom abstract Observer class to provide clients with a uniform interface, and subclass the implementation details.

Base Implementation

Firstly, we define a public interface called Observer:

Public Interface Observer
  Sub Update(ByVal subj As Object)
End Interface

All our observers (i.e. objects that will be interested in data changes) will have to implement this interface.

Then we define an abstract (MustInherit in VB.NET) class called Subject. This is the base class for all objects whose state we are going to watch.

Public MustInherit Class Subject

A collection where we want our observers to be stored.

Private _observers As New ArrayList()

Methods for adding and removing observers

Public Sub AddObserver(ByRef ob As Observer)
End Sub

Public Sub RemoveObserver(ByRef ob As Observer)
End Sub

And at last, a public method that will notify all our observers that subject’s state has changed.

  Public Sub Notify()
    Dim ob As Observer
    For Each ob In _observers
  End Sub
End Class

We are through with the abstract part of the implementation.

Live Example

We will implement 3 classes (one of them is only for convenience). First one is Broker:

' Class Broker
' one of the model's participants
Public Class Broker
  Private _name As String
  Private _balance As Decimal
  Private _acc As New BrokerAccount(Me)
  Public ReadOnly Property Account() As BrokerAccount
      Return _acc
    End Get
  End Property
  Public Sub New()
  End Sub
  Public Property Name() As String
      Return _name
    End Get
    Set(ByVal Value As String)
      _name = Value
    End Set
  End Property
  Public Property Balance() As Decimal
      Return _balance
    End Get
    Set(ByVal Value As Decimal)
      _balance = Value
    End Set
  End Property
End Class 'Broker

Second one is BrokerAccount – a class responsible for changing Broker’s balance.

Public Class BrokerAccount
  Inherits Subject
  Private _br As Broker
  Public Class InvalidBalanceException
    Inherits Exception
    Public Sub New()
      MyBase.New("Broker balance is less than debited amount!")
    End Sub
  End Class
  Public Sub New(ByRef br As Broker)
    _br = br
  End Sub
  Public Sub Credit(ByVal adAmount As Decimal)
    _br.Balance += adAmount
  End Sub
  Public Sub Debit(ByVal adAmount As Decimal)
    If _br.Balance - adAmount < 0 Then
      Throw New InvalidBalanceException()
      _br.Balance -= adAmount
    End If
  End Sub
End Class 'BrokerAccount

And a helper class – collection of Broker objects.

Public Class BrokerCollection
  Inherits ArrayList
  Default Public Overrides Property Item(ByVal index As Integer) As Object
      Return MyBase.Item(index)
    End Get
    Set(ByVal Value As Object)
      If Not TypeOf Value Is Broker Then
        Throw New Exception("Can't hold objects of other than Broker type")
        MyBase.Item(index) = Value
      End If
    End Set
  End Property
  Public Overrides Function Add(ByVal value As Object) As Integer
    If Not TypeOf value Is Broker Then
      Throw New Exception("Can't hold objects of other than Broker type")
      Return MyBase.Add(value)
    End If
  End Function
End Class

The provided sample (MV_Form) gives you a quick overview on how to use this pattern in a Windows Forms application:

Public Class Form1
  Inherits System.Windows.Forms.Form
  Implements MV_Objects.Observer

Form_Load event: Here we initialize a ListView control that holds the list of 10 brokers. Each list view is associated with a Broker object through its Tag property (very useful one indeed :))

For i = 1 To 10
   br = New Broker()
   br.Name = "broker " & i

   itm = New ListViewItem(New String() {br.Name, br.Balance})
   itm.Tag = br


The following sub implements Update method of the Observer interface. It finds the entry which is associated with a certain broker in the ListView and updates the balance column.

Public Sub UpdateBrokers(ByVal subj As Object) _ 
             Implements MV_Objects.Observer.Update
    Dim br As Broker, itm As ListViewItem
    For Each itm In lvBr.Items
      br = itm.Tag
      If br.Account Is subj Then
        itm.SubItems(1).Text = br.Balance
      End If
  End Sub

Also there are 2 buttons and a text box on the form. Their implementation is trivial and not presented in the article for the sake of being concrete.

The End

That’s it! Run the attached sample application to see how it works. You can place a breakpoint on methods Credit and Debit of the BrokerAccount class and step through with a debugger. It’s really a simple but powerful pattern which can used for several more purposes. You are welcome to mention them in the forum :)

One more thing that can be added to this small project is putting each update procedure in a separate thread. It’s OK when the number of objects being watched is small, but fails on other cases. Any hints on this problem (when the number of objects is more than 50,000) will be really appreciated.


This article is based on the work by James Maioriello, Ph.D., where he describes basic design patterns. Sorry, I don’t remember where I got it from, but anyway, I did acknowledge it :)


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Serge Lobko-Lobanovsky
Web Developer
Belarus Belarus
I work for Logic Software ( as a lead .NET developer/architect.

You may also be interested in...

Comments and Discussions

GeneralJust curious... Pin
schmig6-Jan-04 3:16
memberschmig6-Jan-04 3:16 
GeneralRe: Just curious... Pin
Serge Lobko-Lobanovsky6-Jan-04 4:50
memberSerge Lobko-Lobanovsky6-Jan-04 4:50 
GeneralRe: Just curious... Pin
schmig6-Jan-04 5:01
memberschmig6-Jan-04 5:01 
GeneralRe: Just curious... Pin
Serge Lobko-Lobanovsky6-Jan-04 5:27
memberSerge Lobko-Lobanovsky6-Jan-04 5:27 
GeneralRe: Just curious... Pin
schmig6-Jan-04 5:37
memberschmig6-Jan-04 5:37 
GeneralRe: Just curious... Pin
Serge Lobko-Lobanovsky6-Jan-04 6:04
memberSerge Lobko-Lobanovsky6-Jan-04 6:04 
Fallen more deeply into this problem I see that I actually need to implement a Chain-Of-Resposibility pattern, because I need to somehow "bubble" the events through the hierarchy, and handle them on several levels in turn.

schmig wrote:
But the pros/cons of using delegates vs. some of my own Observer implementations is something I've been looking at recently, and I've yet to figure out the benefits of using my own code (unless you need additional functionality that's outside the scope of the pattern, that is).

I think that both approaches are good Smile | :) In MSDN they clearly state that implementing the pattern by yourself is like re-inventing the wheel, cuz it has already been done through events and delegates.

However, there is always a "tastes differ" approach Smile | :) I implemented this pattern and thought it was great Big Grin | :-D
GeneralRe: Just curious... Pin
bsherwin6-Jan-04 15:53
memberbsherwin6-Jan-04 15:53 
GeneralRe: Just curious... Pin
Serge Lobko-Lobanovsky6-Jan-04 23:52
memberSerge Lobko-Lobanovsky6-Jan-04 23:52 
GeneralRe: Just curious... Pin
BVandenbon22-Aug-07 4:38
memberBVandenbon22-Aug-07 4:38 
GeneralRe: Just curious... Pin
displaced16-Apr-08 12:53
memberdisplaced16-Apr-08 12:53 
GeneralUm... Pin
obelisk292-Jan-04 17:48
memberobelisk292-Jan-04 17:48 
GeneralRe: Um... Pin
Serge Lobko-Lobanovsky3-Jan-04 0:23
memberSerge Lobko-Lobanovsky3-Jan-04 0:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171114.1 | Last Updated 2 Jan 2004
Article Copyright 2004 by Serge Lobko-Lobanovsky
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid