Composite
Purpose:
To treat a group of objects the same way as a single instance of the object.

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
{
/**
* Varibles Description
*
* @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
*
* @return Void
*/
public function addElement(RenderableInterface $element)
{
$this->elements[] = $element;
}
}
?>
InputElement.php
<?php
namespace DesignPatterns\Structural\Composite;
/**
* Input Element
*/
class InputElement implements RenderableInterface
{
/**
* Function Description
*
* @return string
*/
public function render(): string
{
return '<input type="text" />';
}
}
?>
TextElement.php
<?php
namespace DesignPatterns\Structural\Composite;
/**
* Text Element
*/
class TextElement implements RenderableInterface
{
/**
* Varibles Description
*
* @var String
*/
private $text;
public function __construct(string $text)
{
$this->text = $text;
}
/**
* Render
*
* @return string $text
*/
public function render(): string
{
return $this->text;
}
}
?>
Tests/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()
);
}
}
浙公网安备 33010602011771号