Object Oriented Programming Patterns for Geeks
The Mediator Pattern
namespace ooppatterns
{
using System;
using System.Collections.Generic;
internal class Program
{
private static void Main(string[] args)
{
// Create messenger
Messager messenger = new Messager();
MessageSink AppA_Client1 = new ApplicationA("Client A 1");
MessageSink AppA_Client2 = new ApplicationA("Client A 2");
MessageSink AppA_Client3 = new ApplicationA("Client A 3");
// Application A registers clients...
messenger.Register(AppA_Client1);
messenger.Register(AppA_Client2);
messenger.Register(AppA_Client3);
MessageSink AppB_Client1 = new ApplicationB("Client B 1");
MessageSink AppB_Client2 = new ApplicationB("Client B 2");
// Application B registers clients...
messenger.Register(AppB_Client1);
messenger.Register(AppB_Client2);
MessageSink AppC_Client1 = new ApplicationC("Client C 1");
// Application C registers clients...
messenger.Register(AppC_Client1);
// Direct access to the mediator:
messenger.Send(AppA_Client1, AppC_Client1, "Hello");
messenger.Send(AppC_Client1, AppB_Client2, "Hello");
// Example of clients sending messages...
AppB_Client2.Send("Client A 3", "Hello");
AppA_Client3.Send("Client B 1", "Hello");
// However they can also send to themselves, so
// you should try to prevent this...
AppC_Client1.Send("Client C 1", "Hello");
messenger.Send(AppC_Client1, AppC_Client1, "Hello");
Console.ReadLine();
}
}
interface IMediator
{
void Register(MessageSink messageSink);
void Send(string from, string to, string message);
}
// This could represent a server process accessible by remoting.
class Messager : IMediator
{
private Dictionary<string, MessageSink> _participants = new Dictionary<string, MessageSink>();
public void Register(MessageSink messageSink)
{
if( !this._participants.ContainsKey(messageSink.Name) )
this._participants.Add(messageSink.Name, messageSink);
messageSink.Messager = this;
}
public void Send(MessageSink from, MessageSink to, string message)
{
this.Send(from.Name, to.Name, message);
}
public void Send(string from, string to, string message)
{
if( this._participants.ContainsKey(to) )
this._participants[to].Receive(from, message);
}
}
// All messages are sent and recieved through here
class MessageSink
{
private Messager _messager;
private string _name;
// Constructor
public MessageSink(string name)
{
this._name = name;
}
// Properties
public string Name
{
get { return this._name; }
}
public Messager Messager
{
set { this._messager = value; }
get { return this._messager; }
}
public void Send(string to, string message)
{
this._messager.Send(this._name, to, message);
}
public virtual void Receive(string from, string message)
{
Console.WriteLine("{0} to {1}: '{2}'", from, _name, message);
}
}
// Client applications that wish to communicate with each other
class ApplicationA : MessageSink
{
// Constructor
public ApplicationA(string name)
: base(name) {}
public override void Receive(string from, string message)
{
Console.Write("To ApplicationA: ");
base.Receive(from, message);
}
}
class ApplicationB : MessageSink
{
// Constructor
public ApplicationB(string name)
: base(name) {}
public override void Receive(string from, string message)
{
Console.Write("To ApplicationB: ");
base.Receive(from, message);
}
}
class ApplicationC : MessageSink
{
// Constructor
public ApplicationC(string name)
: base(name) {}
public override void Receive(string from, string message)
{
Console.Write("To ApplicationC: ");
base.Receive(from, message);
}
}
}