PHP设计模式之装饰器(装饰者)模式(Decorator)(4)

RenderInXml.php

<?php
namespace DesignPatterns\Structural\Decorator;
/**
 * RenderInXml类
 */
class RenderInXml extends Decorator
{
  /**
   * render data as XML
   *
   * @return mixed|string
   */
  public function renderData()
  {
    $output = $this->wrapped->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.php

<?php
namespace DesignPatterns\Structural\Decorator;
/**
 * RenderInJson类
 */
class RenderInJson extends Decorator
{
  /**
   * render data as JSON
   *
   * @return mixed|string
   */
  public function renderData()
  {
    $output = $this->wrapped->renderData();
    return json_encode($output);
  }
}

Tests/DecoratorTest.php

<?php
namespace DesignPatterns\Structural\Decorator\Tests;
use DesignPatterns\Structural\Decorator;
/**
 * DecoratorTest 用于测试装饰器模式
 */
class DecoratorTest extends \PHPUnit_Framework_TestCase
{
  protected $service;
  protected function setUp()
  {
    $this->service = new Decorator\Webservice(array('foo' => 'bar'));
  }
  public function testJsonDecorator()
  {
    // Wrap service with a JSON decorator for renderers
    $service = new Decorator\RenderInJson($this->service);
    // Our Renderer will now output JSON instead of an array
    $this->assertEquals('{"foo":"bar"}', $service->renderData());
  }
  public function testXmlDecorator()
  {
    // Wrap service with a XML decorator for renderers
    $service = new Decorator\RenderInXml($this->service);
    // Our Renderer will now output XML instead of an array
    $xml = '<?xml version="1.0"?><foo>bar</foo>';
    $this->assertXmlStringEqualsXmlString($xml, $service->renderData());
  }
  /**
   * The first key-point of this pattern :
   */
  public function testDecoratorMustImplementsRenderer()
  {
    $className = 'DesignPatterns\Structural\Decorator\Decorator';
    $interfaceName = 'DesignPatterns\Structural\Decorator\RendererInterface';
    $this->assertTrue(is_subclass_of($className, $interfaceName));
  }
  /**
   * Second key-point of this pattern : the decorator is type-hinted
   *
   * @expectedException \PHPUnit_Framework_Error
   */
  public function testDecoratorTypeHinted()
  {
    if (version_compare(PHP_VERSION, '7', '>=')) {
      throw new \PHPUnit_Framework_Error('Skip test for PHP 7', 0, __FILE__, __LINE__);
    }
    $this->getMockForAbstractClass('DesignPatterns\Structural\Decorator\Decorator', array(new \stdClass()));
  }
  /**
   * Second key-point of this pattern : the decorator is type-hinted
   *
   * @requires PHP 7
   * @expectedException TypeError
   */
  public function testDecoratorTypeHintedForPhp7()
  {
    $this->getMockForAbstractClass('DesignPatterns\Structural\Decorator\Decorator', array(new \stdClass()));
  }
  /**
   * The decorator implements and wraps the same interface
   */
  public function testDecoratorOnlyAcceptRenderer()
  {
    $mock = $this->getMock('DesignPatterns\Structural\Decorator\RendererInterface');
    $dec = $this->getMockForAbstractClass('DesignPatterns\Structural\Decorator\Decorator', array($mock));
    $this->assertNotNull($dec);
  }
}


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/4111.html