BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 2.0+

Mediator Design Pattern

The mediator pattern is a design pattern that promotes loose coupling of objects by removing the need for classes to communicate with each other directly. Instead, mediator objects are used to encapsulate and centralise the interactions between classes.

What is the Mediator Pattern?

The mediator pattern is a Gang of Four design pattern. This is a behavioural pattern as it defines a manner for controlling communication between classes or entities. The mediator pattern is used to reduce coupling between classes that communicate with each other. Instead of classes communicating directly, and thus requiring knowledge of their implementation, the classes send messages to a mediator object. The mediator object then transmits the messages to the other classes in a manner that they can interpret. The object initiating a message therefore requires no knowledge of the objects that will receive it.

The mediator pattern promotes loose coupling of classes by removing the direct dependencies. It can also simplify communication in general when a program contains a large number of classes that interact. Each class need only know how to pass messages to its mediator, rather than to numerous colleagues. This simplified communication can improve the readability of the code. It can also increase the maintainability, as a class and its mediator may be changed without requiring modifications to other types.

An example of the mediator design pattern could be used when developing an on-line presentation tool that connects a presenter to multiple attendees. When the presenter updates the on-screen slide, the new picture would be sent to all attendees. Attendees may be able to send a question that the presenter will receive and answer. Each of these actions would be sent to a method of the mediator. The mediator would then pass the messages on to the correct recipients. The objects representing the person that initiated the communication would be unaware of the number of other attendees.

Implementing the Mediator Pattern

Mediator Design Pattern UML

The UML class diagram above shows an implementation of the mediator design pattern. The items in the diagram are described below:

  • ColleagueBase. This abstract class is the base class for the colleague object. It defines a single, protected field that holds a reference to a mediator.
  • ConcreteColleague A/B. The concrete colleagues are the classes that communicate with each other via the mediator. Each inherits the mediator field from the ColleagueBase class. The Send and Receive methods in the UML diagram are used to send messages to and receive messages from the mediator.
  • MediatorBase. This abstract class is the base class for the concrete mediator objects. The class defines methods that can be called by colleague objects.
  • ConcreteMediator. The concrete mediators implement the communication methods of the MediatorBase class. They also hold references to the colleagues that they are currently servicing. The SendMessage method in the UML diagram is called by a colleague object when it wished to transmit a message, passing the caller object as a parameter. The mediator then decides which of the colleagues should receive the message and calls their Receive methods.

The following shows the basic code of the mediator design pattern implemented using C#. To simplify the example the code uses C# 3.0 automatically implemented property syntax to define properties. For earlier versions of the language you should use full property declarations with backing variables.

public abstract class ColleagueBase
{
    protected MediatorBase _mediator;

    public ColleagueBase(MediatorBase mediator)
    {
        _mediator = mediator;
    }
}


public class ColleagueA : ColleagueBase
{
    public ColleagueA(MediatorBase mediator) : base(mediator) { }

    public void Send()
    {
        Console.WriteLine("ColleagueA sent message");
        _mediator.SendMessage(this);
    }

    public void Receive()
    {
        Console.WriteLine("ColleagueA received message");
    }
}


public class ColleagueB : ColleagueBase
{
    public ColleagueB(MediatorBase mediator) : base(mediator) { }

    public void Send()
    {
        Console.WriteLine("ColleagueB sent message");
        _mediator.SendMessage(this);
    }

    public void Receive()
    {
        Console.WriteLine("ColleagueB received message");
    }
}


public abstract class MediatorBase
{
    public abstract void SendMessage(ColleagueBase caller);
}


public class ConcreteMediator : MediatorBase
{
    public ColleagueA Colleague1 { get; set; }

    public ColleagueB Colleague2 { get; set; }

    public override void SendMessage(ColleagueBase caller)
    {
        if (caller == Colleague1)
            Colleague2.Receive();
        else
            Colleague1.Receive();
    }
}
30 July 2009