您的位置:首页 > 其它

组合模式实现方式二

2017-02-22 15:55 295 查看
<?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 持久化。
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  组合模式