php设计模式(十四)安全组合模式

上篇文章我们讲了透明组合模式;
但是也说了透明组合模式中的叶子节点虽然有 add 方法;
运行的时候却是抛出错误;
这还有个安全的组合模式避免这种情况;

结构

Component:只包含树枝节点和叶子节点公共的方法抽象类
Composite:树枝节点 有子节点 示例中指 Dir 文件夹
Leaf:叶子节点 没有子节点 示例中指 File 文件

示例

只包含树枝节点和叶子节点公共的方法抽象类
Component.php

<?php

namespace Baijunyao\DesignPatterns\SafeComposite;

/**
 * 只包含树枝节点和叶子节点公共的方法抽象类
 *
 * Class Component
 * @package Baijunyao\DesignPatterns\SafeComposite
 */
abstract class Component
{
    /**
     * @var
     */
    protected $name;

    /**
     * Component constructor.
     * @param $name
     */
    public function __construct($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    abstract public function display();
}

文件夹
Dir.php

<?php

namespace Baijunyao\DesignPatterns\SafeComposite;

/**
 * 文件夹
 *
 * Class Dir
 * @package Baijunyao\DesignPatterns\SafeComposite
 */
class Dir extends Component
{
    /**
     * @var array
     */
    protected $children = [];

    /**
     * 添加子节点
     *
     * @param Component $component
     */
    public function add(Component $component)
    {
        $this->children[] = $component;
    }

    /**
     * @return mixed|string
     */
    public function display()
    {
        $nameStr = $this->name .'<br>';
        foreach ($this->children as $k => $v) {

            $nameStr .= '--' . $v->display();
        }
        return $nameStr;
    }
}

文件
File.php

<?php

namespace Baijunyao\DesignPatterns\SafeComposite;

/**
 * 文件
 *
 * Class File
 * @package Baijunyao\DesignPatterns\SafeComposite
 */
class File extends Component
{
    /**
     * @return mixed|string
     */
    public function display()
    {
        return '--' . $this->name .'<br>';
    }
}

运行;
index.php

<?php

namespace Baijunyao\DesignPatterns\SafeComposite;

require __DIR__.'/../vendor/autoload.php';

/**
 * 客户端
 *
 * Class Client
 * @package Baijunyao\DesignPatterns\SafeComposite
 */
class Client
{
    /**
     * 运行
     */
    public function run()
    {
        $designPatterns = new Dir('design-patterns');

        $classAdapter = new Dir('ClassAdapter');
        $objectAdapter = new Dir('ObjectAdapter');
        $safeComposite = new Dir('SafeComposite');

        $designPatterns->add($classAdapter);
        $designPatterns->add($objectAdapter);
        $designPatterns->add($safeComposite);

        $componentFile = new File('Component.php');
        $dirFile = new File('Dir.php');
        $fileFile = new File('File.php');
        $indexFile = new File('index.php');

        $safeComposite->add($componentFile);
        $safeComposite->add($dirFile);
        $safeComposite->add($fileFile);
        $safeComposite->add($indexFile);

        echo $designPatterns->display();
    }
}

$client = new Client();
$client->run();

运行结果是这个样子的;

我们看一眼 UML ;

在对比下透明模式的 UML ;

我们可以发现其实树枝节点的 Dir.php 没有任何变化;
从透明转变到安全也很直观;
就是把树枝节点特有的方法从抽象类中下移到树枝节点类中;
但是这样也有缺点;
就是没法愉快的面向抽象类编程了;

github示例:https://github.com/baijunyao/design-patterns/tree/master/SafeComposite

白俊遥博客
请先登录后发表评论
  • latest comments
  • 总共2条评论
白俊遥博客

devfomimigame :安全组合 和 透明组合 代码和UML时序图都是一样的@baijunyao

2018-12-31 18:20:28 回复

白俊遥博客

devfomimigame :感觉是放错了,除了File少了add

2018-12-31 18:50:13 回复