[设计模式] 组合模式
组合模式用来解决整体和部分可以一致对待的问题
比如说 文件夹 和其下的 文件;
可以复制文件也可以复制整个文件夹;
组合模式是将对象组合成树形结构以表示整体和部分的层次结构;
可以方便的增加节点;
说明
运用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 协议》,转载必须注明作者和本文链接
推荐文章: