首頁  >  文章  >  後端開發  >  深入淺析PHP中的組合模式

深入淺析PHP中的組合模式

青灯夜游
青灯夜游轉載
2021-07-15 19:30:512752瀏覽

在先前的文章《一文了解PHP中的享元模式》中我們介紹了PHP中的享元模式,以下這篇文章帶大家了解一下PHP設計模式中的組合模式。

深入淺析PHP中的組合模式

網路公司流行扁平化管理,也就是管理層級盡量少於或不超過三層,作為一個底層的碼農,你的CEO和你的職級也就相差3層以內。但是很多傳統企業,則會有非常深的層級關係,從資料結構來看,這種按職能分組的組織架構非常像一顆樹。而我們今天介紹的組合模式的作用就和這個企業組織架構層級的模式非常類似。

Gof類別圖及解釋

GoF定義:將物件組合成樹狀結構以表示「部分-整體」的層次結構。 Composite使得使用者對單一物件和組合物件的使用具有一致性

GoF類別圖

深入淺析PHP中的組合模式

程式碼實作

abstract class Component
{
    protected $name;

    public function __construct($name){
        $this->name = $name;
    }
    
    abstract public function Operation(int $depth);

    abstract public function Add(Component $component);

    abstract public function Remove(Component $component);
}

抽象化的組合節點聲明,在適當情況下實作所有類別的公共介面的預設行為,是所有子節點的父類別。

class Composite extends Component
{
    private $componentList;

    public function Operation($depth)
    {
        echo str_repeat('-', $depth) . $this->name . PHP_EOL;
        foreach ($this->componentList as $component) {
            $component->Operation($depth + 2);
        }
    }

    public function Add(Component $component)
    {
        $this->componentList[] = $component;
    }

    public function Remove(Component $component)
    {
        $position = 0;
        foreach ($this->componentList as $child) {
            ++$position;
            if ($child == $component) {
                array_splice($this->componentList, ($position), 1);
            }
        }
    }

    public function GetChild(int $i)
    {
        return $this->componentList[$i];
    }
}

具體的節點實作類,保存下級節點的引用,定義實際的節點行為。

class Leaf extends Component
{
    public function Add(Component $c)
    {
        echo 'Cannot add to a leaf' . PHP_EOL;
    }
    public function Remove(Component $c)
    {
        echo 'Cannot remove from a leaf' . PHP_EOL;
    }
    public function Operation(int $depth)
    {
        echo str_repeat('-', $depth) . $this->name . PHP_EOL;
    }
}

葉子節點,沒有子節點的最終節點。

  • 從來程式碼來看,完全就是一顆樹的實作
  • 所有的子節點和葉子節點都可以處理數據,但葉子節點為終點
  • #你希望使用者可以忽略組合物件與單一物件的不同,統一地使用組合結構中的所有物件時,就應該考慮使用組合模式
  • 使用者不用關心到底是處理一個葉節點還是處理一個組合元件,也就用不著為定義組合而寫一些選擇判斷語句了
  • 組合模式可以讓客戶一致性地使用組合結構和單一物件

接著文章最開頭的例子來說,在我們的組織架構中,一項任務下達到最底層的人員時,會經歷多個層級。我還是比較喜歡傳統一起的企業管理方式。通常是一位總監對應多位主管,一位主管對應多位經理,一位經理對應多位組長,一位組長對應多位員工。當一個通知下發時,每一層的工作人員都要做出回應,並將通知繼續下發到下屬員工那裡,同時從下屬哪裡獲得回饋。這樣,我們就不知不覺地在實踐中完成了一次組合模式的應用。突然感覺自己棒棒噠,感覺人生已經到達巔峰了! !

完整程式碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/14.composite/source/composite.php

#實例

簡訊短信,這個功能我們可以是翻來覆去的用了。這次也不例外。這項回我們的網站後台的功能是要針對不同分站和不同來源的用戶進行簡訊的發送。在這裡,我們依然只專注於簡訊發送這件事兒,我們希望給你不同管道角色但包含統一行為的用戶,你來進行發送就行了,這樣的功能似乎並不難吧!

簡訊發送類別圖

深入淺析PHP中的組合模式

#完整原始碼:https://github.com/zhangyue0503/designpatterns-php /blob/master/14.composite/source/composite-msg.php

<?php

abstract class Role
{
    protected $userRoleList;
    protected $name;
    public function __construct(String $name)
    {
        $this->name = $name;
    }

    abstract public function Add(Role $role);

    abstract public function Remove(Role $role);

    abstract public function SendMessage();
}

class RoleManger extends Role
{
    public function Add(Role $role)
    {
        $this->userRoleList[] = $role;
    }

    public function Remove(Role $role)
    {
        $position = 0;
        foreach ($this->userRoleList as $n) {
            ++$position;
            if ($n == $role) {
                array_splice($this->userRoleList, ($position), 1);
            }
        }
    }

    public function SendMessage()
    {
        echo "开始发送用户角色:" . $this->name . &#39;下的所有用户短信&#39;, PHP_EOL;
        foreach ($this->userRoleList as $role) {
            $role->SendMessage();
        }
    }
}

class Team extends Role
{

    public function Add(Role $role)
    {
        echo "小组用户不能添加下级了!", PHP_EOL;
    }

    public function Remove(Role $role)
    {
        echo "小组用户没有下级可以删除!", PHP_EOL;
    }

    public function SendMessage()
    {
        echo "小组用户角色:" . $this->name . &#39;的短信已发送!&#39;, PHP_EOL;
    }
}

// root用户
$root = new RoleManger(&#39;网站用户&#39;);
$root->add(new Team(&#39;主站用户&#39;));
$root->SendMessage();

// 社交版块
$root2 = new RoleManger(&#39;社交版块&#39;);
$managerA = new RoleManger(&#39;论坛用户&#39;);
$managerA->add(new Team(&#39;北京论坛用户&#39;));
$managerA->add(new Team(&#39;上海论坛用户&#39;));

$managerB = new RoleManger(&#39;sns用户&#39;);
$managerB->add(new Team(&#39;北京sns用户&#39;));
$managerB->add(new Team(&#39;上海sns用户&#39;));

$root2->add($managerA);
$root2->add($managerB);
$root2->SendMessage();

說明

  • 當我要傳送論壇版塊的用戶時,我可以自由地加入各地方站的葉子節點來控制發送物件
  • 你可以把整個$root2的發送看作是一個整體,不同的版塊和地區看成是部分
  • 這個組合可以一直向下延伸,直到深度的葉子節點結束,這個度當然是由自己來把控,很清晰明了

原文網址:https://juejin .cn/post/6844903967407734792

作者:硬核心專案經理

推薦學習:《PHP影片教學

以上是深入淺析PHP中的組合模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除