从装饰器调用方法的正确方法是什么,其中方法不会修改功能


What is the proper way to call methods from a decorator where the method doesn't modify the functionality?

从这个例子来看,CoffeeWithCream的getBrand()方法是否不当或有问题?我这样做的原因是避免在任何地方编写$coffeeWithCream->$coffee->getBrand()。

特别是,浮出水面的一个关注领域是单元测试。我对单元测试还不够满意,无法知道这种策略是否使测试复杂化。

另外,我知道getBrand()只是一个简单的访问器方法。如果该方法执行更复杂的任务,答案会改变吗?

Class Coffee {
    public $brand;
    public $ingredients = array('coffee');
    public function getBrand() {
        return $this->brand;
    }
    public function getIngredients() {
        return $this->ingredients;
    }
}
Class CoffeeWithCream {
    public $coffee;
    public __construct(Coffee $coffee) {
        $this->coffee = $coffee;
    }
    public function getIngredients() {
        $ingredients = $this->coffee->getIngredients();
        $ingredients[] = 'cream';
        return $ingredients;
    }
    public function getBrand() {
        $this->coffee->getBrand();
    }
}

你应该实现一个抽象的装饰器类,它使用与咖啡类相同的接口。这个抽象类基本上用于将所有方法调用传递给 Coffee 类。您的混凝土装饰器从抽象装饰器扩展而来,并且仅覆盖它们要向其添加功能的特定方法。请参考维基有了这个,你将摆脱你的$coffeeWithCream->$coffee->getBrand()问题。

interface ICoffee 
{
    public function getBrand();
    public function getIngredients();
}

class Coffee implements ICoffee { ... }

abstract class CoffeeDecorator implements ICoffee
{
    protected $coffee;      
    public function __construct(Coffee $coffee)
    {
        $this->coffee = $coffee;
    }
    public function getBrand()
    {
        return $this->coffee->getBrand();
    }
    public function getIngredients()
    {
        return $this->coffee->getIngredients();
    }  
}

class CoffeeWithCream extends CoffeeDecorator
{
    public function getIngredients() 
    {
        $ingredients = parent::getIngredients();
        $ingredients[] = 'cream';
        return $ingredients;
    }
}