The Mediator pattern is intended to define an object that encapsulates how a set of objects interacts. Object do not communicate directly with eachother, but through a mediator. This reduces the dependencies between communicating objects.
The client instantiates the communicating objects, so called colleagues, and a mediator through which they are communicating.
|
1 2 3 4 5 6 7 8 9 10 |
Colleague c1 = new ConcreteColleague1(m); Colleague c2 = new ConcreteColleague2(m); Mediator m = new ConcreteMediator(); m.AddColleague(c1); m.AddColleague(c2); c1.Send(c2, "Hello, c2. Are you there?"); c2.Send(c1, "No, goodbye!"); |
The abstract class Colleague contains a Mediator, which is injected at instantiation. In this example, it has two methods for communication. One for sending a message, the other for receiving a message.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
abstract class Colleague { protected Mediator mediator; public Colleague(Mediator mediator) { this.mediator = mediator; } abstract public void Send(Colleague to, string message); abstract public void Received(Colleague from, string message); } |
The abstract class Mediator contains an internal store for colleages and a method for adding colleagues. It also contains an abstract method for sending a message to the preferred colleague.
|
1 2 3 4 5 6 7 8 9 10 11 |
abstract class Mediator { protected List colleagues = new List(); public void AddColleague(Colleague colleague) { colleagues.Add(colleague); } public abstract void Send(Colleague colleague, string message); } |
The concrete class implements the abstract method. In this case, it forwards the message to the selected colleague.
|
1 2 3 4 5 6 7 |
class ConcreteMediator : Mediator { public override void Send(Colleague to, string message) { to.Received(to,message); } } |
Finally, the selected concrete colleague receives the message. I only show the concrete class ConcreteColleague1, since ConcreteColleague2 is almost identical to this one. So if you want to try this code, I suggest you do a search and replace on ConcreteColleague1.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class ConcreteColleague1 : Colleague { public ConcreteColleague1(Mediator mediator) : base(mediator) { } override public void Send(Colleague to, string message) { Console.WriteLine("Sending message (ConcreteColleague1)-----------------------------"); Console.WriteLine("To : " + to.GetType().Name); Console.WriteLine("Message: " + message); Console.WriteLine(); mediator.Send(to,message); } override public void Received(Colleague from, string message) { Console.WriteLine("Receiving message (ConcreteColleague1)---------------------------"); Console.WriteLine("From : " + from.GetType().Name); Console.WriteLine("Message: " + message); Console.WriteLine(); } } |
This post is part of a series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern by looking at a minimalistic example to reveal its structure and then look at more concrete and useful real-world C# code that implements the pattern.
Comments