搜尋
首頁後端開發php教程裝飾器模式:釋放設計模式的力量

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

在本系列的前面部分,我們探討了本系列中的外觀和轉接器設計模式。使用 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
PHP中的依賴注入:避免常見的陷阱PHP中的依賴注入:避免常見的陷阱May 16, 2025 am 12:17 AM

DependencyInjection(DI)inPHPenhancescodeflexibilityandtestabilitybydecouplingdependencycreationfromusage.ToimplementDIeffectively:1)UseDIcontainersjudiciouslytoavoidover-engineering.2)Avoidconstructoroverloadbylimitingdependenciestothreeorfour.3)Adhe

如何加快PHP網站:性能調整如何加快PHP網站:性能調整May 16, 2025 am 12:12 AM

到Improveyourphpwebsite的實力,UsEthestertate:1)emplastOpCodeCachingWithOpcachetCachetOspeedUpScriptInterpretation.2)優化的atabasequesquesquesquelies berselectingOnlynlynnellynnessaryfields.3)usecachingsystemssslikeremememememcachedisemcachedtoredtoredtoredsatabaseloadch.4)

通過PHP發送大規模電子郵件:有可能嗎?通過PHP發送大規模電子郵件:有可能嗎?May 16, 2025 am 12:10 AM

是的,ItispossibletosendMassemailswithp.1)uselibrarieslikeLikePhpMailerorSwiftMailerForeffitedEmailsending.2)enasledeLaysBetenemailstoavoidSpamflagssspamflags.3))

PHP中依賴注入的目的是什麼?PHP中依賴注入的目的是什麼?May 16, 2025 am 12:10 AM

DependencyInjection(DI)inPHPisadesignpatternthatachievesInversionofControl(IoC)byallowingdependenciestobeinjectedintoclasses,enhancingmodularity,testability,andflexibility.DIdecouplesclassesfromspecificimplementations,makingcodemoremanageableandadapt

如何使用PHP發送電子郵件?如何使用PHP發送電子郵件?May 16, 2025 am 12:03 AM

使用PHP發送電子郵件的最佳方法包括:1.使用PHP的mail()函數進行基本發送;2.使用PHPMailer庫發送更複雜的HTML郵件;3.使用SendGrid等事務性郵件服務提高可靠性和分析能力。通過這些方法,可以確保郵件不僅到達收件箱,還能吸引收件人。

如何計算PHP多維數組的元素總數?如何計算PHP多維數組的元素總數?May 15, 2025 pm 09:00 PM

計算PHP多維數組的元素總數可以使用遞歸或迭代方法。 1.遞歸方法通過遍歷數組並遞歸處理嵌套數組來計數。 2.迭代方法使用棧來模擬遞歸,避免深度問題。 3.array_walk_recursive函數也能實現,但需手動計數。

PHP中do-while循環有什麼特點?PHP中do-while循環有什麼特點?May 15, 2025 pm 08:57 PM

在PHP中,do-while循環的特點是保證循環體至少執行一次,然後再根據條件決定是否繼續循環。 1)它在條件檢查之前執行循環體,適合需要確保操作至少執行一次的場景,如用戶輸入驗證和菜單系統。 2)然而,do-while循環的語法可能導致新手困惑,且可能增加不必要的性能開銷。

PHP中如何哈希字符串?PHP中如何哈希字符串?May 15, 2025 pm 08:54 PM

在PHP中高效地哈希字符串可以使用以下方法:1.使用md5函數進行快速哈希,但不適合密碼存儲。 2.使用sha256函數提高安全性。 3.使用password_hash函數處理密碼,提供最高安全性和便捷性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。