裝飾器模式
允許向一個(gè)已有的對(duì)象動(dòng)態(tài)添加新的功能,又不改變其結(jié)構(gòu),使用子類繼承的方法去實(shí)現(xiàn)添加新功能,會(huì)不可避免的出現(xiàn)子類過(guò)多,繼承鏈很長(zhǎng)額情況.
目錄結(jié)構(gòu)
|decorator #項(xiàng)目根目錄
|--Think #核心類庫(kù)
|----Loder.php #自動(dòng)加載類
|----decorator.php #裝飾器接口
|----colorDecorator.php #顏色裝飾器
|----sizeDecorator.php #字體大小裝飾器
|----echoText.php #被裝飾者
|--index.php #單一的入口文件
代碼實(shí)踐
裝飾器接口 Think/decorator.php
<?php
/**
* 裝飾器接口
* Interface decorator
* @package Think
*/
namespace Think;
interface decorator{
public function beforeDraw();
public function afterDraw();
}
顏色裝飾器 Think/colorDecorator.php
<?php
/**
* 顏色裝飾器
*/
namespace Think;
class colorDecorator implements decorator{
protected $color;
public function __construct($color) {
$this->color = $color;
}
public function beforeDraw() {
echo "color decorator :{$this->color}\n";
}
public function afterDraw() {
echo "end color decorator\n";
}
}
字體大小裝飾器 Think/sizeDecorator.php
<?php
/**
* 字體大小裝飾器
*/
namespace Think;
class sizeDecorator implements decorator{
protected $size;
public function __construct($size) {
$this->size = $size;
}
public function beforeDraw() {
echo "size decorator {$this->size}\n";
}
public function afterDraw() {
echo "end size decorator\n";
}
}
被裝飾者 Think/echoText.php
<?php
/**
* 被裝飾者
*/
namespace Think;
class echoText {
protected $decorator = array(); //存放裝飾器
//裝飾方法
public function index() {
//調(diào)用裝飾器前置操作
$this->before();
echo "你好,我是裝飾器\n";
//執(zhí)行裝飾器后置操作
$this->after();
}
public function addDecorator(Decorator $decorator) {
$this->decorator[] = $decorator;
}
//執(zhí)行裝飾器前置操作 先進(jìn)先出
public function before() {
foreach ($this->decorator as $decorator){
$decorator->beforeDraw();
}
}
//執(zhí)行裝飾器后置操作 先進(jìn)后出
public function after() {
$decorators = array_reverse($this->decorator);
foreach ($decorators as $decorator){
$decorator->afterDraw();
}
}
}
自動(dòng)加載 Think/Loder.php
<?php
namespace Think;
class Loder{
static function autoload($class){
require BASEDIR . '/' .str_replace('\\','/',$class) . '.php';
}
}
入口文件index.php
<?php
define('BASEDIR',__DIR__);
include BASEDIR . '/Think/Loder.php';
spl_autoload_register('\\Think\\Loder::autoload');
//實(shí)例化輸出類
$echo = new \Think\echoText();
//增加裝飾器
$echo->addDecorator(new \Think\colorDecorator('red'));
//增加裝飾器
$echo->addDecorator(new \Think\sizeDecorator('12'));
//裝飾方法
$echo->index();