Recuerda el punto clave, los Decoradores son para agregar/decorar un objeto base y/o modificar su resultado de la clase base. Esto es que los decoradores no deben de funcionar por si solos, y solo es un agregado a la clase, revisa este ejemplo que diseñe:
Código PHP:
Ver original$html = new Html();
$html->addTag(new Link(new Img
('foto.jpg'), 'http://www.php.net/')); $html->addTag(new Bold(new Node('Test')));
En este caso hay dos nodos base, Img, y Node, que son nodos base que no pueden decorar a otro nodo (no puedes hacer <img><algo></img>).
Las clases que use son las siguientes:
Código PHP:
Ver original// Base Tag Class
abstract class Tag
{
abstract public function render();
public function __toString()
{
return $this->render();
}
}
// Base Decorator Class
abstract class TagDecorator extends Tag
{
protected $_tag;
public function __construct(Tag $tag)
{
$this->_tag = $tag;
}
public function getTag()
{
return $this->_tag;
}
}
class Html
{
private $_tags = array(); public function __construct(){}
public function addTag(Tag $tag)
{
$this->_tags[] = $tag;
}
public function renderHtml()
{
$strOutput = '';
foreach ($this->_tags as $Tag) {
$strOutput = (string) $Tag;
}
return $strOutput;
}
public function __toString()
{
return $this->renderHtml();
}
}
/** Base Clases **/
class Node extends Tag
{
private $_text;
public function __construct($text)
{
$this->_text = $text;
}
public function render()
{
return $this->_text;
}
}
class Img extends Tag
{
private $_path;
private $_border;
public function __construct($path, $border = 0)
{
$this->_path = $path;
$this->_border = $border;
}
public function render()
{
return '<img src="' . $this->_path . '" border="'.$this->_border.'" />');
}
}
/** Decorators **/
class Link extends TagDecorator
{
private $_url;
public function __construct(Tag $text, $url)
{
parent::__construct($text);
$this->setUrl($url);
}
public function setUrl($url)
{
$this->_url = $url;
}
public function render()
{
return '<a href="' . $this->_url . '">' . $this->getTag() . '</a>';
}
}
class Bold extends TagDecorator
{
public function render()
{
return '<b>' . $this->getTag() . '</b>';
}
}
class Italic extends TagDecorator
{
public function render()
{
return '<i>' . $this->getTag() . '</i>';
}
}
Saludos.