设计模式--原型模式/装饰器模式

2021-05-02

原型模式:对于大对象使用克隆的方式创建多个对象而不是new的方式创建,因为new对象会消耗更多的资源

装饰器模式:

可以动态的添加修改类的功能
一个类提供了一项功能,如果在修改并添加额外的功能,传统的编程模式,需要写一个子类继承他,并重新实现类的方法
使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
当其中一个装饰器中拥有exit,die等终止语句时,后续的装饰器将不再执行

<?php

interface Decorator
{
	public function beforeDraw();
	public function afterDraw();
}

// 修改字体颜色
class ColorDecorator implements Decorator
{
	private $_color;
	public function __construct($color)
	{
		$this->_color = $color;
	}
	public function beforeDraw()
	{
		return "<div style='color:{$this->_color}'>";
	}
	public function afterDraw()
	{
		return "</div>";
	}
}

// 修改字体大小
class SizeDecorator implements Decorator
{
	private $_size;
	public function __construct($size)
	{
		$this->_size = $size;
	}
	public function beforeDraw()
	{
		return "<div style='font-size:{$this->_size}'>";
	}
	public function afterDraw()
	{
		return "</div>";
	}
}

class BigObject
{
	private $_datas;
	private $_decorators;
	public function __construct($length, $height)
	{
		for ($i = 0; $i <= $legth; $i++) {
			for ($j = 0; $j <= $height; $j++) {
				$this->_datas[$i][$j] = '*';
			}
		}
	}

	public function setXing($a, $a1, $b1, $b2)
	{
		foreach($this->_datas as $k1 => $line)
        {
            if ($k1 < $a1 or $k1 > $a2) continue;
            foreach($line as $k2 => $char)
            {
                if ($k2 < $b1 or $k2 > $b2) continue;
                $this->_datas[$k1][$k2] = '&nbsp;';
            }
        }
	}

	public function draw()
	{
		$this->beforeDecorator();
		foreach ($this->_datas as $value) {
			foreach ($value as $val) {
				echo $val;
			}
			echo "<br />";
		}
		$this->afterDecorator();
	}

	public function addDecorator(Decorator $decorator)
	{
		$this->_decorators[] = $decorator;
	}

	public function beforeDecorator()
	{
		foreach ($this->_decorators as $decorator) {
			$decorator->beforeDraw();
		}
	}

	public function afterDecorator()
	{
		$decorators = array_reverse($this->decorators);
		foreach ($this->_decorators as $decorator) {
			$decorator->afterDraw();
		}
	}
}

$object = new BigObject(20, 10);
// 原型模式伪代码
$object1 = clone $object;
$object2 = clone $object;
// 装饰器模式伪代码
$object->addDecorator(new ColorDecorator('red'));
$object->addDecorator(new SizeDecorator('17px'));
$object->setXing(5,7,9,9);
$object->draw();

 

{/if}