在做一些关于Decorator模式的教程时,我遇到了两种不同的实现。
Implementation 1(简称I1)
Implementation 2(简称I2)
简而言之,
I1的父装饰器类实现原始对象的接口(在示例中,类PropertyDecorator
实现PropertyInterface
。原始对象Property
也实现PropertyInterface
。
I2的父装饰器类没有实现原始对象的接口(在示例中,Decorator_Wrapper
没有实现Cupcake
接口。实际上,根本没有CupcakeInterface
。< / p>
我的问题是,
这仅仅是个人偏好理解和实施Decorator模式吗?或者一个是错的,一个是对的?
答案 0 :(得分:1)
只取决于您的需求。 我们来看看:
抽象类
<强>接口强>
我通常更喜欢使用基本抽象类,因为我也可以声明一些基本函数,因为你可以拥有许多具有类似功能的不同类型的装饰器。无论如何都可以覆盖方法+你可以实现一些接口。
class Decorator extends Decorator_Wrapper implements Interface1, Inteface2 {
public function __construct(){
parent::__construct() ; // Here you could perform some basic decorator actions. It is an advantage compared to interfaces.
}
}
答案 1 :(得分:0)
当您希望扩展类实例的功能而不扩展类本身(因此,不影响所述类的其他实例)时,将使用Decorator模式。
它在运行时是一种扩展,它非常有用,因为它允许您在运行时自定义对象的行为。你甚至可以用它“模拟”多重继承。
由于您的示例都可以实现此目的,因此两者都是正确的。装饰器不需要实现基接口或扩展原始对象。
...无论其
如果装饰器没有实现基本接口,它可能无法与原始类互换使用。
如果不能“安全地”使用它,那么可能会破坏使用装饰器的目的。
示例:
interface FooInterface {
public function scare();
}
class Foo implements FooInterface {
protected $boo = 'boo';
public function scare() { echo $this->boo; }
}
class FooBar {
public function __construct(FooInterface $foo) {
$this->foo = $foo;
}
public function scareAlot() {
echo strtoupper($this->foo->scare());
}
}
class INeedFoo {
public static function gimmeFoo(FooInterface $foo) {}
}
$foo = new Foo();
$fooBar = new FooBar($foo);
INeedFoo::gimmeFoo($foo); //Works
INeedFoo::gimmeFoo($fooBar); //Does not Work
此外,如果您实现基本接口或扩展基类,可能更容易在彼此之上添加多个装饰器,但是......您最终可能会获得大量复制功能。