简介:
组合模式,属于结构型的设计模式。将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式分两种状态:
- 透明方式,子类的所有接口一致,使其叶子节点和枝节点对外界没有区别。
- 安全方式,子类接口不一致,只实现特定的接口。
适用场景:
希望客户端可以忽略组合对象与单个对象的差异,进行无感知的调用。
优点:
让客户端忽略层次之间的差异,方便对每个层次的数据进行处理。
缺点:
如果服务端限制类型时,数据不方便处理。
代码:
// component为组合中的对象接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的字部件。
abstract class Component {
protected $name;
function __construct($name) {
$this->name = $name;
}
//通常用add和remove方法来提供增加或移除树枝或树叶的功能
abstract public function add(Component $c);
abstract public function remove(Component $c);
abstract public function display($depth);
}
//透明方式和安全方式的区别就在叶子节点上,透明方式的叶子结点可以无限扩充,然而安全方式就是对其做了绝育限制。
class Leaf extends Component {
public function add(Component $c) {
echo "不能在添加叶子节点了\n";
}
public function remove(Component $c) {
echo "不能移除叶子节点了\n";
}
// 叶节点的具体方法,此处是显示其名称和级别
public function display($depth) {
echo '|' . str_repeat('-', $depth) . $this->name . "\n";
}
}
//composite用来处理子节点,控制添加,删除和展示(这里的展示可以是任意功能)
class Composite extends Component
{
//一个子对象集合用来存储其下属的枝节点和叶节点。
private $children = [];
public function add(Component $c) {
array_push($this->children, $c);
}
public function remove(Component $c) {
foreach ($this->children as $key => $value) {
if ($c === $value) {
unset($this->children[$key]);
}
}
}
public function display($depth) {
echo str_repeat('-', $depth) . $this->name . "\n";
foreach ($this->children as $component) {
$component->display($depth);
}
}
}
//客户端代码
//声明根节点
$root = new Composite('根');
//在根节点下,添加叶子节点
$root->add(new Leaf("叶子节点1"));
$root->add(new Leaf("叶子节点2"));
//声明树枝
$comp = new Composite("树枝");
$comp->add(new Leaf("树枝A"));
$comp->add(new Leaf("树枝B"));
$root->add($comp);
$root->add(new Leaf("叶子节点3"));
//添加并删除叶子节点4
$leaf = new Leaf("叶子节点4");
$root->add($leaf);
$root->remove($leaf);
//展示
$root->display(1);
文章评论