时间: 2020-09-4|tag: 33次围观|0 条评论

 

定义:

组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了。

 

实现方式:

1、透明方式:叶节点和枝节点对于外界没有什么区别,它们具备完全一致的行为接口,问题则是叶节点会有冗余方法。

2、安全方式:叶节点中的冗余代码不实现,问题则是由于不够透明,所以叶节点和枝节点将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

 

代码实例:

一、透明方式实现:

// 1、抽象类Component.php/** * 包含叶节点和枝节点方法的抽象类 * Class Component */abstract class Component{    /**     * @var     */    protected $name;    /**     * Component constructor.     * @param $name     */    public function __construct($name)    {        $this->name = $name;    }    /**     * 添加叶节点或枝节点     * @param Component $component     * @return mixed     */    abstract public function add(Component $component);    /**     * @param $depth     * @return mixed     */    abstract public function display($depth);}// 2、枝节点Composite.php/** * 枝节点 * Class Composite */class Composite extends Component{    /**     * @var array     */    protected $children = [];    /**     * @param Component $component     * @return mixed|void     */    public function add(Component $component)    {        // TODO: Implement add() method.        $this->children[] = $component;    }    public function display($depth)    {        // TODO: Implement display() method.        $nameStr = str_repeat('-', $depth) . $this->name . '<br>';        foreach ($this->children as $component) {            $nameStr .= $component->display($depth + 2);        }        return $nameStr;    }}// 3、叶节点Leaf.php/** * 叶节点 * Class Leaf */class Leaf extends Component{    /**     * 叶节点不需要添加子节点,但为了保持叶节点和枝节点一致,代码冗余,透明方式     * @param Component $component     * @return mixed|string     */    public function add(Component $component)    {        // TODO: Implement add() method.        return '叶节点不能添加子节点' . '<br>';    }    public function display($depth)    {        // TODO: Implement display() method.        return str_repeat('-', $depth) . $this->name . '<br>';    }}

调用:

// 生成树根root,根上长出两叶LeafA和LeafB$root = new Composite("root");$root->add(new Leaf("Leaf A"));$root->add(new Leaf("Leaf B"));// 根上长出分支 CompositeX,分支上也有两叶LeafXA和LeafXB$comp = new Composite("Composite X");$comp->add(new Leaf("Leaf XA"));$comp->add(new Leaf("Leaf XB"));$root->add($comp);// 在CompositeX分支上再长出分支CompositeXY,分支上也有两叶LeafXYA和LeafXYB$comp2 = new Composite("Composite XY");$comp2->add(new Leaf("Leaf XYA"));$comp2->add(new Leaf("Leaf XYB"));$comp->add($comp2);echo $root->display(2);

结果:

--root----Leaf A----Leaf B----Composite X------Leaf XA------Leaf XB------Composite XY--------Leaf XYA--------Leaf XYB

 

二、安全方式实现:

// 1、抽象类Component.php/** * 包含叶节点和枝节点方法的抽象类 * Class Component */abstract class Component{    /**     * @var     */    protected $name;    /**     * Component constructor.     * @param $name     */    public function __construct($name)    {        $this->name = $name;    }    /**     * @param $depth     * @return mixed     */    abstract public function display($depth);}// 2、枝节点Composite.php/** * 枝节点 * Class Composite */class Composite extends Component{    /**     * @var array     */    protected $children = [];    /**     * @param Component $component     * @return mixed|void     */    public function add(Component $component)    {        // TODO: Implement add() method.        $this->children[] = $component;    }    public function display($depth)    {        // TODO: Implement display() method.        $nameStr = str_repeat('-', $depth) . $this->name . '<br>';        foreach ($this->children as $component) {            $nameStr .= $component->display($depth + 2);        }        return $nameStr;    }}// 3、叶节点Leaf.php/** * 叶节点 * Class Leaf */class Leaf extends Component{    public function display($depth)    {        // TODO: Implement display() method.        return str_repeat('-', $depth) . $this->name . '<br>';    }}

调用:

// 生成树根root,根上长出两叶LeafA和LeafB$root = new Composite("root");$root->add(new Leaf("Leaf A"));$root->add(new Leaf("Leaf B"));// 根上长出分支 CompositeX,分支上也有两叶LeafXA和LeafXB$comp = new Composite("Composite X");$comp->add(new Leaf("Leaf XA"));$comp->add(new Leaf("Leaf XB"));$root->add($comp);// 在CompositeX分支上再长出分支CompositeXY,分支上也有两叶LeafXYA和LeafXYB$comp2 = new Composite("Composite XY");$comp2->add(new Leaf("Leaf XYA"));$comp2->add(new Leaf("Leaf XYB"));$comp->add($comp2);echo $root->display(2);

结果:

--root----Leaf A----Leaf B----Composite X------Leaf XA------Leaf XB------Composite XY--------Leaf XYA--------Leaf XYB

 

文章转载于:https://www.cnblogs.com/woods1815/p/12822057.html

原著是一个有趣的人,若有侵权,请通知删除

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自起风了,原文地址《PHP设计模式—组合模式
   

还没有人抢沙发呢~