在本系列的前面部分,我們探討了本系列中的外觀和轉接器設計模式。使用 Facade,我們可以簡化大型系統,並且透過實作適配器,我們可以在使用外部 API 和類別時保持安全。現在我們將介紹裝飾器設計模式,它也屬於結構模式的範疇。
#當我們只想為基底類別賦予一些額外的責任時,我們可以使用裝飾器模式。這種設計模式是子類化功能的絕佳替代方案,可擴展功能並具有一些附加優勢。
如果您感到困惑,並認為我們也可以透過子類功能實現相同的功能,那麼讓我向您展示一些程式碼範例,它們將消除您的困惑並讓您喜歡裝飾器模式。
#我將舉一個負責產生電子郵件內容的類別的範例。在下一個程式碼區塊中,如您所見,此類無需任何修改即可很好地產生電子郵件內容。
#class eMailBody { private $header = 'This is email header'; private $footer = 'This is email Footer'; public $body = ''; public function loadBody() { $this->body .= "This is Main Email body.<br />"; } }
我們知道聖誕節即將到來,假設我想在下一封時事通訊電子郵件中向我的讀者致意。因此,我必須在電子郵件正文中添加一條訊息,其中包含看起來不錯的圖像。
為此,我可以直接在我的電子郵件類別中進行編輯,但我真的不想這樣做。所以我可以實現繼承來達到同樣的效果。我創建主電子郵件正文類別的單獨子類別:
class christmasEmail extends eMailBody { public function loadBody() { parent::loadBody(); $this->body .= "Added Content for Xmas<br />"; } } $christmasEmail = new christmasEmail(); $christmasEmail->loadBody(); echo $christmasEmail->body;
所以我完成了我的程式碼,我想在幾天後發送一封包含新年祝福的電子郵件。我們可以使用與聖誕節相同的方法。
class newYearEmail extends eMailBody { public function loadBody() { parent::loadBody(); $this->body .= "Added Content for New Year<br />"; } } $newYearEmail = new newYearEmail(); $newYearEmail->loadBody(); echo $newYearEmail->body;
一切都很順利,沒有出現任何問題。現在,假設我忘記在這兩個場合(聖誕節和新年)向訪客致意,並且我想在一封電子郵件中發送這兩種問候,而不修改基類中的任何代碼。
您的腦海中立即充滿了以下問題:子類別和繼承在這裡會有幫助嗎?我贊成這樣做,但我們需要使用額外/不必要的程式碼來實現這一點。我們可以使用特徵來實現類似多重繼承的東西。
我們在上一節中討論的問題可以透過實作裝飾器模式來解決。
#根據維基百科:
裝飾器模式(也稱為包裝器,與適配器模式共享的替代命名)是一種設計模式,允許靜態或動態地將行為添加到單個對象,而不影響其他對象的行為。同一個班級。
在上一節中,我們已經看到,我們可以使用一個子類別來擴展功能/行為,但是當涉及到添加多個功能/行為時,它就會變得冗長而複雜。這就是我們應該使用裝飾器模式的地方。
interface eMailBody { public function loadBody(); }
這是一個簡單的接口,用於確保某些類別必須實現所需的方法。
class eMail implements eMailBody { public function loadBody() { echo "This is Main Email body.<br />"; } }
這是產生電子郵件預設正文的主類,我通常用它來發送電子郵件。然而,我需要的是根據某些場合修改正文內容,但不更改主要電子郵件類。
abstract class emailBodyDecorator implements eMailBody { protected $emailBody; public function __construct(eMailBody $emailBody) { $this->emailBody = $emailBody; } abstract public function loadBody(); }
這是我們的主要裝飾器類,它保存對我們的主要電子郵件類的引用並根據需要更改其行為。這裡我們定義了一個抽象方法,loadBody
,子裝飾器需要實作它來改變行為。
class christmasEmailBody extends emailBodyDecorator { public function loadBody() { echo 'This is Extra Content for Christmas<br />'; $this->emailBody->loadBody(); } } class newYearEmailBody extends emailBodyDecorator { public function loadBody() { echo 'This is Extra Content for New Year.<br />'; $this->emailBody->loadBody(); } }
這裡我們創建了主裝飾器的兩個子類,它們實際上對我們的主電子郵件類執行了行為更改。
我們已經創建了所有必要的元素。我們需要做的就是使用我們的程式碼並享受。
interface eMailBody { public function loadBody(); } class eMail implements eMailBody { public function loadBody() { echo "This is Main Email body.<br />"; } } abstract class emailBodyDecorator implements eMailBody { protected $emailBody; public function __construct(eMailBody $emailBody) { $this->emailBody = $emailBody; } abstract public function loadBody(); } class christmasEmailBody extends emailBodyDecorator { public function loadBody() { echo 'This is Extra Content for Christmas<br />'; $this->emailBody->loadBody(); } } class newYearEmailBody extends emailBodyDecorator { public function loadBody() { echo 'This is Extra Content for New Year.<br />'; $this->emailBody->loadBody(); } }
現在我們將根據需要以各種方式使用這個裝飾器類別:
/* * Normal Email */ $email = new eMail(); $email->loadBody(); // Output This is Main Email body. /* * Email with Xmas Greetings */ $email = new eMail(); $email = new christmasEmailBody($email); $email->loadBody(); // Output This is Extra Content for Christmas This is Main Email body. /* * Email with New Year Greetings */ $email = new eMail(); $email = new newYearEmailBody($email); $email->loadBody(); // Output This is Extra Content for New Year. This is Main Email body. /* * Email with Xmas and New Year Greetings */ $email = new eMail(); $email = new christmasEmailBody($email); $email = new newYearEmailBody($email); $email->loadBody(); // Output This is Extra Content for New Year. This is Extra Content for Christmas This is Main Email body.
我們可以看到,現在我們已經更改了電子郵件的正文,而沒有修改主電子郵件類別。
我們擁有的每個應用程式都需要定期進行某種更改和/或改進。所以在這種情況下我們可以實現裝飾器設計模式,它最終會提高程式碼品質並使我們的程式碼更具可擴展性。
我盡力向您解釋裝飾器模式,但如果您還有其他意見或問題,請隨時將其添加到下面的 Feed 中。
以上是裝飾器模式:釋放設計模式的力量的詳細內容。更多資訊請關注PHP中文網其他相關文章!