UML图
(GoF《设计模式》):将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
使用场景:当遇到树形的结构,一般使用组合模式。思想是,将枝干和叶子抽象出一个接口,让枝干和叶子类实现抽象接口,让它们具有一致性。常见的文件夹系统。文件的叶子最底层,文件夹是枝干下面可以有文件和文件夹。将文件和文件夹抽象出一个一致对外的接口。
具体代码实现:
//组合抽象接口 Component.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/3/21
* Time: 10:26
*/
abstract class Component
{
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public abstract function add(Component $component);
public abstract function remove(Component $component);
public abstract function display($depth);
}
//实现组合接口文件类 Doc.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/3/21
* Time: 10:31
*/
class Doc extends Component
{
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function add(Component $component)
{
echo "不能向叶子节点添加子节点/n";
}
public function remove(Component $component)
{
echo "叶子节点没有子节点/n";
}
public function display($depth)
{
echo str_repeat('-',$depth).$this->name."\n";
}
}
//实现组合接口文件夹类 Files.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/3/21
* Time: 10:41
*/
require_once 'Component.php';
class Files extends Component
{
public $list = [];
public $name;
public function __construct($name)
{
$this->name = $name;
}
public function add(Component $component)
{
$this->list[$component->name] = $component;
}
public function remove(Component $component)
{
if(isset($this->list[$component->name]))
{
unset($this->list[$component->name]);
}
}
public function display($depth)
{
//echo '<pre>';
//var_dump($this->list);
echo str_repeat('-',$depth).$this->name."\n";
foreach($this->list as $key => $children) {
$children->display($depth+2);
}
}
}
//入口文件 Main.php
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2019/3/21
* Time: 10:50
*/
require_once 'Files.php';
require_once 'Component.php';
require_once 'Doc.php';
header('Content-type:text/html;charset=utf8');
$files = new Files('根目录root');
echo '<pre>';
//var_dump($files);
$fileA = new Doc('根目录下的文件A');
$files->add($fileA);
$files->remove($fileA);
//var_dump($files);
$files->add(new Doc('根目录下的文件B'));
//var_dump($files);
$component = new Files('根目录下的文件夹FA');
$f2 = new Doc('文件夹FA下的文件AA');
$component->add($f2);
$component->add(new Doc('文件夹FA下的文件AB'));
$files->add($component);
$files->display(1);