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