組合模式用來解決整體和部分可以一致對待的問題
比如說 資料夾 和其下的 檔案;
可以複製檔案也可以複製整個資料夾;
組合模式是將物件組合成樹形結構以表示整體和部分的層次結構;
可以方便的增加節點;
說明
運用tp5框架進行測試;
這裡選用的層次結構是:唐朝的三省六部制
程式碼
1、CentralSystem.php檔案(抽象類)
<?php
namespace app\composite\controller;
/**
* Class CentralSystem 中央官制抽象類,其子類必須實現抽象方法
*/
abstract class CentralSystem
{
// 當前類名字
protected $name;
// 建構函式,初始化$name
public function __construct($name)
{
$this->name = $name;
}
// 獲得類名字
public function getName()
{
return $this->name;
}
// 新增子節點
abstract public function add(CentralSystem $centralSystem);
// 移除子節點
abstract public function remove(CentralSystem $centralSystem);
// 迴圈當前節點的子節點
abstract public function show($deep);
}
2、Emperor.php檔案 與 Province.php檔案 一樣 (皇帝類和三省類)
可以只寫一個Emperor檔案,不用同我一樣,我就是糾結症犯了
<?php
namespace app\composite\controller;
use think\Exception;
/**
* Class Emperor 皇帝類,相當於樹的根節點root
*/
class Emperor extends CentralSystem
{
// 存放其子節點
protected $office = [];
/**
* @param CentralSystem $centralSystem 新增子節點,將子節點放在陣列
* @throws Exception
*/
public function add(CentralSystem $centralSystem)
{
// 獲取新節點的名字
$office_name = $centralSystem->getName();
if (in_array($office_name, $this->office)) {
throw new Exception($office_name . '節點已經存在');
} else {
$this->office[$office_name] = $centralSystem;
}
}
/**
* @param CentralSystem $centralSystem 移除子節點,將子節點從陣列中移除
* @throws Exception
*/
public function remove(CentralSystem $centralSystem)
{
// 獲取新節點的名字
$office_name = $centralSystem->getName();
if (in_array($office_name, $this->office)) {
unset($this->office[$office_name]);
} else {
throw new Exception($office_name . '節點不存在');
}
}
/**
* @param int $deep 重複字元'-'的次數
*/
public function show($deep = 0)
{
echo str_repeat('-', $deep) . $this->name;
echo "</br>";
// 迴圈子節點的 節點陣列$office
foreach ($this->office as $item) {
$item->show($deep + 4);
}
}
}
3、Ministries.php檔案 (六部類)
<?php
namespace app\composite\controller;
class Ministries extends CentralSystem
{
/**
* @param CentralSystem $centralSystem 葉子節點,沒有子節點
*/
public function add(CentralSystem $centralSystem)
{
echo "葉子節點不能新增子節點";
}
public function remove(CentralSystem $centralSystem)
{
echo "葉子節點不能移除子節點";
}
/**
* @param int $deep 字元'-'重複的次數
*/
public function show($deep = 0)
{
echo str_repeat('-', $deep) . $this->name. "</br>";
}
}
4、CompositeTest.php 測試檔案
<?php
namespace app\composite\controller;
/**
* Class CompositeTest 組合模式測試----唐朝三省六部制
*/
class CompositeTest
{
public function test()
{
// 唐太宗相當於根節點root
$emperor = new Emperor('唐太宗');
// 唐太宗下的三個子節點:門下省、尚書省、中書省
$emperor->add(new Province('門下省'));
$emperor->add(new Province('中書省'));
$shangshu = new Province('尚書省'); // 這裡單獨賦值是因為“尚書省”要另外新增子節點
$emperor->add($shangshu);
// 尚書省新增六部
$shangshu->add(new Ministries('吏部'));
$shangshu->add(new Ministries('戶部'));
$shangshu->add(new Ministries('禮部'));
$shangshu->add(new Ministries('兵部'));
$shangshu->add(new Ministries('刑部'));
$shangshu->add(new Ministries('工部'));
// 迴圈唐太宗的子節點陣列,其子節點又有自己的子節點。
$emperor->show();
}
}
測試結果
本作品採用《CC 協議》,轉載必須註明作者和本文連結