组合模式
将若干局部对象根据标准组合成一个抽象的庞大的对象
- 通过 聚合 来管理很多 相似 的对象
组合模式类的设计
- 划分主对象和局部对象两种角色
- 主对象与局部对象通过继承对象共享一个接口
- 因为共享一个接口,组合对象也可以是当做"局部对象"使用
- 主对象操作的是局部对象。局部对象不可操作组合对象
- 主对象是局部对象的继承类
场景举例
- 因为是树形结构,可以很好生成xml
- 通过组合模式,可以丰富商品的属性
缺陷
- 所有的类要继承一个基类
- 模型越复杂,就要越多组合对象。对象会臃肿
- 特殊对象越多,组合模式弊大于利
总结
- 通过单个对象去理解组合对象
- 组成结构尽可能简单,不复杂化
- 组合模式思想: 聚合组件
代码思路
- 创建主体对象和局部对象接口
- 两者接口需要统一
- 主体开放接口添加对应接口
- 主体对象在执行的时候,也会操作局部对象接口
- 组合模式的局部对象, 是主体对象的一个属性。
代码示例
<?php
/**
* 属性类接口
* Class attribute
*/
abstract class attribute {
/**
* 以数组返回
* @return array
*/
abstract function Attr(): array ;
}
/**
* 局部对象: 颜色属性
* Class ColorAttr
*/
class ColorAttr extends attribute {
function Attr(): array
{
return [
'color' => 'red'
];
}
}
/**
* 局部对象: 尺寸属性
* Class SizeAttr
*/
class SizeAttr extends attribute {
function Attr(): array
{
return [
'size' => '1980*1080'
];
}
}
/**
* 局部对象: 作者
* Class AuthorAttr
*/
class AuthorAttr extends attribute {
function Attr(): array
{
return [
'author' => 'mk'
];
}
}
/**
* 主对象: 商品
*/
class Good {
/**
* 定义局部对象
* @var array
*/
protected $middle = [
SizeAttr::class,
AuthorAttr::class,
ColorAttr::class
];
/**
* 商品保存
* @var array
*/
private $attr = [];
/**
* 通过组合的方式,将局部对象属性组合进来
* @throws ReflectionException
*/
public function attr(){
foreach ($this->middle as $attr)
{
$obj = new ReflectionClass($attr);
$method = $obj->getMethod('Attr');
$val = $method->invoke($obj->newInstance());
$this->attr = array_merge($this->attr,$val);
}
return $this->attr;
}
}
// 输出打印
var_dump((new Good())->attr());