1

阅读本文并完成装饰器示例。代码返回<strong></strong>而不是预期的<strong><a href="logout.php">Logout</a></strong>

class HtmlLinks {
//some methods which is available to all html links
}

class LogoutLink extends HtmlLinks 
{
protected $_html;

public function __construct() {
$this->_html = "<a href=\"logout.php\">Logout</a>";
}

public function setHtml($html) {
$this->_html = $html;
}

public function render() {
    echo $this->_html;
}
}


class LogoutLinkStrongDecorator extends HtmlLinks {
   protected $_logout_link;

    public function __construct( $logout_link ) {
    $this->_logout_link = $logout_link;
    $this->setHtml("<strong>" . $this->_html . "</strong>");
    }

    public function __call( $name, $args ) {
    $this->_logout_link->$name($args[0]);
    }
}

$logout_link = new LogoutLink();

$logout_link = new LogoutLinkStrongDecorator($logout_link);
$logout_link->render();

整个下午都试图调试,但我没有取得任何进展。任何见解将不胜感激。

4

2 回答 2

1

看起来您忘记从内部对象中提取 _html 了。您需要将它添加到每个装饰器的每个构造函数方法中。基本上加上这个$this->_html=$_linked_obj->_html。

于 2013-07-30T00:48:00.383 回答
0

装饰图案:

  1. Decorator 和 Decorated Object 实现相同的接口。
  2. 装饰器在其构造函数中接受一个实现共享接口的对象。

不一定希望您的装饰器继承自它所装饰的类。您只关心它在您使用它的上下文中实现了您需要的方法(在本例中为“render()”),您可以通过使用接口来强制执行该方法。使用继承的好处是保证所有其他方法仍然是可调用的,并且您还将返回您传入的类的实例。

编码:

interface Renderable
{
    public function render();
}

class HtmlLink implements Renderable
{
    public function render()
    {
        return '<a href="'.$this->href.'">'.$this->anchorText.'</a>';
    }
    // other link methods...
}

class StrongRenderableDecorator implements Renderable
{
    protected $renderable;
    public function __construct(Renderable $renderable)
    {
        $this->renderable = $renderable;
    }
    public function render()
    {
        return '<strong>'.$this->renderable->render().'</strong>';
    }
}

$logout_link = new StrongRenderableDecorator(new LogoutLink());
$logout_link->render();
于 2013-07-30T08:41:53.990 回答