PHP設計模式之中介者模式

上回說道,咱們在外打工的常常會和一類人有很深的接觸,那就是房產中介。大學畢業後立刻就能在喜歡的城市買到房子的X二代不在咱們的考慮範圍內哈。既然須要長期的租房,那麼由於工做或者生活的變更,不可避免的一兩年或者三五年就要和房產中介打一次交道。有的時候,咱們租房並不必定會知道房主的信息,房主也不用知道咱們的信息,所有都由中介來進行處理。在這裏,中介就成爲了咱們溝通的橋樑,這種狀況其實就像是房主出國了或者在外地有事兒而將房子徹底的託管到了中介手中。相似於這種狀況,在代碼世界中,就是中介者模式的典型應用。php

Gof類圖及解釋

GoF定義:用一箇中介對象來封裝一系列的對象交互。 中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互git

GoF類圖github

中介者模式

代碼實現web

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學習

實例

這回咱們不發短信了,實現一個聊天室吧。一個簡單的在線聊天室,需求就是讓進入聊天室的用戶均可以在線聊天,讓咱們來看看使用中介者模式來如何實現這個聊天室吧!this

聊天室類圖

聊天室功能中介者模式版

完整源碼: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, 你們好呀!'); // 用戶二、用戶3收到消息

$u2->Send('你好呀!'); // 用戶一、用戶3收到消息

$m->Detach($u2); // 用戶2退出聊天室

$u3->Send('歡迎歡迎!'); // 用戶1收到消息

說明

  • 有沒有發現,中介者就是這個「聊天室」,由它來進行信息的傳遞轉移
  • 這裏因爲不固定用戶人數,所以是一個數組維護的,當用戶發送消息的時候,除了他本身,其餘人都收到了這條消息
  • 聊天室能夠自由地進出用戶,說實話,這個例子真的很像一個已經差很少實現功能了的聊天應用哦
  • 果真中介者模式真的很適合通訊方面的應用,可是,若是進入的用戶很是多,$users列表就會愈來愈臃腫了哦,這就是上文中所述的中介者模式的問題所在

下期看點

中介者模式是否是頗有趣,在某些場景下也確實很是有用。可是就像以前說的,設計模式並非萬能藥,利用各類模式的組合才能造成完整的框架。這就是如今流行的各類框架的基礎。因此,學以至用,而且合適的用,纔是咱們學習的最終目標。別急別急,先把模式一個一個弄清楚了再說框架的事,下一個即將到來的是建造者模式,還請繼續期待喲。

關注公衆號:【硬核項目經理】獲取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料

知乎、公衆號、抖音、頭條搜索【硬核項目經理】

B站ID:482780532

相關文章
相關標籤/搜索