Design Patterns: Mediator

The Mediator Pattern allows objects to communicate with each other through a common instance of a mediator class. It promotes loose coupling and prevents objects from referring to each other directly.

Through a common instance of a mediator the classes subscribing to it can communicate by sending messages to this instance and it will notify the other subscribed instances.

Figure 1: Subscribed instances
  1. public abstract class Mediator  
  2. {  
  3.     public IList<AirCraft> AirCrafts { getprivate set; }  
  4.   
  5.     public Mediator()  
  6.     {  
  7.         AirCrafts = new List<AirCraft>();  
  8.     }  
  9.   
  10.     public abstract void Send(AirCraft sender, string message);  
  11. }  
  12.   
  13. public class CommunicationTower : Mediator  
  14. {  
  15.     public override void Send(AirCraft sender, string message)  
  16.     {  
  17.         foreach (var airCraft in AirCrafts)  
  18.         {  
  19.             if (airCraft != sender)  
  20.             {  
  21.                 airCraft.Receive(sender, message);  
  22.             }  
  23.         }  
  24.     }  
  25. }  
  26.   
  27. public abstract class AirCraftCollegue  
  28. {  
  29.     public abstract void Receive(AirCraft sender, string message);  
  30. }  
  31.   
  32. public class AirCraft : AirCraftCollegue  
  33. {  
  34.     public AirCraft(CommunicationTower mediator)  
  35.     {  
  36.         mediator.AirCrafts.Add(this);  
  37.     }  
  38.   
  39.     public string Name { getset; }  
  40.   
  41.     public override void Receive(AirCraft sender, string message)  
  42.     {  
  43.         Console.WriteLine("{0}: Received message '{1}' from '{2}'", Name, message, sender.Name);  
  44.     }  
  45. }  

In the preceding example the mediator tells the subscribed aircrafts (except the sender) that one of them is saying something. 

Example usage:
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         var towerMediator = new CommunicationTower();  
  6.    
  7.         var airCraft1 = new AirCraft(towerMediator) { Name = "Unit #1" };  
  8.         var airCraft2 = new AirCraft(towerMediator) { Name = "Unit #2" };  
  9.         var airCraft3 = new AirCraft(towerMediator) { Name = "Unit #3" };  
  10.         var airCraft4 = new AirCraft(towerMediator) { Name = "Unit #4" };  
  11.         var airCraft5 = new AirCraft(towerMediator) { Name = "Unit #5" };  
  12.    
  13.         towerMediator.Send(airCraft1, "Let's go up!");  
  14.     }  
  15. }  

Output:

  1. Unit #2: Received message 'Let's go up!' from 'Unit #1'  
  2. Unit #3: Received message 'Let's go up!' from 'Unit #1'  
  3. Unit #4: Received message 'Let's go up!' from 'Unit #1'  
  4. Unit #5: Received message 'Let's go up!' from 'Unit #1'  

One actual example is the EventAggreagator that we see in WPF. It allows the communication between view models that don't know about the existence of each other.