组合模式的目的是为了将对象组合成一个树形结构以表现部分/整体的层次结构。实现组合模式能够统一地处理单个组件与整个组合体。
使用
例如表单组件中可以插入多个子组件:输入框与文本框,同时在表单组件中的任何位置右可以插入其他的表单组件,这样多个子组件就能够以组合模式构成一个大的树形表单组件
代码实现
子组件都必须实现同样的接口,这里是都必须有render()
方法,以为不同的表单组件渲染出不同的 html 格式
interface RenderableInterface
{
public function render();
}
Form 组件能够在其中添加子组件
class Form implements RenderableInterface
{
private $elements;
public function render()
{
$formCode = '<form>';
foreach ($this->elements as $element) {
$formCode .= $element->render();
}
$formCode .= '</form>';
return $formCode;
}
public function addElement(RenderableInterface $element)
{
$this->elements[] = $element;
}
}
Input 与 Text 子组件则是最小的子组件,不能向其中添加功能
class InputElement implements RenderableInterface
{
public function render() : string
{
return '<input type="text" />';
}
}
class TextElement implements RenderableInterface
{
private $text;
public function __construct(string $text)
{
$this->text = $text;
}
public function render() : string
{
return $this->text;
}
}
测试
//新建树结构的根节点
$form = new Form();
//向 form 节点中插入子组件
$form->addElement(new TextElement('Email:'));
$form->addElement(new InputElement());
$embed = new Form();
$embed->addElement(new TextElement('Password:'));
$embed->addElement(new InputElement());
$form->addElement($embed);
echo $form->render();
输出:
<form>Email:<input type="text" /><form>Password:<input type="text" /></form></form>