Friday, May 31, 2013

Implementing Observer Design Pattern in VBA without Events

Observer Design Pattern (DP) can be useful tool in your DP toolpack. Now, for what reason is this pattern used for? For example, looking closely to Bloomberg BBCOM API methods and its mechanism, leads me to assume strongly that the market data retrieving process has been implemented by using Observer DP. You could use this pattern, if you get some feed from somewhere and you would like to save the result of that feed to somewhere else, for example.

Anyway, In the following example below, I am presenting one possible VBA implementation of Observer DP, without using Events. First we create "source" class (VBA Class Module, name = DataSource):

Option Explicit
'
Private observers As Collection
Private data As Double
'
Public Function registerObserver(ByRef observer As DataObserver)
    '
    Debug.Print "Observer " & ObjPtr(observer) & " registered"
    observers.Add observer
End Function
'
Public Function unRegisterObserver(ByRef observer As DataObserver)
    '
    Dim i As Integer
    For i = 1 To observers.Count
        If ((ObjPtr(observers(i)) = (ObjPtr(observer)))) Then
            Debug.Print "Observer " & ObjPtr(observers(i)) & " unregistered"
            observers.Remove i
            Exit For
        End If
    Next i
End Function
'
Private Function notifyObservers()
    '
    If (observers.Count > 0) Then
        Dim i As Integer
        For i = 1 To observers.Count
            observers(i).updateMarketData (data)
        Next i
    End If
End Function
'
Public Function getMarketDataUpdate(ByVal marketData As Double)
    '
    data = marketData
    notifyObservers
End Function
'
Private Sub Class_Initialize()
    Set observers = New Collection
End Sub
'
Private Sub Class_Terminate()
    Set observers = Nothing
End Sub
'

Then we create class for "observers" (VBA Class Module, name = DataObserver):

Option Explicit
'
Private data As Double
'
Private Function displayMarketData()
    Debug.Print "Market data update from observer " & ObjPtr(Me) & ": " & data
End Function
'
Public Function updateMarketData(ByVal marketData As Double)
    data = marketData
    displayMarketData
End Function
'

Then we create tester program (VBA Standard Module). In tester program, I have been creating one test run, in which the data source is registering/unregistering observers and sending data feed for them:

Option Explicit
'
Public Sub tester()
    '
    ' create data source object and two observers
    Dim source As New DataSource
    Dim observer1 As New DataObserver
    Dim observer2 As New DataObserver
    '
    ' register both observers
    source.registerObserver observer1
    source.registerObserver observer2
    '
    ' data source sends feed to both observers
    source.getMarketDataUpdate 100.25
    source.getMarketDataUpdate 100.15
    '
    ' unregister observer2, data source sends feed to observer1
    source.unRegisterObserver observer2
    source.getMarketDataUpdate 100.1
    '
    ' unregister observer1, no data feed to any observer
    source.unRegisterObserver observer1
    source.getMarketDataUpdate 100.1
    '
    ' re-register observer1, data source sends feed to observer1
    source.registerObserver observer1
    source.getMarketDataUpdate 100.2
    '
    ' re-register observer2, data source sends feed to both observers
    source.registerObserver observer2
    source.getMarketDataUpdate 100.25
    '
    ' destroy source and observers
    Set observer2 = Nothing
    Set observer1 = Nothing
    Set source = Nothing
End Sub
'

Resulting Immediate Window printout (observer1 in blue, observer2 in red):

Observer 242968104 registered
Observer 242967944 registered
Market data update from observer 242968104: 100,25
Market data update from observer 242967944: 100,25
Market data update from observer 242968104: 100,15
Market data update from observer 242967944: 100,15
Observer 242967944 unregistered

Market data update from observer 242968104: 100,1
Observer 242968104 unregistered
Observer 242968104 registered
Market data update from observer 242968104: 100,2

Observer 242967944 registered
Market data update from observer 242968104: 100,25
Market data update from observer 242967944: 100,25

This was one possible implementation of Observer DP in a nutshell. Nice to know. Have a nice day. 
-Mike

No comments:

Post a Comment