【问题标题】:Trying to implement (understand) the Decorator pattern in php尝试在 php 中实现(理解)装饰器模式
【发布时间】:2011-09-15 16:22:03
【问题描述】:

我正在尝试理解装饰器模式,并且我已经阅读了关于 SO 的其他相关问题,然后我决定用一个简单的例子来尝试它(我是 PHP 新手):

interface iTitle {
   public function getTitle();
}

class Title implements iTitle {
   protected $_text;

   public function __construct() {
      $this->_text='Our page';
   }

   public function getTitle() {
      return $this->_text;
   }
}

abstract class TitleDecorator implements iTitle {
   protected $_title;

   public function __construct(iTitle $title) {
      $this->_title=$title;
   }
}

class BeforeTitle extends TitleDecorator {
   public function getTitle() {
      return 'Welcome to '.$this->_title->getTitle();
   }
}

class AfterTitle extends TitleDecorator {
   public function getTitle() {
      return $this->_title->getTitle().', Dear user!';
   }
}

这是装饰器模式的(某种)正确实现吗? 如果没有,正确的方法是什么? 如果是,是否可以改进?如何改进? 或者这可能更适合另一种模式?

任何帮助/想法将不胜感激,在此先感谢!

【问题讨论】:

  • 我更新了答案,因为我认为我在您的代码中发现了一些小问题。
  • 获取标题? O_O 应该是 getTitle

标签: php design-patterns


【解决方案1】:

这是装饰器模式的(某种)正确实现吗?

是的

如果是,是否可以改进?如何改进?或者这可能更适合另一种模式?

你实现了装饰器模式。当你想实现一个装饰器模式时,我无法想象有什么比装饰器模式更好的模式。

通常人们会使用装饰器来实现一个接口并仅替换原始对象的一部分并将其余部分传递。这在很大程度上取决于对象的使用。由于您的代码仅显示了如何实现模式而不显示对象的使用,因此无法具体回答该模式是否符合您的需求。

因此,您也可以实现其他模式,然后决定哪种模式感觉更好。模式的症结在于:只有知道哪些存在,才能利用它们。

因此,在模式旁边以及通常选择哪个模式的决定是OOAD。如果你是新手,checkout this nice book

关于您的代码

当你问这是否正确时,我首先回答是。有点对,但是这部分在我看来确实不对:

class BeforeTitle extends TitleDecorator {
   public function getTitle() {
      return 'Welcome to '.$this->getTitle();
   }
}

这是错误的,因为 BeforeTitle 类中的 getter 递归调用自己(它一次又一次地调用自己......)。我认为这不是你的本意。

你在另一个装饰器类中做对了,指的是$this->_title,它是被装饰的对象实例:

class AfterTitle extends TitleDecorator {
   public function getTitle() {
      return $this->_title->getTitle().', Dear user!';
   }
}

如果你想替换/扩展一个对象的行为,但你想这样做而不需要完全重写一个对象的功能,你可以使用装饰器模式。但是其他人可以比我更好地描述这一点。

【讨论】:

    【解决方案2】:

    在装饰模式中,你应该总是注入值而不是在构造函数中初始化。例子 : 这是错误的方式。

    class Title implements iTitle {
       protected $_text;
    
       public function __construct() {
          $this->_text='Our page';
       }
    
       public function getTitle() {
          return $this->_text;
       }
    }
    

    这是正确的方法:

     class Title implements iTitle {
       protected $_text;
    
       public function __construct($text) {
          $this->_text=$text;
       }
    
       public function getTitle() {
          return $this->_text;
       }
    }
    

    如果您需要更详细的真实示例,请参阅链接here

    【讨论】:

      猜你喜欢
      • 2012-02-16
      • 2011-03-08
      • 2019-03-25
      • 2021-04-07
      • 2018-12-23
      • 2018-03-10
      • 1970-01-01
      • 2013-05-04
      • 2010-10-31
      相关资源
      最近更新 更多