首頁  >  文章  >  後端開發  >  裝飾器模式:釋放設計模式的力量

裝飾器模式:釋放設計模式的力量

WBOY
WBOY原創
2023-09-04 21:01:08909瀏覽

裝飾器模式:釋放設計模式的力量

在本系列的前面部分,我們探討了本系列中的外觀和轉接器設計模式。使用 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn