簡體   English   中英

在PHP中實現Decorator模式的兩種不同方式

[英]Two different ways to implement Decorator pattern in PHP

在進行有關Decorator模式的一些教程時,我遇到了兩種不同的實現。

實施1 (稱為I1)

實施2 (稱為I2)

簡而言之,

I1的父裝飾器類實現了原始對象的接口(在示例中,類PropertyDecorator實現了PropertyInterface 。原始對象Property實現了PropertyInterface )。

I2的父裝飾器類不實現原始對象的接口(在示例中, Decorator_Wrapper不實現Cupcake接口。實際上,甚至CupcakeInterface沒有CupcakeInterface )。

我的問題是

這僅僅是理解和實現裝飾器模式的個人喜好嗎? 或一個是錯誤的,另一個是正確的?

只取決於您的需求。 讓我們來看看:

抽象類

  • 可以提供抽象方法。
  • 可以提供真實的函數和變量。
  • 可以擴展。 但是一個類只能擴展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.
  }
}

當您希望擴展類實例的功能而不擴展類本身時使用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

另外,如果實現基本接口或擴展基類,則在彼此之上添加多個裝飾器可能會更容易,但是...您可能還會得到很多復制功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM