Mediator pattern

1. Usage

In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program’s running behavior.

Usually a program is made up of a large number of classes. So the logic and computation is distributed among these classes. However, as more classes are developed in a program, especially during maintenance and/or refactoring, the problem of communication between these classes may become more complex. This makes the program harder to read and maintain. Furthermore, it can become difficult to change the program, since any change may affect code in several other classes.

With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling.

2. UML class diagram

Mediator UML class diagram:
Mediator UML sequence diagram:

3. Pros

  • promotes a loose coupling between the Colleagues – instead of a Many:Many
    publish, it’s a Many:1 (Colleagues to Mediator) followed by a 1:Many (Mediator to Colleagues)
  • promotes reuse – Colleagues aren’t bogged down with relationship
    management code so can be reused in other circumstances
  • centralizes relationship management in the Mediator

4. Cons

  • the Mediator can become very complex and difficult to maintain

5. Source code

// From http://patterns.pl/mediator.html
    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    class Mediator
    {
    public:
      virtual void send(const string& id, const string& message) = 0;
    };
    class Colleague
    {
      Mediator* mediator;
      string id;
    public:
      Colleague(const string& cid) { id = cid; }
      string getId() { return id; }
      void registerMediator(Mediator &m) { mediator = &m; }
      void receive(const string & msg)
      {
        cout << "Message received by " + id + ": " + msg << endl;
      }
      void send(const string & ids, const string & msg) 
      {
        cout << id + " send message to " + ids + " : " + msg << endl;
        mediator->send(ids, msg);
      }
    };
    class ConcreteMediator : public Mediator
    {
      map<string, Colleague*> colleagues;
      bool isRegistered(string id)
      {
        return colleagues.find(id) != colleagues.end();
      }
    public:
      void registerColleague(Colleague& c)
      {
        if (!isRegistered(c.getId()))
        {
          c.registerMediator(*this);
          colleagues[c.getId()] = &c;
        }
      }
      void send(const string& id, const string& message) override
      {
        if (isRegistered(id))
        {
          Colleague *c = colleagues[id];
          c->receive(message);
        }
      }
    };
    int main()
    {
      Colleague peter("Peter");
      Colleague paul("Paul");
      Colleague kate("Kate");
      ConcreteMediator mediator;
      mediator.registerColleague(peter);
      mediator.registerColleague(paul);
      mediator.registerColleague(kate);
      peter.send("Paul", "wu"); //whats up?
      paul.send("Peter", "aas"); //alive and smiling
      kate.send("Paul", "diku"); //do I know you?
      paul.send("Kate", "ydkm"); //you don't know me
      return 0;
    }

Leave a Reply

Your email address will not be published. Required fields are marked *