This week, I present to you not much used, but quite useful Mediator pattern.

Mediator pattern provides a unified interface to set of interfaces in a subsystem.

Or, to simplify… Mediator pattern is mediator for communication between several classes.

Example

Now, the easiest way to explain this pattern is via example. Example itself is borrowed from dofactory page, but modified to fit LotusScript. It is about a simple support chat room. This chat room has several users of two types: admins and customers. I will call them participants. These participants can communicate amongst each other, presuming, they know user ids.

First, we need a chatroom template class, as we might end up with more than one chat room. Chat room will need to register participants and to be able to deliver messages to them.

Class CChatroomTemplate
   Sub Register (participant As CParticipant)
   End Sub

   Sub Send (strFrom As String, strTo As String, strMsg As String)
   End Sub
End Class

As participants need instance of chatroom class and chatroom needs list of participant class instances, we need to create chatroom and participant class frameworks and only then put code into it. Participants need to be able to send and receive messages. Finished classes are displayed below.

Class CSupportChat As CChatroomTemplate
   m_LMembers List As CParticipant

   Sub Register(participant As CParticipant)
      If (Not Iselement (m_LMembers (participant.UserId))) Then
         Set m_LMembers (participant.UserId) = participant
      End If
      Set participant.Chatroom = Me
   End Sub

   Sub Send (strFrom As String, strTo As String, strMsg As String)
      Dim participant As CParticipant

      If (Not Iselement (m_LMembers (strTo))) Then Exit Sub
      Set participant = m_LMembers (strTo)
      Call participant.Receive (strFrom, strMsg)
   End Sub
End Class

Class CParticipant
   m_chatroom As CSupportChat
   m_strUserId As String

   Property Set Chatroom As CSupportChat
      Set m_chatroom = Chatroom
   End Property

   Property Get UserId As String
      UserId = m_strUserId
   End Property

   Property Set UserId As String
      m_strUserId = UserId
   End Property

   Sub new (strUserId As String)
      m_strUserId = strUserId
   End Sub

   Sub Send (strTo As String, strMsg As String)
      Call m_chatroom.Send (m_strUserId, strTo, strMsg)
   End Sub

   Sub Receive (strFrom As String, strMsg As String)
      Messagebox strFrom & " to " & m_strUserId & ": " & strMsg
   End Sub
End Class

Now that base classes are set, it is time to create real participant classes. In our case, we need one for admins and one for regular users.

Class CAdmin As CParticipant
   Sub new (strUserId As String)
   End Sub

   Sub Receive (strFrom As String, strMsg As String)
      Messagebox "Admin message"
      Call CParticipant..Receive (strFrom, strMsg)
   End Sub
End Class

Class CUser As CParticipant
   Sub new (strUserId As String)
   End Sub

   Sub Receive (strFrom As String, strMsg As String)
      Messagebox "User message"
      Call CParticipant..Receive (strFrom, strMsg)
   End Sub
End Class

Testing the code

For testing purposes, I put it all in agent, created four users (of which one is admin) and sent 3 messages to admin and admin responded to first one. The code is below.

Sub Initialize
   Dim chatroom As CSupportChat
   Dim user1 As CParticipant
   Dim user2 As CParticipant
   Dim user3 As CParticipant
   Dim user4 As CParticipant

   Set chatroom = New CSupportChat()
   Set user1 = New CUser ("User 1")
   Set user2 = New CUser ("User 2")
   Set user3 = New CUser ("User 3")
   Set user4 = New CAdmin ("Admin 1")

   Call chatroom.Register (user1)
   Call chatroom.Register (user2)
   Call chatroom.Register (user3)
   Call chatroom.Register (user4)

   Call user1.Send ("Admin 1", "Help?")
   Call user4.Send ("User 1", "What's wrong?")
   Call user2.Send ("Admin 1", "My server just crashed!!!")
   Call user3.Send ("Admin 1", "Network died!")
End Sub