【问题标题】:Correct use of a decorator正确使用装饰器
【发布时间】:2011-12-15 17:33:52
【问题描述】:

我有一个 Products 课程。现在我想向我的网站添加某种折扣模块,该模块应该与 Products 类交互。

目前我能想到的唯一解决方案是使用某种装饰器模式来包裹产品类,这样它就可以改变产品的价格。

像这样:

class Product {
    function price() {
        return 10;
    }
}

class ProductDiscountDecorator {
    private $product;

    function __construct($product) {
        $this->product = $product;
    }

    function price() {
        return $this->product->price()*0.8;
    }
}

$product = new ProductDiscountDecorator(new Product());
echo $product->price();

这是折扣,应在网站的每个页面上调整价格。所以每个使用 Product 类的页面也应该添加装饰器。我能想到解决这个问题的唯一方法是使用自动添加这个装饰器的工厂。

$product = $factory->get('product'); // returns new ProductDiscountDecorator(new Product());

它可能会起作用,但我觉得我在这里误用了装饰器模式。

你们对此有什么想法吗?你会如何实现这样的东西?

【问题讨论】:

    标签: php design-patterns decorator


    【解决方案1】:

    装饰器是一种选择。另一种选择是使用策略模式来计算折扣

    示例

    class Product
    {
        protected $discountStrategy;
        protected $price;
    
        public function __construct(DiscountStrategy $discountStrategy)
        {
            $this->discountStrategy = $discountStrategy;
        }
    
        public function getPrice()
        {
            return $this->discountStrategy->applyDiscount($this->price);
        }
    }
    

    然后将各种可能的折扣封装到自己的类别中:

    interface DiscountStrategy 
    {
        public function applyDiscount($cent);
    }
    
    class NoDiscount implements DiscountStrategy
    {
        public function applyDiscount($cent)
        {
            return $cent;
        }
    }
    
    class PremiumDiscount implements DiscountStrategy
    {
        public function applyDiscount($cent)
        {
            return $cent - $cent * 0.8;
        }
    }
    

    您仍然会使用工厂来组装产品,但策略更精细,您也可以在其他情况下重复使用它们,例如,即使产品本身没有,一些忠实客户也可以获得折扣有折扣。

    【讨论】:

    • 有趣,我会看看 :)
    【解决方案2】:

    总体来说还不错。

    为了遵守良好的 OOP 设计原则,我还将定义一个“产品”接口

    即。

    interface IProduct { public function getPrice(); }
    

    并在 Product 和 ProductDiscountDecorator 上实现它

    class Product implements IProduct { ... }
    class ProductDiscountDecorator implements IProduct { ... }
    

    【讨论】:

      猜你喜欢
      • 2021-05-30
      • 2014-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      相关资源
      最近更新 更多