将对象组合成树形结构以表示“部分-整体”的层次结构,composite使得用户对单个对象和组合对象的使用具有一致性,<br />说白了就是用对象组成一个树形结构,用户在操作的时候不用在意对象是单一的,还是多个对象,只用一个操作就可以,剩余的交给组合模式的属性结构来解决<br />定义一个数组,每次添加一个对象,对象分为叶子节点,跟节点,节点可以有子节点,可以操作子节点,<br />将A B C 三个对象添加到X对象中,X Y对象再添加到1对象中,这就是树形结构<br />角色:<br />component:组合中的对象接口声明,在适当的情况加实现所有类拥有的默认行为,<br />leaf:在组合中表示叶子节点,没有子节点,<br />composite:定义有子节点的行为,储存子节点,并在接口中实现与子类有关的操作(增加删除)<br />client:最终调用组合部件的对象<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22438777/1635387380129-28048b1f-9f51-4f9f-95c8-5d530f45c2b7.png#clientId=u873a798d-b96e-4&from=paste&height=486&id=uc2c28b33&margin=%5Bobject%20Object%5D&name=image.png&originHeight=486&originWidth=1091&originalType=binary&ratio=1&size=65766&status=done&style=none&taskId=u55ef2972-07f6-4677-8073-22876a234d7&width=1091)
<?php
//组合接口类
abstract class Component
{
protected $name;
public function __construct($name){
$this->name = $name;
}
abstract public function Operation(int $depth);
abstract public function Add(Component $component);
abstract public function Remove(Component $component);
}
//节点
class Composite extends Component
{
private $componentList;
public function Operation($depth)
{
echo str_repeat('-', $depth) . $this->name . PHP_EOL;
foreach ($this->componentList as $component) {
//循环调用子类
$component->Operation($depth + 2);
}
}
public function Add(Component $component)
{
$this->componentList[] = $component;
}
public function Remove(Component $component)
{
$position = 0;
foreach ($this->componentList as $child) {
if ($child == $component) {
array_splice($this->componentList, ($position), 1);
}
++$position;
}
}
public function GetChild(int $i)
{
return $this->componentList[$i];
}
}
//叶子节点
class Leaf extends Component
{
public function Add(Component $c)
{
echo 'Cannot add to a leaf' . PHP_EOL;
}
public function Remove(Component $c)
{
echo 'Cannot remove from a leaf' . PHP_EOL;
}
public function Operation(int $depth)
{
echo str_repeat('-', $depth) . $this->name . PHP_EOL;
}
}
$root =new Composite('root');
$root->add(new Leaf('航母'));
$root->add(new Leaf('潜艇'));
$comp1=new Composite('坦克');
$comp1->add(new Leaf('冲锋车'));
$comp1->add(new Leaf('装甲车'));
$root->add($comp1);
$comp1->add(new Leaf('重坦'));
$root->add(new Composite('飞机'));
var_dump($root);
$root->Remove(new Leaf('潜艇'));
//var_dump($root->GetChild(0));
$root->Operation(1);
// var_dump($root);
class Composite#1 (2) {
private $componentList =>
array(4) {
[0] =>
class Leaf#2 (1) {
protected $name =>
string(6) "航母"
}
[1] =>
class Leaf#3 (1) {
protected $name =>
string(6) "潜艇"
}
[2] =>
class Composite#4 (2) {
private $componentList =>
array(3) {
...
}
protected $name =>
string(6) "坦克"
}
[3] =>
class Composite#8 (2) {
private $componentList =>
NULL
protected $name =>
string(6) "飞机"
}
}
protected $name =>
string(4) "root"
}
实例 比如说发送短信,定义很多组,需要给固定的组,以及组员发送短信,就可以用组合模式,定义好关系,发送短息,只用一个组长,发送,组员(子节点)也会发送<br />组合模式有两种实现方式,透明式的组合模式,安全式的组合模式<br />上面的就是透明式的,一个组合接口定义所有用到的方法,但是叶子节点不用操作子类,也没有子类,有的方法就没有用了,万一调用可能会报错,(实现为空,不操作没事),所以提出了安全式<br />安全式就是定义一个组合接口,里之定义叶子节点的方法,然后节点自己再继承顶一个一个节点接口,自己使用,相当于定义了两个接口,子节点跟叶子节点,