laiyuquan

博客

组合模式(Composite)

模式概念

组合模式:将对象组合成树形结构,以表示“部分-整体”的层次结构;
独立对象:一个有特定功能的对象,它不引用任何其他对象;
组合对象-则是提供相似功能对象的集合,管理独立对象。并为客户端提供和独立对象一样的访问方式。

应用场景

  • 想表示对象的部分-整体层次结构;
  • 让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节

UML类图

《组合模式(Composite)》

代码实现

** RenderableInterface.php**

<?php

namespace DesignPatterns\Structural\Composite;

interface RenderableInterface
{
   public function render(): string;
}

Form.php

<?php

namespace DesignPatterns\Structural\Composite;

/**
* The composite node MUST extend the component contract. This is mandatory for building
* a tree of components.
*/
class Form implements RenderableInterface
{
   /**
    * @var RenderableInterface[]
    */
   private $elements;

   /**
    * runs through all elements and calls render() on them, then returns the complete representation
    * of the form.
    *
    * from the outside, one will not see this and the form will act like a single object instance
    *
    * @return string
    */
   public function render(): string
   {
       $formCode = '<form>';

       foreach ($this->elements as $element) {
           $formCode .= $element->render();
       }

       $formCode .= '</form>';

       return $formCode;
   }

   /**
    * @param RenderableInterface $element
    */
   public function addElement(RenderableInterface $element)
   {
       $this->elements[] = $element;
   }
}

InputElement.php

<?php

namespace DesignPatterns\Structural\Composite;

class InputElement implements RenderableInterface
{
   public function render(): string
   {
       return '<input type="text" />';
   }
}

TextElement.php

<?php

namespace DesignPatterns\Structural\Composite;

class TextElement implements RenderableInterface
{
   /**
    * @var string
    */
   private $text;

   public function __construct(string $text)
   {
       $this->text = $text;
   }

   public function render(): string
   {
       return $this->text;
   }
}

CompositeTest.php

<?php

namespace DesignPatterns\Structural\Composite\Tests;

use DesignPatterns\Structural\Composite;
use PHPUnit\Framework\TestCase;

class CompositeTest extends TestCase
{
   public function testRender()
   {
       $form = new Composite\Form();
       $form->addElement(new Composite\TextElement('Email:'));
       $form->addElement(new Composite\InputElement());
       $embed = new Composite\Form();
       $embed->addElement(new Composite\TextElement('Password:'));
       $embed->addElement(new Composite\InputElement());
       $form->addElement($embed);

       // This is just an example, in a real world scenario it is important to remember that web browsers do not
       // currently support nested forms

       $this->assertEquals(
           '<form>Email:<input type="text" /><form>Password:<input type="text" /></form></form>',
           $form->render()
       );
   }
}

心得总结

  • “部分-整体”的结构层次,而部分和整体又有统一的接口;
  • 层次结构清晰,客户针对抽象进行编程,无需知道是代表部分的叶子对象 还是 代表整理的容器对象,一直的调用方式;

点赞

发表评论