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 { get; private set; }
  4. public Mediator()
  5. {
  6. AirCrafts = new List<AirCraft>();
  7. }
  8. public abstract void Send(AirCraft sender, string message);
  9. }
  10. public class CommunicationTower : Mediator
  11. {
  12. public override void Send(AirCraft sender, string message)
  13. {
  14. foreach (var airCraft in AirCrafts)
  15. {
  16. if (airCraft != sender)
  17. {
  18. airCraft.Receive(sender, message);
  19. }
  20. }
  21. }
  22. }
  23. public abstract class AirCraftCollegue
  24. {
  25. public abstract void Receive(AirCraft sender, string message);
  26. }
  27. public class AirCraft : AirCraftCollegue
  28. {
  29. public AirCraft(CommunicationTower mediator)
  30. {
  31. mediator.AirCrafts.Add(this);
  32. }
  33. public string Name { get; set; }
  34. public override void Receive(AirCraft sender, string message)
  35. {
  36. Console.WriteLine("{0}: Received message '{1}' from '{2}'", Name, message, sender.Name);
  37. }
  38. }

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. var airCraft1 = new AirCraft(towerMediator) { Name = "Unit #1" };
  7. var airCraft2 = new AirCraft(towerMediator) { Name = "Unit #2" };
  8. var airCraft3 = new AirCraft(towerMediator) { Name = "Unit #3" };
  9. var airCraft4 = new AirCraft(towerMediator) { Name = "Unit #4" };
  10. var airCraft5 = new AirCraft(towerMediator) { Name = "Unit #5" };
  11. towerMediator.Send(airCraft1, "Let's go up!");
  12. }
  13. }

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.