中介者模式是什麼呢?其實很好理解,那就是中介
,中介可能大家都並不陌生,房產中介的電話也接到不少;中介者模式就充當著房產中介的角色,就好比我們要租房子,我們只需要與中介建立聯絡,而房源以及業主不需要我們去建立聯絡。
中介者模式主要是為了解耦多對多的聯絡,沒有中介者之前的模式類似於網狀結構,要對每個物件都建立聯絡,如果需要改動則所有物件都可能需要進行改動,牽一髮而動全身。
下面以商城中採購
、銷售
、庫存
為例子,未使用中介者模式解耦的結構如下:
使用中介者模式後,可以減少物件之間的耦合,都交給了中介者去聯絡,結構變成了這樣:
對比下兩者 UML 類圖:
中介者模式類圖:
非中介者模式類圖:
兩者比較得知,不使用中介者模式,物件耦合嚴重,需要每個建立聯絡。
中介者模式的定義
中介者模式:用一箇中介物件封裝一系列的物件互動,中介者使各物件不需要顯示地相互作用,從而使其鬆耦合,而且可以獨立地改變他們之間的互動。
中介者模式有以下幾部分組成:
抽象中介者
抽象中介者是中介者的抽象類,提供了執行同事物件資訊的抽象方法。
具體中介者
實現了抽象中介者的方法,協調各個同事角色之間的互動關係。
抽象同事類
抽象同事類,儲存中介者物件,提供同事物件互動的抽象方法。
具體同事類
抽象同事類的實現者。如需要與其他同事物件互動時,由中介者物件負責互動。
程式碼實現
上文提及
採購
、銷售
、庫存
例子中介者具體實現程式碼,詳細程式碼請檢視GitHub
不使用中介者模式具體實現程式碼,詳細程式碼請檢視GitHub
下面程式碼實現為通用程式碼:
抽象中介者:
/**
* 抽象中介
*
* Interface AbstractMediator
* @package DesignPatterns\AbstractMediator
*/
abstract class AbstractMediator
{
/**
* 事件方法, 處理多個物件之間的關係
*
* @param string $classAlias 類別名
* @param string $method 方法名
* @param array $args 引數
* @return mixed
*/
abstract public function execute(string $classAlias, string $method, ...$args);
/**
* 設定同事類
*
* @param AbstractColleague $colleague 同事類
* @param string $classAlias 別名
*/
abstract public function setColleague(AbstractColleague $colleague, string $classAlias);
}
具體中介者:
/**
* 具體中介類
*
* Class ConcreteAbstractMediator
* @package DesignPatterns\Mediator
*/
class ConcreteMediator extends AbstractMediator
{
/**
* 事件方法, 處理多個物件之間的關係
*
* @param string $classAlias
* @param string $method 方法名
* @param array $args
* @return mixed|void
*/
public function execute(string $classAlias, string $method, ...$args)
{
return $this->{$classAlias}->{$method}(...$args);
}
}
抽象同事類:
/**
* 抽象同事
*
* Class AbstractColleague
* @package DesignPatterns\AbstractMediator
*/
abstract class AbstractColleague
{
/**
* @var AbstractMediator $mediator
*/
protected $mediator;
/**
* 設定中介者
*
* @param AbstractMediator $mediator 中介者
*/
public function setMediator(AbstractMediator $mediator)
{
$this->mediator = $mediator;
}
}
具體同事類:
/**
* 具體同事類
*
* Class ConcreteColleague
* @package DesignPatterns\Mediator
*/
class ConcreteColleague extends AbstractColleague
{
/**
* do something
*/
public function doSomething()
{
// TODO
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結