Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Synchronize Data Among Objects with the Publish/Subscribe Design Pattern : Page 3

Use the Publish/Subscribe design pattern to propagate changes to data between objects in your application.

How EventApp Works
When EventApp starts up, frmMain (the MDI parent form) creates an instance of the data event channel, clsDataEvents, at the module level. The instance is kept in memory:

Private Sub frmMain_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles MyBase.Load mobjDataEventChannel = New clsDataEvents() Me.IsMdiContainer = True Me.Text = "Publish/Subscribe Event Sample" Me.WindowState = FormWindowState.Maximized End Sub

When the MDI form is loaded, you can select "File->New List" from the menu to create a new instance of frmList:

Private Sub MenuItem2_Click(ByVal sender As _ System.Object, ByVal e As System.EventArgs) _ Handles MenuItem2.Click Dim objNewForm As frmList objNewForm = New frmList() mobjDataEventChannel.AttachSubscriber(objNewForm) objNewForm.MdiParent = Me objNewForm.Show() End Sub

When the child form is created, it is registered with the data event channel. During the registration process, the event channel will initialize the new subscriber, assigning it a token and passing it a reference to itself. It does this so that when a third party registers the class with an event channel (as opposed to registering itself with the channel), it will still be aware that the registration has occurred:

Public Overridable Sub Initialize(ByVal Token As _ String, ByVal EventChannel As clsEventChannel) mstrToken = Token mobjEventChannel = EventChannel End Sub

During the registration process, the subscriber is assigned a unique Token, which is used to identify the subscriber in the event channel. The event channel also uses this token internally to index the subscribers. Although the sample application uses the object's Hash Code as the Token, I recommend using another approach to generate a unique identifier (such as generating a GUID) in your own apps.

Use the New List menu option to create three or four instances of frmList, then select an item in one of the lists. Click twice on the item to go into "label edit" mode. Type in a new name and press enter. The form creates an event describing the change to the data and sends it off through the event channel:

Private Sub lvwList_AfterLabelEdit(ByVal sender As _ Object,
ByVal e As _ System.Windows.Forms.LabelEditEventArgs) _ Handles lvwList.AfterLabelEdit Dim objEvent As clsDataEvent If e.Label <> "" Then objEvent = New clsDataEvent() With objEvent .Name = "NameChanged" .Value = e.Label .ExtraData = lvwList.Items(e.Item).Tag .Origin = Me End With MyBase.EventChannel.PublishEvent(objEvent) End If End Sub

Note that the form sending the event identifies itself as the originator; it sets the Origin property of the clsDataEvent class to itself. This prevents the sender from receiving the event that it published, which can shoot off redundant events. After all, the publisher of the event is well aware that the data has changed.

All the subscribers to the data event channel receive the event. In EventApp, every other instance of frmList receives the event and can react to it by changing the text of the appropriate item in the ListView:

Public Overrides Sub EventRaise( _ ByVal NewEvent As _ EventApp.clsEvent) Dim objListItem As ListViewItem Select Case NewEvent.Name Case "NameChanged" For Each objListItem In lvwList.Items If objListItem.Tag = NewEvent.ExtraData Then objListItem.Text = NewEvent.Value End If Next Case Else 'Handle other events End Select End Sub

This type of event system gives you flexibility. You can have any object in an application publish events on a channel while only interested subscribers get notified of them. It also allows you to create multiple event channels that group functionally related event types.

You also can improve the implementation of the Event Channel class. You can create an Event Channel that systematically stacks the events and sends them out asynchronously when a set number is reached, either individually or all together. You could also implement an Event Channel that sends out the events over HTTP through a Web service or a messaging system such as MS Message Queue or IBM MQ Series.

Marc D'Aoust is vice president of research and development for OSTnet OpenSource Technologies Inc., a Montreal, Quebec (Canada)-based company that develops tools to enable software reuse. to reach him by e-mail.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date