The Mediator design pattern defines an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
IChatroom
)
Chatroom
)
Participant
)
This structural code demonstrates the Mediator pattern facilitating loosely coupled communication between different objects and object types. The mediator is a central hub through which all interaction must take place.
using System;
namespace Mediator.Structural
{
/// <summary>
/// Mediator Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
ConcreteMediator m = new ConcreteMediator();
ConcreteColleague1 c1 = new ConcreteColleague1(m);
ConcreteColleague2 c2 = new ConcreteColleague2(m);
m.Colleague1 = c1;
m.Colleague2 = c2;
c1.Send("How are you?");
c2.Send("Fine, thanks");
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Mediator' abstract class
/// </summary>
public abstract class Mediator
{
public abstract void Send(string message,
Colleague colleague);
}
/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
public class ConcreteMediator : Mediator
{
ConcreteColleague1 colleague1;
ConcreteColleague2 colleague2;
public ConcreteColleague1 Colleague1
{
set { colleague1 = value; }
}
public ConcreteColleague2 Colleague2
{
set { colleague2 = value; }
}
public override void Send(string message, Colleague colleague)
{
if (colleague == colleague1)
{
colleague2.Notify(message);
}
else
{
colleague1.Notify(message);
}
}
}
/// <summary>
/// The 'Colleague' abstract class
/// </summary>
public abstract class Colleague
{
protected Mediator mediator;
// Constructor
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
}
/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
public class ConcreteColleague1 : Colleague
{
// Constructor
public ConcreteColleague1(Mediator mediator)
: base(mediator)
{
}
public void Send(string message)
{
mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine("Colleague1 gets message: "
+ message);
}
}
/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
public class ConcreteColleague2 : Colleague
{
// Constructor
public ConcreteColleague2(Mediator mediator)
: base(mediator)
{
}
public void Send(string message)
{
mediator.Send(message, this);
}
public void Notify(string message)
{
Console.WriteLine("Colleague2 gets message: "
+ message);
}
}
}
This real-world code demonstrates the Mediator pattern facilitating loosely coupled communication between different Participants registering with a Chatroom. The Chatroom is the central hub through which all communication takes place. At this point only one-to-one communication is implemented in the Chatroom, but would be trivial to change to one-to-many.
using System;
using System.Collections.Generic;
namespace Mediator.RealWorld
{
/// <summary>
/// Mediator Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Create chatroom
Chatroom chatroom = new Chatroom();
// Create participants and register them
Participant George = new Beatle("George");
Participant Paul = new Beatle("Paul");
Participant Ringo = new Beatle("Ringo");
Participant John = new Beatle("John");
Participant Yoko = new NonBeatle("Yoko");
chatroom.Register(George);
chatroom.Register(Paul);
chatroom.Register(Ringo);
chatroom.Register(John);
chatroom.Register(Yoko);
// Chatting participants
Yoko.Send("John", "Hi John!");
Paul.Send("Ringo", "All you need is love");
Ringo.Send("George", "My sweet Lord");
Paul.Send("John", "Can't buy me love");
John.Send("Yoko", "My sweet love");
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Mediator' abstract class
/// </summary>
public abstract class AbstractChatroom
{
public abstract void Register(Participant participant);
public abstract void Send(
string from, string to, string message);
}
/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
public class Chatroom : AbstractChatroom
{
private Dictionary<string, Participant> participants = new Dictionary<string, Participant>();
public override void Register(Participant participant)
{
if (!participants.ContainsValue(participant))
{
participants[participant.Name] = participant;
}
participant.Chatroom = this;
}
public override void Send(string from, string to, string message)
{
Participant participant = participants[to];
if (participant != null)
{
participant.Receive(from, message);
}
}
}
/// <summary>
/// The 'AbstractColleague' class
/// </summary>
public class Participant
{
Chatroom chatroom;
string name;
// Constructor
public Participant(string name)
{
this.name = name;
}
// Gets participant name
public string Name
{
get { return name; }
}
// Gets chatroom
public Chatroom Chatroom
{
set { chatroom = value; }
get { return chatroom; }
}
// Sends message to given participant
public void Send(string to, string message)
{
chatroom.Send(name, to, message);
}
// Receives message from given participant
public virtual void Receive(
string from, string message)
{
Console.WriteLine("{0} to {1}: '{2}'",
from, Name, message);
}
}
/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
public class Beatle : Participant
{
// Constructor
public Beatle(string name)
: base(name)
{
}
public override void Receive(string from, string message)
{
Console.Write("To a Beatle: ");
base.Receive(from, message);
}
}
/// <summary>
/// A 'ConcreteColleague' class
/// </summary>
public class NonBeatle : Participant
{
// Constructor
public NonBeatle(string name)
: base(name)
{
}
public override void Receive(string from, string message)
{
Console.Write("To a non-Beatle: ");
base.Receive(from, message);
}
}
}
The .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features,
such as, generics, reflection, LINQ, lambda functions, etc.
You can find an example on our Singleton pattern page.
All other patterns (and much more) are available in our Dofactory .NET product.
Not only does Dofactory .NET cover the Gang of Four and Enterprise patterns, it also includes
pattern architectures, low-code, and RAD (Rapid Application Development) techniques.
Accelerate development to where you can write
entire solutions in just 33 days!.
This unique package will change your developer lifestyle.
Here's what is included: