目的
動(dòng)態(tài)地為類(lèi)的實(shí)例添加功能
例子
Zend Framework: Zend_Form_Element 實(shí)例的裝飾者
Web Service層:REST服務(wù)的JSON與XML裝飾器(當(dāng)然,在此只能使用其中的一種)
UML圖

代碼
- RenderableInterface.php
<?php
namespace DesignPatterns\Structural\Decorator;
/**
* 創(chuàng)建渲染接口。
* 這里的裝飾方法 renderData() 返回的是字符串格式數(shù)據(jù)。
*/
interface RenderableInterface
{
public function renderData(): string;
}
- Webservice.php
<?php
namespace DesignPatterns\Structural\Decorator;
/**
* 創(chuàng)建 Webservice 服務(wù)類(lèi)實(shí)現(xiàn) RenderableInterface。
* 該類(lèi)將在后面為裝飾者實(shí)現(xiàn)數(shù)據(jù)的輸入。
*/
class Webservice implements RenderableInterface
{
/**
* @var string
*/
private $data;
/**
* 傳入字符串格式數(shù)據(jù)。
*/
public function __construct(string $data)
{
$this->data = $data;
}
/**
* 實(shí)現(xiàn) RenderableInterface 渲染接口中的 renderData() 方法。
* 返回傳入的數(shù)據(jù)。
*/
public function renderData(): string
{
return $this->data;
}
}
- RendererDecorator.php
<?php
namespace DesignPatterns\Structural\Decorator;
/**
* 裝飾者必須實(shí)現(xiàn)渲染接口類(lèi) RenderableInterface 契約,這是該設(shè)計(jì)
* 模式的關(guān)鍵點(diǎn)。否則,這將不是一個(gè)裝飾者而只是一個(gè)自欺欺人的包
* 裝。
*
* 創(chuàng)建抽象類(lèi) RendererDecorator (渲染器裝飾者)實(shí)現(xiàn)渲染接口。
*/
abstract class RendererDecorator implements RenderableInterface
{
/**
* @var RenderableInterface
* 定義渲染接口變量。
*/
protected $wrapped;
/**
* @param RenderableInterface $renderer
* 傳入渲染接口類(lèi)對(duì)象 $renderer。
*/
public function __construct(RenderableInterface $renderer)
{
$this->wrapped = $renderer;
}
}
- XmlRenderer.php
<?php
namespace DesignPatterns\Structural\Decorator;
/**
* 創(chuàng)建 Xml 修飾者并繼承抽象類(lèi) RendererDecorator 。
*/
class XmlRenderer extends RendererDecorator
{
/**
* 對(duì)傳入的渲染接口對(duì)象進(jìn)行處理,生成 DOM 數(shù)據(jù)文件。
*/
public function renderData(): string
{
$doc = new \DOMDocument();
$data = $this->wrapped->renderData();
$doc->appendChild($doc->createElement('content', $data));
return $doc->saveXML();
}
}
- JsonRenderer.php
<?php
namespace DesignPatterns\Structural\Decorator;
/**
* 創(chuàng)建 Json 修飾者并繼承抽象類(lèi) RendererDecorator 。
*/
class JsonRenderer extends RendererDecorator
{
/**
* 對(duì)傳入的渲染接口對(duì)象進(jìn)行處理,生成 JSON 數(shù)據(jù)。
*/
public function renderData(): string
{
return json_encode($this->wrapped->renderData());
}
}
測(cè)試
- Tests/DecoratorTest.php
<?php
namespace DesignPatterns\Structural\Decorator\Tests;
use DesignPatterns\Structural\Decorator;
use PHPUnit\Framework\TestCase;
/**
* 創(chuàng)建自動(dòng)化測(cè)試單元 DecoratorTest 。
*/
class DecoratorTest extends TestCase
{
/**
* @var Decorator\Webservice
*/
private $service;
/**
* 傳入字符串 'foobar' 。
*/
protected function setUp()
{
$this->service = new Decorator\Webservice('foobar');
}
/**
* 測(cè)試 JSON 裝飾者。
* 這里的 assertEquals 是為了判斷返回的結(jié)果是否符合預(yù)期。
*/
public function testJsonDecorator()
{
$service = new Decorator\JsonRenderer($this->service);
$this->assertEquals('"foobar"', $service->renderData());
}
/**
* 測(cè)試 Xml 裝飾者。
*/
public function testXmlDecorator()
{
$service = new Decorator\XmlRenderer($this->service);
$this->assertXmlStringEqualsXmlString('<?xml version="1.0"?><content>foobar</content>', $service->renderData());
}
}
PHP 互聯(lián)網(wǎng)架構(gòu)師成長(zhǎng)之路*「設(shè)計(jì)模式」終極指南
PHP 互聯(lián)網(wǎng)架構(gòu)師 50K 成長(zhǎng)指南+行業(yè)問(wèn)題解決總綱(持續(xù)更新)
面試10家公司,收獲9個(gè)offer,2020年P(guān)HP 面試問(wèn)題
★如果喜歡我的文章,想與更多資深開(kāi)發(fā)者一起交流學(xué)習(xí)的話,獲取更多大廠面試相關(guān)技術(shù)咨詢和指導(dǎo),歡迎加入我們的群啊,暗號(hào):phpzh(君羊號(hào)碼856460874)。

內(nèi)容不錯(cuò)的話希望大家支持鼓勵(lì)下點(diǎn)個(gè)贊/喜歡,歡迎一起來(lái)交流;另外如果有什么問(wèn)題 建議 想看的內(nèi)容可以在評(píng)論提出