2

在做一些关于装饰器模式的教程时,我遇到了两种不同的实现。

实现1(简称I1)

实现2(简称I2)

简而言之,

I1 的父装饰器类实现了原始对象的接口(在示例中,类PropertyDecorator实现了PropertyInterface. 原始对象也Property实现PropertyInterface了)。

I2 的父装饰器类不实现原始对象的接口(在示例中,Decorator_Wrapper不实现Cupcake接口。实际上,甚至根本没有CupcakeInterface)。

我的问题是,

这仅仅是理解和实现装饰器模式的个人偏好吗?还是一个是错的一个是对的?

4

2 回答 2

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.
  }
}
于 2013-05-09T20:36:37.637 回答
0

当您希望扩展类实例的功能而不扩展类本身(因此,不影响所述类的其他实例)时,使用装饰器模式。

它是运行时的一种扩展,非常有用,因为它允许您在运行时自定义对象的行为。你甚至可以用它“模拟”多重继承。

由于您的两个示例都实现了这一点,因此两者都是正确的。不需要装饰器来实现基本接口或扩展原始对象。


然而...


如果装饰器没有实现基接口,它可能无法与原始类互换使用。

如果您不能“安全地”在任何地方使用它,这可能会破坏使用装饰器的目的。

例子:

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

此外,如果您实现基接口或扩展基类,则可能更容易在彼此之上添加多个装饰器,但是......您最终也可能会得到很多复制的功能。

于 2013-05-09T20:53:21.193 回答