<?php
// 组合模式
interface Component
{
public function doAction();
public function addComponent(Component $c);
public function removeComponent(Component $c);
}
abstract class AbstractComponent
{
// public abstract function doAction();
/**
* default implementation
*/
public function addComponent(Component $c)
{
throw new Exception('This is leaf node, can\'t be call addComponent method!');
}
/**
* default implementation
*/
public function removeComponent(Component $c)
{
throw new Exception('This is leaf node, can\'t be call removeComponent method!');
}
}
/**
* 局部类
* 可能并不需要 addComponent, removeComponent 方法,但是必须实现
* 可以用抽象类作为超类(AbstractComponent),需要实现的覆盖即可,不需要实现的若调用则会发出异常。
*/
class Leaf implements Component
{
public function doAction()
{
echoLine('The [leaf] doAction!');
}
/**
* null implementation
*/
public function addComponent(Component $c) { }
/**
* null implementation
*/
public function removeComponent(Component $c) { }
}
/**
* 组合模式的一个问题是如何实现 add 和 remove 方法。一般的组合模式会在抽象超类中添加 add
* 和 remove 方法。这可以确保模式中的所有类都共享同一个借口,但这同时也意味着局部类也必须
* 实现这些方法。实际上,我们并不希望在局部类中实现这些方法。
*
* 需要担心的问题:
* 1. 组合操作的成本。
* 2. 对象持久化问题。难以直接将数据保存在关系型数据中,但其数据却非常适合持久化为 XML。
*/
class Composite implements Component
{
/**
* component container
*/
private $container = array();
public function doAction()
{
echoLine('The [Composite] doAction!');
foreach ($this->container as $c)
$c->doAction();
}
/**
* add component
* @param Component $c
*/
public function addComponent(Component $c)
{
if(!in_array($c, $this->container, true))
$this->container[] = $c;
}
/**
* remove conponent
* @param Component $c
*/
public function removeComponent(Component $c)
{
$this->container = array_diff($this->container, array($c));
}
/**
* get all components
* @return array
*/
public function getComponents()
{
return $this->container;
}
}
// test code
$leaf = new Leaf();
$composite = new Composite();
$composite->addComponent($leaf);
$composite->addComponent(new Leaf());
$composite->addComponent(new Leaf());
$composite->doAction();
/**
* 总结:
* 如果你想像对待单个对象一样对待组合对象,那么组合模式十分有用。可能是因为组合对象本质上和局部对象
* 相似,也可能因为在环境中组合对象和局部对象的特征相同。因为组合是树型结构,所以对整体的操作会影响
* 到局部,而通过组合,对客户端代码来说局部的数据又是透明的。组合模式使这些操作和查询对客户端代码透明。
* 对象树可以方便的进行遍历。你也可以轻松的在组合结构中加入新的组件类型。
* 但另一方面,组合模式又依赖于其组成部分的简单性。随着我们引入复杂的规则,代码会变得越来越难以维护。
* 组合模式不能很好的在关系型数据库中保存数据,但却非常适合使用 XML 持久化。
*/
组合模式实现方式二
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.