1.5. Mediator¶
1.5.1. Intent¶
According to the Gang of Four, the Mediator is a way to “define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently” (Design Patterns: Elements of Reusable Object-Oriented Software, 2013, p. 273).
1.5.2. When to use it?¶
Mediator pattern should be used when a large set of objects has too many direct relationships and you want to reduce that complexity. It’s a way to balance distribution of behavior among objects with loose coupling.
1.5.3. Diagram¶
Created using PhpStorm and yFiles.
1.5.4. Implementation¶
AbstractColleague.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php
namespace Phpatterns\Behavioral\Mediator;
abstract class AbstractColleague
{
/** @var TaxiCallCenterInterface */
private $mediator;
/**
* @param TaxiCallCenterInterface $mediator
*/
public function __construct(TaxiCallCenterInterface $mediator)
{
$this->mediator = $mediator;
}
/**
* @return TaxiCallCenterInterface
*/
protected function getMediator()
{
return $this->mediator;
}
}
|
Customer.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php
namespace Phpatterns\Behavioral\Mediator\Colleague;
use Phpatterns\Behavioral\Mediator;
class Customer extends Mediator\AbstractColleague
{
/**
* @param Mediator\TaxiCallCenterInterface $mediator
*/
public function __construct(Mediator\TaxiCallCenterInterface $mediator)
{
parent::__construct($mediator);
}
/**
* @return bool
*/
public function requestRace()
{
return $this->getMediator()->requestRace();
}
/**
* @return bool
*/
public function confirm()
{
return true;
}
}
|
Taxi.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php
namespace Phpatterns\Behavioral\Mediator\Colleague;
use Phpatterns\Behavioral\Mediator;
class Taxi extends Mediator\AbstractColleague
{
/** @var bool */
private $available;
/**
* @param Mediator\TaxiCallCenterInterface $mediator
*/
public function __construct(Mediator\TaxiCallCenterInterface $mediator)
{
parent::__construct($mediator);
$this->available = true;
}
/**
* @param bool $available
*/
public function setAvailable($available)
{
$this->available = $available;
}
/**
* @return bool
*/
public function request()
{
if ($this->available) {
$this->setAvailable(false);
return $this->getMediator()->acceptRace();
}
return false;
}
}
|
TaxiCallCenterInterface.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
namespace Phpatterns\Behavioral\Mediator;
/**
* Interface TaxiCallCenterInterface
* Classes implementing that interface will be used as Mediators
*/
interface TaxiCallCenterInterface
{
/**
* @return bool
*/
public function requestRace();
/**
* @return bool
*/
public function acceptRace();
}
|
YellowTaxiCallCenter.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | <?php
namespace Phpatterns\Behavioral\Mediator\TaxiCallCenter;
use Phpatterns\Behavioral\Mediator;
class YellowTaxiCallCenter implements Mediator\TaxiCallCenterInterface
{
/** @var Mediator\AbstractColleague */
private $taxi;
/** @var Mediator\AbstractColleague */
private $customer;
/**
* @param Mediator\AbstractColleague $taxi
* @return $this
*/
public function setTaxi($taxi)
{
$this->taxi = $taxi;
return $this;
}
/**
* @param Mediator\AbstractColleague $customer
* @return $this
*/
public function setCustomer($customer)
{
$this->customer = $customer;
return $this;
}
/**
* @return bool
*/
public function requestRace()
{
return $this->taxi->request();
}
/**
* @return bool
*/
public function acceptRace()
{
return $this->customer->confirm();
}
}
|
1.5.5. Tests¶
MediatorTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php
namespace Test\Phpatterns\Behavioral\Mediator;
use Phpatterns\Behavioral\Mediator;
use Phpatterns\Behavioral\Mediator\TaxiCallCenter;
use Phpatterns\Behavioral\Mediator\Colleague;
class MediatorTest extends \PHPUnit_Framework_TestCase
{
/** @var Colleague\Customer */
private $customer;
protected function setUp()
{
$mediator = new TaxiCallCenter\YellowTaxiCallCenter();
$this->customer = new Colleague\Customer($mediator);
$taxi = new Colleague\Taxi($mediator);
$mediator
->setCustomer($this->customer)
->setTaxi($taxi);
}
public function testTaxiRequest()
{
$this->assertTrue($this->customer->requestRace());
}
}
|