PHP設(shè)計(jì)模式之裝飾模式(Decorator)代碼實(shí)例大全(14)

目的

動(dòng)態(tài)地為類(lèi)的實(shí)例添加功能

例子

  • Zend Framework: Zend_Form_Element 實(shí)例的裝飾者

  • Web Service層:REST服務(wù)的JSON與XML裝飾器(當(dāng)然,在此只能使用其中的一種)

UML圖

★官方PHP高級(jí)學(xué)習(xí)交流社群「點(diǎn)擊」管理整理了一些資料,BAT等一線大廠進(jìn)階知識(shí)體系備好(相關(guān)學(xué)習(xí)資料以及筆面試題)以及不限于:分布式架構(gòu)、高可擴(kuò)展、高性能、高并發(fā)、服務(wù)器性能調(diào)優(yōu)、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優(yōu)化、shell腳本、Docker、微服務(wù)、Nginx等多個(gè)知識(shí)點(diǎn)高級(jí)進(jìn)階干貨

代碼

  • 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)。

2020年最新PHP進(jìn)階教程,全系列!

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容