Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Mediator Design Pattern

, 4 May 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
Mediator Design Pattern clearly explained with example
You can see this and other great articles on design patterns here.

The Mediator Design Pattern allows you to decouple the direct communication between objects by introducing a middle object, the mediator, that facilitates the communication between the objects. Imagine you have a system where numerous objects communicate with each other by holding the reference to other objects. As the number of object grows and the references to other objects increases the system becomes hard to maintain. The mediator pattern is designed to solve this problem.

The mediator is the communication center for the objects. When an object needs to communicate to another object, it does not call the other object directly. Instead, it calls the mediator object whose main duty is to route the messages to the destination object. It allows the developers not having to manage the links between the objects.

Let's look at the UML of the mediator pattern first, then we will look at some code to see how it works. Below is the UML of the Mediator Design Pattern:

The left side is the mediator, the object that distributes the messages. The right side are the participants. The official UML of the mediator pattern calls the participants as Colleagues, it's just a different terminology.

  • The IMediator interface defines the properties and the methods that all mediators must support:
    • ColleagueList -- This is the list of the registered participants
    • DistributeMessage(IColleague) -- Sends the messages from the sender to all the participants
    • Register(IColleague) -- Register the participant to receive the message from the mediator
  • The ConcreteMediator is the mediator class:
    • DistributeMessage(IColleague) -- Sends the message to the participants. It does not send the message back to the sender.
    • Register(IColleague) -- Register the participant to receive the message from the mediator
  • The IColleague interface defines the methods that all participants must support:
    • SendMessage(IMediator) -- Sends the message to the mediator
    • ReceiveMessage() -- Gets the message from the mediator
  • The ConcreteColleague class are the participants:
    • SendMessage(IMediator) -- Sends the message to the mediator by passing itself to the mediator
    • ReceiveMessage() -- Gets the message from the mediator

A comparison between the mediator pattern and the observer pattern shows some similarities and some clear differences. Both patterns facilitates the communication between objects, and both decouples the link between the sender and the receiver. The main difference is that in the mediator pattern there is the notion of the participants and they communicate with each other using the mediator as a central hub, whereas in the observer pattern there is a clear distinction between the sender and the receiver, and the receiver merely listens to the changes in the sender.

 

Below are the implementation code and the output of the Mediator Design Pattern. You can think of the mediator as a chat room, where each participant can register to different chat rooms and send messages to the chat rooms. Only the participants in the chat room will receive the message:

class Program
{
    static void Main(string[] args)
    {
        //list of participants
        IColleague<string> colleagueA = new ConcreteColleague<string>("ColleagueA");
        IColleague<string> colleagueB = new ConcreteColleague<string>("ColleagueB");
        IColleague<string> colleagueC = new ConcreteColleague<string>("ColleagueC");
        IColleague<string> colleagueD = new ConcreteColleague<string>("ColleagueD");

        //first mediator
        IMediator<string> mediator1 = new ConcreteMediator<string>();
        //participants registers to the mediator
        mediator1.Register(colleagueA);
        mediator1.Register(colleagueB);
        mediator1.Register(colleagueC);
        //participantA sends out a message
        colleagueA.SendMessage(mediator1, "MessageX from ColleagueA");

        //second mediator
        IMediator<string> mediator2 = new ConcreteMediator<string>();
        //participants registers to the mediator
        mediator2.Register(colleagueB);
        mediator2.Register(colleagueD);
        //participantB sends out a message
        colleagueB.SendMessage(mediator2, "MessageY from ColleagueB");
    }
}

public interface IColleague<t>
{
    void SendMessage(IMediator<t> mediator, T message);

    void ReceiveMessage(T message);
}

public class ConcreteColleague<t> : IColleague<t>
{
    private string name;

    public ConcreteColleague(string name)
    {
        this.name = name;
    }

    void IColleague<t>.SendMessage(IMediator<t> mediator, T message)
    {
        mediator.DistributeMessage(this, message);
    }

    void IColleague<t>.ReceiveMessage(T message)
    {
        Console.WriteLine(this.name + " received " + message.ToString());
    }
}


public interface IMediator<t>
{
    List<icolleague><t>> ColleagueList { get; }

    void DistributeMessage(IColleague<t> sender, T message);

    void Register(IColleague<t> colleague);
}


public class ConcreteMediator<t> : IMediator<t>
{
    private List<icolleague><t>> colleagueList = new List<icolleague><t>>();

    List<icolleague><t>> IMediator<t>.ColleagueList
    {
        get { return colleagueList; }
    }

    void IMediator<t>.Register(IColleague<t> colleague)
    {
        colleagueList.Add(colleague);
    }

    void IMediator<t>.DistributeMessage(IColleague<t> sender, T message)
    {
        foreach (IColleague<t> c in colleagueList)
            if (c != sender)    //don't need to send message to sender
                c.ReceiveMessage(message);
    }
}

Liked this article? You can see this and other great articles on design patterns here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

DevLake

United States United States
No Biography provided

Comments and Discussions

 
QuestionVery good article. Nicely explained with a very good example PinmemberMember 996123922-Nov-13 6:58 
QuestionGreat Article. Pinmemberrajeshjj25-Sep-13 16:56 
GeneralMy vote of 5 Pinmemberjohannesnestler9-Aug-13 2:13 
QuestionIf you have trouble compiling this code ... Pinmembersmt529-Aug-13 1:53 
QuestionExcellent article! Pinmembersmt529-Aug-13 1:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.1 | Last Updated 4 May 2011
Article Copyright 2011 by DevLake
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid