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

时间:2013-09-20 19:00:46

标签: php unit-testing decorator

从这个例子来看,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();
    }
}

1 个答案:

答案 0 :(得分:3)

你应该实现一个抽象装饰器类,它使用与coffee类相同的接口。此抽象类主要用于将所有方法调用传递给Coffee类。您的具体装饰器从抽象装饰器扩展而来,只覆盖他们想要添加功能的特定方法。请参阅Wiki 有了这个,你就可以摆脱你的$ 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;
    }

}