Home » Code » 常见设计模式之——装饰器模式(2)

常见设计模式之——装饰器模式(2)

这一系列最先的一篇已写有装饰器模式,现补充另一更直观的写法。依然是发表文章,这次是模拟一篇文章在页面上渲染出来的过程。文章是什么原封不动,只是在渲染的过程中对它进行一系列“装饰”,使之呈现出来符合我们的要求:或许要加点摘要,或者要过滤一下敏感词等等,文章渲染出来后或许还要做点其他,比如添加某些记录、后边再输出个版权信息等等。我们仍以小编与总编两个“装饰器”来对文章进行装饰。

class Article
{
	protected $content;
	protected $decorators = array();//存储所有装饰器

	public function __construct($content)
	{
		$this->content = $content;
	}

	public function addDecorator(Decorator $decorator)
	{
		$this->decorators[] = $decorator;//动态添加装饰器
	}

	protected function beforeRender()
	{
		//前面的修饰,先添加的先运行,反转一下
		$decorators = array_reverse($this->decorators);
		foreach ($decorators as $decorator)
		{
			$decorator->beforeRender($this->content);
		}
	}

	protected function afterRender()
	{
		//后边的装饰,后添加的后运行,不需要反转
		$decorators = $this->decorators;
		foreach ($decorators as $decorator)
		{
			$decorator->afterRender($this->content);
		}
	}

	public function render()
	{
		$this->beforeRender($this->content);//运行所有渲染前的装饰方法

		echo '(这是内容部分:内容输出前编辑内容或执行操作)<br/>';

		echo '<div style="color:red">';
		echo $this->content;
		echo '</div>';

		echo '<br/>(这是内容输出后的部分:内容输出后执行其他操作)<br/>';

		$this->afterRender($this->content);//运行所有渲染后的装饰方法
	}

}

interface Decorator
{
	public function beforeRender(&$content);
	public function afterRender(&$content);
}

class Xiaobian implements Decorator
{
	public function beforeRender(&$content)
	{
		$content = "内容前追加:小编加了摘要<br/>".$content;
		return TRUE;
	}
	public function afterRender(&$content)
	{
		echo "内容输出后输出:小编审核记录已存储<br/>";
		return TRUE;
	}
}

class Zongbian implements Decorator
{
	public function beforeRender(&$content)
	{
		$content = "内容前追加:总编过滤了敏感词<br/>".$content;
		return TRUE;
	}
	public function afterRender(&$content)
	{
		echo "内容输出后输出:文章来自XXX,版权所有,转载必究————XXX主编:吴大嘴<br/>";
		return TRUE;
	}
}

$content = new Article('This is a test Article!');
$content->addDecorator(new Xiaobian());
$content->addDecorator(new Zongbian());
$content->render();

结果输出如下:

(这是内容部分:内容输出前编辑内容或执行操作)
内容前追加:小编加了摘要
内容前追加:总编过滤了敏感词
This is a test Article!

(这是内容输出后的部分:内容输出后执行其他操作)
内容输出后输出:小编审核记录已存储
内容输出后输出:文章来自XXX,版权所有,转载必究————XXX主编:吴大嘴

在一些框架中,经常有的before、after这些方法,应该也是一些装饰器。Wordpress中的所谓钩子add_filter之类,跟装饰器应该也是差不多,都是将内容接过来装饰一下(有时候或许需要再将之返回才能生效),或者借助这个方法运行的环境执行一些额外的操作。

One comment

  1. mark,又一篇高大上

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.