組合模式實現方式二

<?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 持久化。
 */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章