欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP设计模式—组合模式

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

 

定义:

组合模式(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