上回說道,我們在外打工的經常會和一類人有很深的接觸,那就是房產中介,大學畢業后馬上就能在喜歡的城市買到房子的X二代不在我們的考慮范圍內哈,既然需要長期的租房,那么因為作業或者生活的變動,不可避免的一兩年或者三五年就要和房產中介打一次交道,有的時候,我們租房并不一定會知道房主的資訊,房主也不用知道我們的資訊,全部都由中介來進行處理,在這里,中介就成為了我們溝通的橋梁,這種情況其實就像是房主出國了或者在外地有事兒而將房子完全的托管到了中介手中,類似于這種情況,在代碼世界中,就是中介者模式的典型應用,
Gof類圖及解釋
GoF定義:用一個中介物件來封裝一系列的物件互動, 中介者使各物件不需要顯式地相互參考,從而使其耦合松散,而且可以獨立地改變它們之間的互動
GoF類圖

代碼實作
abstract class Mediator
{
abstract public function Send(String $message, Colleague $colleague);
}
class ConcreteMediator extends Mediator
{
public $colleague1;
public $colleague2;
public function Send(String $message, Colleague $colleague)
{
if ($colleague == $this->colleague1) {
$this->colleague2->Notify($message);
} else {
$this->colleague1->Notify($message);
}
}
}
抽象出來的中介者和具體的實作,在這里,我們假定有固定的兩個同事類,讓他們互相對話,所以進入的同事是1的時候,就去呼叫2的Notify方法,相當于是讓2接收到了1發來的訊息
abstract class Colleague
{
protected $mediator;
public function __construct(Mediator $mediator)
{
$this->mediator = $mediator;
}
}
class ConcreteColleague1 extends Colleague
{
public function Send(String $message)
{
$this->mediator->Send($message, $this);
}
public function Notify(String $message)
{
echo "同事1得到資訊:" . $message, PHP_EOL;
}
}
class ConcreteColleague2 extends Colleague
{
public function Send(String $message)
{
$this->mediator->Send($message, $this);
}
public function Notify(String $message)
{
echo "同事2得到資訊:" . $message;
}
}
同事類及具體的實作,這里我們要確認的一點就是,每一個同事類,只認識中介者,并不認識另外的同事類,這就是中介者的特點,雙方不用認識,
$m = new ConcreteMediator();
$c1 = new ConcreteColleague1($m);
$c2 = new ConcreteColleague2($m);
$m->colleague1 = $c1;
$m->colleague2 = $c2;
$c1->Send("吃過飯了嗎?");
$c2->Send("沒有呢,你打算請客?");
客戶端的呼叫就比較很簡單啦!
- 是不是感覺這個模式很適合做一些通訊類的產品?沒錯,聊天社交、sns、直播之類的都很合適,因為這個模式就是能讓用戶與用戶之間解耦,不需要讓一個用戶去維護所有有關聯的用戶物件
- 因為不需要用戶去維護關系,所以也就順便解決了關系之間的多對多維護的問題,同時,也不需要去修改用戶類來進行關系的變更,保持了用戶類的良好封裝
- 但是,中介者集中維護可能導致這個類過于復雜和龐大
- 所以,模式不是萬能的,一定要弄清楚業務場景進行取舍地使用
- 中介者適用于一組物件以定義良好但是復雜的方式進行通信的場合,以及想定制一個分布在多個類中的行為,而又不想生成太多子類的場合
作為一名企業家,深知專案管理的重要性,而專案經理,在很多場合下就是一名中介者的角色,從組織角度看,一個專案的開始和結束,作為老板的我并不需要關心是由誰來具體編碼實作,我要溝通的人只是專案經理,同理,其他輔助部門包括財務、人事、行政等,他們也不關心誰來寫代碼,而只需要和專案經理交流了解專案的情況以及需要配合的內容,在專案團隊中,寫代碼的人呢?也不需要知道誰來給他發工資或者考勤問題出在哪里,這一切也交給專案經理解決就好了,所以說,專案經理負責制的專案開發,就是中介者模式的典型應用,我們的手機廠之所以發展的如此之快,也多虧了這些專案經理們,晚上請他們吃大餐去咯~~~
完整代碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/15.mediator/source/mediator.php
實體
這回我們不發短信了,實作一個聊天室吧,一個簡單的在線聊天室,需求就是讓進入聊天室的用戶都可以在線聊天,讓我們來看看使用中介者模式來如何實作這個聊天室吧!
聊天室類圖

完整原始碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/15.mediator/source/mediator-webchat.php
<?php
abstract class Mediator
{
abstract public function Send($message, $user);
}
class ChatMediator extends Mediator
{
public $users = [];
public function Attach($user)
{
if (!in_array($user, $this->users)) {
$this->users[] = $user;
}
}
public function Detach($user)
{
$position = 0;
foreach ($this->users as $u) {
if ($u == $user) {
unset($this->users[$position]);
}
$position++;
}
}
public function Send($message, $user)
{
foreach ($this->users as $u) {
if ($u == $user) {
continue;
}
$u->Notify($message);
}
}
}
abstract class User
{
public $mediator;
public $name;
public function __construct($mediator, $name)
{
$this->mediator = $mediator;
$this->name = $name;
}
}
class ChatUser extends User
{
public function Send($message)
{
$this->mediator->Send($message . '(' . $this->name . '發送)', $this);
}
public function Notify($message)
{
echo $this->name . '收到訊息:' . $message, PHP_EOL;
}
}
$m = new ChatMediator();
$u1 = new ChatUser($m, '用戶1');
$u2 = new ChatUser($m, '用戶2');
$u3 = new ChatUser($m, '用戶3');
$m->Attach($u1);
$m->Attach($u3);
$m->Attach($u2);
$u1->Send('Hello, 大家好呀!'); // 用戶2、用戶3收到訊息
$u2->Send('你好呀!'); // 用戶1、用戶3收到訊息
$m->Detach($u2); // 用戶2退出聊天室
$u3->Send('歡迎歡迎!'); // 用戶1收到訊息
說明
- 有沒有發現,中介者就是這個“聊天室”,由它來進行資訊的傳遞轉移
- 這里由于不固定用戶人數,因此是一個陣列維護的,當用戶發送訊息的時候,除了他自己,其他人都收到了這條訊息
- 聊天室可以自由地進出用戶,說實話,這個例子真的很像一個已經差不多實作功能了的聊天應用哦
- 果然中介者模式真的很適合通信方面的應用,但是,如果進入的用戶非常多,$users串列就會越來越臃腫了哦,這就是上文中所述的中介者模式的問題所在
下期看點
中介者模式是不是很有趣,在某些場景下也確實非常有用,但是就像之前說的,設計模式并不是萬能藥,利用各種模式的組合才能形成完整的框架,這就是現在流行的各種框架的基礎,所以,學以致用,并且合適的用,才是我們學習的最終目標,別急別急,先把模式一個一個弄清楚了再說框架的事,下一個即將到來的是建造者模式,還請繼續期待喲,
關注公眾號:【硬核專案經理】獲取最新文章
添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、專案管理學習資料
知乎、公眾號、抖音、頭條搜索【硬核專案經理】
B站ID:482780532
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/241725.html
標籤:PHP
下一篇:[PHP] php中的資料型別
