裝飾器模式(Decorator)
裝飾器模式能夠從一個(gè)對(duì)象的外部動(dòng)態(tài)地給對(duì)象添加功能。
一般的,我們?yōu)榱藬U(kuò)展一個(gè)類經(jīng)常使用繼承方式實(shí)現(xiàn),由于繼承為類引入靜態(tài)特征,并且隨著擴(kuò)展功能的增多,子類會(huì)很膨脹。使用裝飾器可以動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé)。就增加功能來(lái)說(shuō),裝飾器模式相比生成子類更為靈活。
關(guān)鍵代碼:
Component 類充當(dāng)抽象角色,不應(yīng)該具體實(shí)現(xiàn)。
修飾類引用和繼承 Component 類,具體擴(kuò)展類重寫父類方
//被裝飾類
interface Renderer {
public function renderData();
}
class WebRender implements Renderer {
protected $data;
public function __construct($data) {
$this->data = $data;
}
public function renderData() {
return $this->data;
}
}
現(xiàn)在在不改動(dòng)原有的類的基礎(chǔ)上,增加renderXml和renderJson的功能。
//實(shí)現(xiàn)Renderer的抽象裝飾類
abstract class Decorator implements Renderer {
protected $derectedRender;
public function __construct(Renderer $derectedRender) {
$this->derectedRenderd = $derectedRender;
}
//public function renderData() {
// $this->derectedRenderd->renderData() ;
//}
}
//實(shí)體裝飾類
/**
* RenderInXml類
*/
class RenderInXml extends Decorator {
public function renderData()
{
$output = $this->derectedRenderd->renderData() ;
// do some fancy conversion to xml from array ...
$doc = new \DOMDocument();
foreach ($output as $key => $val) {
$doc->appendChild($doc->createElement($key, $val));
}
return $doc->saveXML();
}
}
/**
* RenderInJson類
*/
class RenderInJson extends Decorator {
public function renderData()
{
$output = $this->derectedRenderd->renderData() ;
return json_encode($output);
}
}
//client
$service = new RenderInXml(new WebRender(array('foo' => 'bar')));