Design Pattern: Mediator Pattern in PHP

Mediator pattern encapsulates the logic of communication between a bunch of defined objects. A mediator object is used for that. The mediator works as a middleman between the set of objects.

This prevents the objects(colleagues) from communicating directly with each other, and ensures loose coupling.

Mediator Pattern communication Between the Mediator and Colleagues

This article demonstrates Mediator pattern implementations in PHP. Check the following examples and implementation details.

Implementation

Use the following steps-

  • Define a mediator interface. Declare method(s) for communication between objects. Accept a colleague type of object.
  • Define mediator class and implement the mediator interface.
  • Define abstract colleague class. Accept a mediator object in constructor and set that to a protected property. Declare abstract methods for sending and receiving messages.
  • Define colleague classes, and extend the main colleague class. Define methods for sending and receiving messages. While sending message, accept a colleague object, and call the method from the colleague to send message to the colleague.

Examples

Let’s take a look at a few examples of Mediator pattern in PHP-

Example #1: General Mediator

Let’s consider a general example.

Mediator Interface

  • Create file “IMediator.php”.
  • Define interface “IMediator”.
  • Declare method “sendMessage” for sending message to different colleagues. Accpet a param of type “Colleague” and another param for the message string.
<?php
// IMediator.php

namespace BigBoxCodeDesignPatternMediatorGeneral;

interface IMediator {
    function sendMessage(Colleague $colleague, string $msg): void;
}

Mediator Class

  • Create file “Mediator.php”.
  • Define class “Mediator”.
  • Implement interface “IMediator” for the class.
  • In the method definition of “sendMessage” – call the receive message of the passed “$receiver” param of type “Colleague”.
<?php
// Mediator.php

namespace BigBoxCodeDesignPatternMediatorGeneral;

class Mediator implements IMediator {
    public function sendMessage(Colleague $receiver, string $msg): void {
        $receiver->receiveMessage($msg);
    }
}

Colleague Abstract Class

  • Create file “Colleague.php”.
  • Define abstract class “Colleague”.
  • Define a protected property “$mediator” of type “Mediator”.
  • Declare abstract method “sendMessage” which accepts a param “$colleague” of type “Colleague”, and another param of type string named “$message”.
  • Declare method “receiveMessage” which accepts a param “$message” of type string.
<?php
// Colleague.php

namespace BigBoxCodeDesignPatternMediatorGeneral;

abstract class Colleague {
    public function __construct(protected Mediator $mediator) {
    }

    abstract function sendMessage(Colleague $colleague, string $message): void;
    abstract function receiveMessage(string $message): void;
}

Colleague1 Class [Colleague Class]

  • Create file “Colleague1.php”.
  • Define class “Colleague1” and extend the abstract class “Colleague”.
  • In the “sendMessage” method definition call the “sendMethod” from the mediator.
  • In the “receiveMessage” method definition implement the steps that need to be executed after receiving a message.
<?php
// Colleague1.php

namespace BigBoxCodeDesignPatternMediatorGeneral;


class Colleague1 extends Colleague {
    public function __construct(Mediator $mediator) {
        parent::__construct($mediator);
    }

    public function sendMessage(Colleague $colleague, string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        $this->mediator->sendMessage($colleague, $msg);
    }

    public function receiveMessage(string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        echo "Message received in Colleague1: " . $msg . "n";
    }
}

Colleague2 Class [Colleague Class]

  • Create file “Colleague2.php”.
  • Define class “Colleague2” and extend “Colleague” class.
  • Define the implementation for the abstract methods “sendMessage” and “receiveMessage”.
<?php
// Colleague2.php

namespace BigBoxCodeDesignPatternMediatorGeneral;

class Colleague2 extends Colleague {
    public function __construct(Mediator $mediator) {
        parent::__construct($mediator);
    }

    public function sendMessage(Colleague $colleague, string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        $this->mediator->sendMessage($colleague, $msg);
    }

    public function receiveMessage(string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        echo "Message received in Colleague2: " . $msg . "n";
    }
}

Colleague3 Class [Colleague Class]

  • Create file “Colleague3.php”.
  • Define class “Colleague3”. Extend “Colleague” for the class, and define abstract methods “sendMessage” and “receiveMessage”.
<?php
// Colleague3.php

namespace BigBoxCodeDesignPatternMediatorGeneral;

class Colleague3 extends Colleague {
    public function __construct(Mediator $mediator) {
        parent::__construct($mediator);
    }

    public function sendMessage(Colleague $colleague, string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        $this->mediator->sendMessage($colleague, $msg);
    }

    public function receiveMessage(string $msg): void {
        // Here can be some additional processing 
        // specific to this colleague for message
        // prcessing/parsing/altering/formatting
        echo "Message received in Colleague3: " . $msg . "n";
    }
}

Demo

In the client create a mediator object. Create colleague objects, and pass the mediator to the colleague.

Then we can call the “sendMessage” method of a colleague to send the message. We need to pass the receiver colleague object.

<?php
// demo.php

require __DIR__ . '/../../vendor/autoload.php';

use BigBoxCodeDesignPatternMediatorGeneralColleague1;
use BigBoxCodeDesignPatternMediatorGeneralColleague2;
use BigBoxCodeDesignPatternMediatorGeneralColleague3;
use BigBoxCodeDesignPatternMediatorGeneralMediator;


$mediator = new Mediator();

// Set mediator and create colleague objects
$colleague1 = new Colleague1($mediator);
$colleague2 = new Colleague2($mediator);
$colleague3 = new Colleague3($mediator);

// Send message from colleague 1 to 2
$colleague1->sendMessage($colleague2, "message from colleague1");

// Send message from colleague 1 to 3
$colleague1->sendMessage($colleague3, "message from colleague1");

// Send message from colleague 2 to 3
$colleague2->sendMessage($colleague3, "message from colleague2");

// Send message from Colleague 3 to 1
$colleague3->sendMessage($colleague1, "message from colleague3");

Output

Output will be as below-

Message received in Colleague2: message from colleague1
Message received in Colleague3: message from colleague1

Message received in Colleague3: message from colleague2

Message received in Colleague1: message from colleague3

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check Mediator pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.