PHP設計模式之組合模式

来源:http://www.cnblogs.com/praglody/archive/2017/04/28/6783317.html
-Advertisement-
Play Games

當我們的一個對象可能代表一個單一的實體,或者一個組合的實體,但是仍然需要通過同樣的方式被使用時,這種情形則適合使用組合模式的設計。 ...


  當我們的一個對象可能代表一個單一的實體,或者一個組合的實體,但是仍然需要通過同樣的方式被使用時,這種情形則適合使用組合模式的設計。

  組合模式是一種結構型模式。

  當看了書上的解釋之後,並不是很理解,遂去翻了翻《大化設計模式》,以下為原文截圖:

 

 

  看完這本書上的解釋之後也不是很理解,但是能夠進行編碼了,以下為組合模式的代碼:

<?php

/**
 * 組合模式抽象基類
 */
abstract class CompanyBase{
    //節點名稱
    protected $name;

    public function __construct($name){

        $this->name = $name;
    }

    public function getName(){
        return $this->name;
    }

    //增加節點
    abstract function add(CompanyBase $c);

    //刪除節點
    abstract function remove(CompanyBase $c);

    //輸出節點信息
    abstract function show($deep);

    //節點職責
    abstract function work($deep);

}

/**
 * 公司類
 */
class Company extends CompanyBase{
    protected $item = [];

    public function add(CompanyBase $c){
        $nodeName = $c->getName();

        if(!isset( $this->item[$nodeName] )){

            $this->item[$nodeName] = $c;
        }else{
            throw new Exception("該節點已存在,節點名稱:".$nodeName);
        }
    }

    public function remove(CompanyBase $c){
        $nodeName = $c->getName();

        if(isset( $this->item[$nodeName] )){

            unset($this->item[$nodeName]);
        }else{
            throw new Exception("該節點不存在,節點名稱:".$nodeName);
        }
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

        foreach($this->item as $value){
            $value->show($deep+4);
        }

    }
    public function work($deep = 0){

        foreach($this->item as $value){
            echo str_repeat("&emsp;",$deep)."[{$this->name}]<br>";
            $value->work($deep+2);
        }
    }

}

/**
 * 人力資源部門
 */
class HumanResources extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("該節點下不能增加節點");
    }

    public function remove(CompanyBase $c){

        throw new Exception("該節點下無子節點");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat("&emsp;",$deep)."人力資源部門的工作是為公司招聘人才";
        echo "<br>";
    }

}

/**
 * 商務部門
 */
class Commerce extends CompanyBase{

    public function add(CompanyBase $c){
        throw new Exception("該節點下不能增加節點");
    }

    public function remove(CompanyBase $c){

        throw new Exception("該節點下無子節點");
    }

    public function show($deep = 0){
        echo str_repeat("-",$deep).$this->name;
        echo "<br>";

    }
    public function work($deep = 0){

        echo str_repeat("&emsp;",$deep)."商務部門的工作是為公司賺取利潤";
        echo "<br>";
    }
}

   設計好類之後,就可以使用它了:

$c = new Company("北京某科技公司");
$h = new HumanResources("人力資源部門");
$com = new Commerce("商務部門");
$c->add($h);
$c->add($com);

//天津分公司
//為了偷懶,分公司的部門直接copy母公司的
$c1 = new Company("天津分公司");
$c1->add($h);
$c1->add($com);
$c->add($c1);

//武漢分公司
$c2 = new Company("武漢分公司");
$c2->add($h);
$c2->add($com);
$c->add($c2);

//使用公司功能
$c->show();
$c->work();

  輸出:

總結以下組合模式的特點:

  1. 必須存在不可分割基本元素;
  2. 組合後的物體任然可以被組合。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 平時我們在用多線程開發的時候少不了Task,確實task給我們帶來了巨大的編程效率,在Task底層有一個TaskScheduler,它決定了task該如何被調度,而 在.net framework中有兩種系統定義Scheduler,第一個是Task預設的ThreadPoolTaskScheduler ...
  • 首先,通過NuGet添加NPOI. NPOI依賴SharpZipLib,通過NuGet添加SharpZipLib. 然後添加NPOI. 添加後項目的引用列表如下: 把DataTable轉換成Excel文件。 代碼如下: public static MemoryStream RenderDataTab ...
  • AspNetCore - MVC實戰系列目錄 . 愛留圖網站誕生 . AspNetCore - MVC實戰系列(一)之Sqlserver表映射實體模型 . AspNetCore-MVC實戰系列(二)之通過綁定郵箱找回密碼 開篇嘮嗑 本篇內容寫在5.1假期前夕,主要是讓大家能在節假日休息充點的時候能有 ...
  • 《Effective C#》快速筆記(三)- 使用 C# 表達設計 目錄 二十一、限制類型的可見性 二十二、通過定義並實現介面替代繼承 二十三、理解介面方法和虛方法的區別 二十四、用委托實現回調 二十五、用事件模式實現通知 二十六、避免返回對內部類對象的引用 二十七、讓類型支持序列化 二十八、提供組 ...
  • //設置頁眉頁腳 tempSheet.Header.Center = "2017-04-27"; tempSheet.Footer.Center = "√" + " 正常 " + "×" + " 故障 " + "○" + " 其他 "; //設置單元格邊線ICellStyle style = wb1 ...
  • NetMQ是ZeroMQ的C#移植版本,它是對標準socket介面的擴展。它提供了一種非同步消息隊列,多消息模式,消息過濾(訂閱),對多種傳輸協議的無縫訪問。本文記錄了NetMQ的源碼進行學習並分析理解。 ...
  • 1.1Spring框架的概述 1.1.1什麼是Spring Spring是分層的JavaSE和JavaEES一站式輕量級開源框架。 分層: SUN提供的EE的三層結構:web層、業務層、數據訪問層(持久層、集成層)。 Struts2是web層基於MVC設計模式框架。 Hibernate是持久層的一個 ...
  • 正則表達式是一個特殊的字元序列,它能幫助你方便的檢查一個字元串是否與某種模式匹配。 re 模塊使 Python 語言擁有全部的正則表達式功能。 compile 函數根據一個模式字元串和可選的標誌參數生成一個正則表達式對象。該對象擁有一系列方法用於正則表達式匹配和替換。 re 模塊也提供了與這些方法功 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...