PHP设计模式——组合器模式

组合模式(有时候又叫做部分-整体模式),将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
实现类图:


12842279-65ca393717910cfc.png
图片.png

三大角色:

抽象结构(Company)角色:此角色实现所有类共有接口的默认行为,声明一个接口管理子部件。

叶子节点(Technology)角色:表示叶子对象,没有子节点。

枝节点(SubCompany)角色:用来存储子部件,实现与子部件有关的操作,如Add()等。

实现代码:

<?php
/**
 * Created by PhpStorm.
 * User: Jiang
 * Date: 2015/5/2
 * Time: 21:14
 */
 
/**抽象结构角色          公司
 * Class Company
 */
abstract class Company
{
    protected $name;
 
    function __construct($name)
    {
        $this->name=$name;
    }
 
    /**增加
     * @param Company $company    子公司,部门
     * @return mixed
     */
    abstract function Add(Company $company);
 
    /**移除
     * @param Company $company   子公司,部门
     * @return mixed
     */
    abstract function Remove(Company $company);
 
    /**显示公司及部门结构
     * @param $depth
     * @return mixed
     */
    abstract function Display($depth);
 
}
 
/**枝节点               子公司
 * Class Beijing
 */
class SubCompany extends Company
{
 
    private $sub_companys=array();
 
    function __construct($name)
    {
        parent::__construct($name);
    }
 
    function Add(Company $company)
    {
        $this->sub_companys[]=$company;
    }
 
    function Remove(Company $company)
    {
        $key=array_search($company,$this->sub_companys);
        if($key!==false)
        {
            unset($this->sub_companys[$key]);
        }
    }
 
    function Display($depth)
    {
        $pre="";
        for($i=0;$i<$depth;$i++)
        {
            $pre.="-";
        }
        $pre.=$this->name."<br/>";
        echo $pre;
 
        foreach($this->sub_companys as $v)
        {
            $v->Display($depth+2);
        }
    }
 
}
 
/**叶子节点                    财务部
 * Class DeptCompany
 */
class MoneyDept extends Company
{
 
    function __construct($name)
    {
        parent::__construct($name);
    }
 
    /**增加
     * @param Company $company 子公司,部门
     * @return mixed
     */
    function Add(Company $company)
    {
        echo "叶子节点,不能继续添加节点。。。。。。。。。。<br/>";
    }
 
    /**移除
     * @param Company $company 子公司,部门
     * @return mixed
     */
    function Remove(Company $company)
    {
        echo "叶子节点,不能删除节点。。。。。。。。。。<br/>";
    }
 
    /**显示公司及部门结构
     * @param $depth
     * @return mixed
     */
    function Display($depth)
    {
        $pre="";
        for($i=0;$i<$depth;$i++)
        {
            $pre.="-";
        }
        $pre.=$this->name."<br/>";
        echo $pre;
    }
 
}
 
/**叶子节点                    技术部门
 * Class DeptCompany
 */
class TechnologyDept extends Company
{
 
    function __construct($name)
    {
        parent::__construct($name);
    }
 
    /**增加
     * @param Company $company 子公司,部门
     * @return mixed
     */
    function Add(Company $company)
    {
        echo "叶子节点,不能继续添加节点。。。。。。。。。。<br/>";
    }
 
    /**移除
     * @param Company $company 子公司,部门
     * @return mixed
     */
    function Remove(Company $company)
    {
        echo "叶子节点,不能删除节点。。。。。。。。。。<br/>";
    }
 
    /**显示公司及部门结构
     * @param $depth
     * @return mixed
     */
    function Display($depth)
    {
        $pre="";
        for($i=0;$i<$depth;$i++)
        {
            $pre.="-";
        }
        $pre.=$this->name."<br/>";
        echo $pre;
    }
 
}

测试代码:

header("Content-Type:text/html;charset=utf-8");
//------------------------组合器模式测试代码------------------
require_once "./Composer/Composer.php";
 
$root=new SubCompany("北京总公司");
$root->Add(new MoneyDept("总公司财务部"));
$root->Add(new TechnologyDept("总公司技术部"));
 
$shanghai=new SubCompany("上海分公司");
$shanghai->Add(new TechnologyDept("上海分公司技术部"));
$shanghai->Add(new MoneyDept("上海分公司财务部"));
 
$root->Add($shanghai);
 
$root->Display(1);
 
echo "<hr/>";
 
$root->Remove($shanghai);
$root->Display(3);

优势:

组合模式让你可以优化处理递归或分级数据结构。有许多关于分级数据结构的例子,使得组合模式非常有用武之地。关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的:文件系统。文件系统由目录和文件组成。每个目录都可以装内容。目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式Composite。


参考:
《大话设计模式》,作者程杰。
https://blog.csdn.net/jhq0113/article/details/45442747

猜你喜欢

转载自blog.csdn.net/weixin_34390996/article/details/87499303