美文网首页
PHP设计模式之装饰模式(Decorator)代码实例大全(14

PHP设计模式之装饰模式(Decorator)代码实例大全(14

作者: 八重樱勿忘 | 来源:发表于2020-09-15 20:54 被阅读0次

    目的

    动态地为类的实例添加功能

    例子

    • Zend Framework: Zend_Form_Element 实例的装饰者

    • Web Service层:REST服务的JSON与XML装饰器(当然,在此只能使用其中的一种)

    UML图

    ★官方PHP高级学习交流社群「点击」管理整理了一些资料,BAT等一线大厂进阶知识体系备好(相关学习资料以及笔面试题)以及不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货

    代码

    • RenderableInterface.php
    
    <?php
    
    namespace DesignPatterns\Structural\Decorator;
    
    /**
    * 创建渲染接口。
    * 这里的装饰方法 renderData() 返回的是字符串格式数据。
    */
    interface RenderableInterface
    {
        public function renderData(): string;
    }
    
    • Webservice.php
    
    <?php
    
    namespace DesignPatterns\Structural\Decorator;
    
    /**
    * 创建 Webservice 服务类实现 RenderableInterface。
    * 该类将在后面为装饰者实现数据的输入。
    */
    class Webservice implements RenderableInterface
    {
        /**
        * @var string
        */
        private $data;
    
        /**
        * 传入字符串格式数据。
        */
        public function __construct(string $data)
        {
            $this->data = $data;
        }
    
        /**
        * 实现 RenderableInterface 渲染接口中的 renderData() 方法。
        * 返回传入的数据。
        */
        public function renderData(): string
        {
            return $this->data;
        }
    }
    
    • RendererDecorator.php
    
    <?php
    
    namespace DesignPatterns\Structural\Decorator;
    
     /**
     * 装饰者必须实现渲染接口类 RenderableInterface 契约,这是该设计
     * 模式的关键点。否则,这将不是一个装饰者而只是一个自欺欺人的包
     * 装。
     * 
     * 创建抽象类 RendererDecorator (渲染器装饰者)实现渲染接口。
     */
    abstract class RendererDecorator implements RenderableInterface
    {
        /**
         * @var RenderableInterface
         * 定义渲染接口变量。
         */
        protected $wrapped;
    
        /**
         * @param RenderableInterface $renderer
         * 传入渲染接口类对象 $renderer。
         */
        public function __construct(RenderableInterface $renderer)
        {
            $this->wrapped = $renderer;
        }
    }
    
    • XmlRenderer.php
    
    <?php
    
    namespace DesignPatterns\Structural\Decorator;
    
    /**
    * 创建 Xml 修饰者并继承抽象类 RendererDecorator 。
    */
    class XmlRenderer extends RendererDecorator
    {
    
        /**
        * 对传入的渲染接口对象进行处理,生成 DOM 数据文件。
        */
        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;
    
    /**
    * 创建 Json 修饰者并继承抽象类 RendererDecorator 。
    */
    class JsonRenderer extends RendererDecorator
    {
        /**
        * 对传入的渲染接口对象进行处理,生成 JSON 数据。
        */
        public function renderData(): string
        {
            return json_encode($this->wrapped->renderData());
        }
    }
    

    测试

    • Tests/DecoratorTest.php
    
    <?php
    
    namespace DesignPatterns\Structural\Decorator\Tests;
    
    use DesignPatterns\Structural\Decorator;
    use PHPUnit\Framework\TestCase;
    
    /**
    * 创建自动化测试单元 DecoratorTest 。
    */
    class DecoratorTest extends TestCase
    {
        /**
         * @var Decorator\Webservice
         */
        private $service;
    
        /** 
        * 传入字符串 'foobar' 。
        */
        protected function setUp()
        {
            $this->service = new Decorator\Webservice('foobar');
        }
    
        /**
        * 测试 JSON 装饰者。
        * 这里的 assertEquals 是为了判断返回的结果是否符合预期。
        */
        public function testJsonDecorator()
        {
            $service = new Decorator\JsonRenderer($this->service);
    
            $this->assertEquals('"foobar"', $service->renderData());
        }
    
        /**
        * 测试 Xml 装饰者。
        */
        public function testXmlDecorator()
        {
            $service = new Decorator\XmlRenderer($this->service);
    
            $this->assertXmlStringEqualsXmlString('<?xml version="1.0"?><content>foobar</content>', $service->renderData());
        }
    }
    

    PHP 互联网架构师成长之路*「设计模式」终极指南

    PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)

    面试10家公司,收获9个offer,2020年PHP 面试问题

    ★如果喜欢我的文章,想与更多资深开发者一起交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入我们的群啊,暗号:phpzh(君羊号码856460874)。

    2020年最新PHP进阶教程,全系列!

    内容不错的话希望大家支持鼓励下点个赞/喜欢,欢迎一起来交流;另外如果有什么问题 建议 想看的内容可以在评论提出

    相关文章

      网友评论

          本文标题:PHP设计模式之装饰模式(Decorator)代码实例大全(14

          本文链接:https://www.haomeiwen.com/subject/ijcqyktx.html