在PHP中实现Decorator模式的两种不同方法

时间:2013-05-09 20:23:08

标签: php design-patterns decorator

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

Implementation 1(简称I1)

Implementation 2(简称I2)

简而言之,

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

I2的父装饰器类没有实现原始对象的接口(在示例中,Decorator_Wrapper没有实现Cupcake接口。实际上,根本没有CupcakeInterface。< / p>

我的问题是,

这仅仅是个人偏好理解和实施Decorator模式吗?或者一个是错的,一个是对的?

2 个答案:

答案 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

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