php設計模式及應用場景「php設計模式有哪些幾種」

組合模式(Composite Pattern),又叫部分整體模式,是用於把一組相似的對象當作一個單一的對象。組合模式依據樹形結構來組合對象,用來表示部分以及整體層次。這種類型的設計模式屬於結構型模式,它創建了對象組的樹形結構。

意圖

將對象組合成樹形結構以表示”部分-整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

解決問題

它在我們樹型結構的問題中,模糊了簡單元素和複雜元素的概念,客戶程序可以像處理簡單元素一樣來處理複雜元素,從而使得客戶程序與複雜元素的內部結構解耦。

UML圖

PHP進階教程-設計模式之組合模式

該模式包含的角色及其職責

抽象根節點(Component)

定義系統各層次對象的共有方法和屬性,可以預先定義一些默認行為和屬性。

樹枝節點(Composite)

定義樹枝節點的行為,存儲子節點,組合樹枝節點和葉子節點形成一個樹形結構。

葉子節點(Leaf)

葉子節點對象,其下再無分支,是系統層次遍歷的最小單位。

在本例子中:

PHP進階教程-設計模式之組合模式

優缺點

優點

  • 複雜的對象分層次表示,添加新的節點容易。
  • 客戶端調用簡單,客戶端可以一致的使用組合結構或其中單個對象。
  • 更容易在組合體內加入對象構件,客戶端不必因為加入了新的對象構件而更改原有代碼。

缺點

  • 在使用組合模式時,其葉子和樹枝的聲明都是實現類,而不是介面,違反了依賴倒置原則。
  • 使設計變得更加抽象,對象的業務規則如果很複雜,則實現組合模式具有很大挑戰性,而且不是所有的方法都與葉子對象子類都有關聯。

應用場景

  • 當想表達對象的部分-整體的層次結構時,如公司的上下級關係,分銷系統,產品品牌分類。
  • 希望用戶忽略組合對象與單個對象的不同,用戶將統一地使用組合結構中的所有對象時。

案例背景

舉一個例子:一家公司的組成通常都是多個部門組成的,現在我們有一家公司有多個部門,部門裡面還有很多職位,我們用這個組合模式來看看。

組織架構

PHP進階教程-設計模式之組合模式

使用代碼把上圖轉換成下圖的形式表達

PHP進階教程-設計模式之組合模式

應用場景

Component.php 抽象的公司架構(Component)

abstract class Component
{
    protected $name;
    /**
     * Component constructor.
     * @param $name
     */
    public function __construct($name){
        $this->name = $name;
    }
    public abstract function operation($depth);
    public abstract function add(Component $component);
    public abstract function remove(Component $component);
}

Composite.php 具體的公司部門(Composite)

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_slice($this->componentList, $position, 1);
            }
        }
    }

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

}

Leaf.php 公司部門最終的職位(Leaf)

class Leaf extends Component
{

    public function operation($depth){
        echo str_repeat('-', $depth) . $this->name . PHP_EOL;
    }

    public function add(Component $component){
        echo "Cannot add to a leaf".PHP_EOL;
    }

    public function remove(Component $component){
        echo "Cannot remove from a leaf".PHP_EOL;
    }
}

調用代碼:

$root = new Composite("公司");

// 添加人事部門
$rs = new Composite("人事部門");
// 添加人事部門下面的職位
$rs->add(new Leaf("人事總監"));
$rs->add(new Leaf("人事主管"));
$rs->add(new Leaf("人事專員"));
$root->add($rs);

// 添加財務部門
$cw = new Composite("財務部門");
// 添加部門下面的職位
$cw->add(new Leaf("財務總監"));
$cw->add(new Leaf("會計"));
$cw->add(new Leaf("出納"));
$root->add($cw);

$root->operation(0);

$child = $root->getChild(0);
print_r($child);

輸出結果:

公司
--人事部門
----人事總監
----人事主管
----人事專員
--財務部門
----財務總監
----會計
----出納

// 通過 getChild 獲取的某個部門對象
Composite Object
(
    [Composite:private] => Array
        (
            [0] => Leaf Object
                (
                    [name:protected] => 人事總監
                )

            [1] => Leaf Object
                (
                    [name:protected] => 人事主管
                )

            [2] => Leaf Object
                (
                    [name:protected] => 人事專員
                )

        )

    [name:protected] => 人事部門
)

如果覺得文章還不錯,請把文章分享給更多的人學習,在文章中發現有誤的地方也希望各位指出更正。現有誤的地方也希望各位指出更正。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/259086.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-15 16:30
下一篇 2024-12-15 16:30

相關推薦

發表回復

登錄後才能評論