The Mediator Design Pattern is a behavioral design pattern that promotes loose coupling between objects by encapsulating how they interact. It centralizes complex communication logic between multiple objects into a mediator object, thus reducing direct dependencies between them. This promotes easier maintenance and scalability of the system.
Related Articles
The Mediator Design Pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object. This pattern is used to centralize complex communications and control between related objects in a system. The Mediator object acts as the communication center for all objects. That means when an object needs to communicate with another object, it does not call the other object directly. Instead, it calls the mediator object, and it is the responsibility of the mediator object to route the message to the destination object.
Components of Mediator Design Pattern
- Mediator: Defines an interface for communication between colleague objects.
- Colleague: It is an abstract class, and Concrete Colleague classes will implement this abstract class.
- ConcreteMediator: Implements the mediator interface, coordinating communication between colleague objects.
- ConcreteColleague: Implements the colleague interface and communicates with other colleagues through the mediator.
Example: Chat Room Application
Let's illustrate the Mediator pattern with a chat room application where users can communicate with each other via messages.
Create Mediator Interface(IChatRoomMediator.cs)using MediatorDesignPattern.Colleague; namespace MediatorDesignPattern.Mediator { ////// Mediator Interface /// public interface IChatRoomMediator { void SendMessage(string message, User user); void RegisterUser(User user); } }
using MediatorDesignPattern.Colleague; namespace MediatorDesignPattern.Mediator { ////// Concrete Mediator /// public class ChatRoom : IChatRoomMediator { private ListUsersList = new List (); //The following method simply registers the user with Mediator public void RegisterUser(User user) { //Adding the user UsersList.Add(user); //Registering the user with Mediator user.Mediator = this; } //The following method is going to send the message in the group i.e. to the group users public void SendMessage(string message, User user) { foreach (User u in UsersList) { //Message should not be received by the user sending it if (u != user) { u.Receive(message); } } } } }
using MediatorDesignPattern.Mediator; namespace MediatorDesignPattern.Colleague { ////// Colleague Abstract Class /// public abstract class User { //This Property holds the name of the user protected string Name; //This Property is going to set and get the Mediator Instance //This Property value is going to be set when we register a user with the Mediator public IChatRoomMediator Mediator { get; set; } //Initializing the name using Constructor public User(string name) { Name = name; } //The following Methods are going to be Implemented by the Concrete Colleague public abstract void Send(string message); public abstract void Receive(string message); } }
namespace MediatorDesignPattern.Colleague { ////// Concrete Colleague /// public class ConcreteUser : User { //Parameterized Constructor is required to set the base class Name Property public ConcreteUser(string Name) : base(Name) { } //Overriding the Receive Method //This method is going to use by the Mediator to send the message to each member of the group public override void Receive(string message) { Console.WriteLine(this.Name + ": Received Message: " + message); } //This method is used to send the message to the Mediator by a user public override void Send(string message) { Console.WriteLine(this.Name + ": Sending Message = " + message + "\n"); Mediator.SendMessage(message, this); } } }
//Create an Instance of Mediator i.e. Creating a Facebook Group using MediatorDesignPattern.Colleague; using MediatorDesignPattern.Mediator; IChatRoomMediator mediator = new ChatRoom(); //Create instances of Colleague i.e. Creating users User Ram = new ConcreteUser("Ram"); User Dave = new ConcreteUser("Dave"); User Smith = new ConcreteUser("Smith"); User Rajesh = new ConcreteUser("Rajesh"); //Registering the users with the Mediator i.e. Facebook Group mediator.RegisterUser(Ram); mediator.RegisterUser(Dave); mediator.RegisterUser(Smith); mediator.RegisterUser(Rajesh); //One of the users Sending one Message in the Group Dave.Send("Hello, everyone!"); Console.WriteLine(); //Another user Sending another Message in the Group Rajesh.Send("Hi, Smith!"); Console.ReadLine();
Outpput
In this example, the ChatRoom acts as the mediator, facilitating communication between users (User). Users send messages through the Send method, and the ChatRoom relays these messages to all other users except the sender. This way, users are decoupled from each other, and the communication logic is centralized in the ChatRoom.
Conclusion
The Mediator Design Pattern is useful when you have a set of objects with complex communication logic. By centralizing this logic in a mediator, it promotes loose coupling and simplifies maintenance and scalability. It's particularly handy in scenarios like chat applications, where multiple entities need to communicate without creating tight dependencies between them.
The full source code is available here:
Happy coding!! 😊