2.裝飾器模式

概述

裝飾器模式:在原有結構,動態地為對象添加職責,它是一種靈活的擴展功能方式。

業務場景:創建訂單

假設你正在開發一個電商系統,用戶在創建訂單時可以選擇不同的服務(如折扣、配送、禮品包裝等)。你需要靈活地計算訂單的總價,并能夠動態地添加或移除這些服務。

核心思想

在創建訂單場景中的核心思想是動態擴展,它通過組合而非繼承的方式,創建時能不斷擴展,訂單對象傳進入參不斷擴展。


1. 基礎組件接口 (Order)

public interface Order {double getTotalPrice(); // 獲取訂單總價String getDescription(); // 獲取訂單描述
}

2. 具體組件 (BasicOrder)

public class BasicOrder implements Order {private double basePrice; // 訂單基礎價格public BasicOrder(double basePrice) {this.basePrice = basePrice;}@Overridepublic double getTotalPrice() {return basePrice; // 返回基礎價格}@Overridepublic String getDescription() {return "基礎訂單(價格:" + basePrice + ")";}
}

3. 裝飾器基類 (OrderDecorator)

public abstract class OrderDecorator implements Order {protected Order decoratedOrder;public OrderDecorator(Order order) {this.decoratedOrder = order;}@Overridepublic double getTotalPrice() {return decoratedOrder.getTotalPrice();}@Overridepublic String getDescription() {return decoratedOrder.getDescription();}
}

4. 具體裝飾器?

折扣裝飾器?DiscountDecorator
public class DiscountDecorator extends OrderDecorator {private double discountRate; // 折扣率public DiscountDecorator(Order order, double discountRate) {super(order);this.discountRate = discountRate;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() * (1 - discountRate); // 應用折扣}@Overridepublic String getDescription() {return super.getDescription() + " + 折扣(" + (discountRate * 100) + "%)";}
}
加急配送裝飾器?ExpressShippingDecorator
public class ExpressShippingDecorator extends OrderDecorator {private double expressShippingFee; // 加急配送費用public ExpressShippingDecorator(Order order, double expressShippingFee) {super(order);this.expressShippingFee = expressShippingFee;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() + expressShippingFee; // 添加加急配送費用}@Overridepublic String getDescription() {return super.getDescription() + " + 加急配送(費用:" + expressShippingFee + ")";}
}
禮品包裝裝飾器?GiftWrapDecorator
public class GiftWrapDecorator extends OrderDecorator {private double giftWrapFee; // 禮品包裝費用public GiftWrapDecorator(Order order, double giftWrapFee) {super(order);this.giftWrapFee = giftWrapFee;}@Overridepublic double getTotalPrice() {return super.getTotalPrice() + giftWrapFee; // 添加禮品包裝費用}@Overridepublic String getDescription() {return super.getDescription() + " + 禮品包裝(費用:" + giftWrapFee + ")";}
}

5. 客戶端代碼

public class OrderSystem {public static void main(String[] args) {// 創建一個基礎訂單Order order = new BasicOrder(100.0);System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加折扣order = new DiscountDecorator(order, 0.1); // 10% 折扣System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加加急配送order = new ExpressShippingDecorator(order, 15.0); // 加急配送費用 15System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());// 添加禮品包裝order = new GiftWrapDecorator(order, 5.0); // 禮品包裝費用 5System.out.println(order.getDescription());System.out.println("總價: " + order.getTotalPrice());}
}

6. 輸出

基礎訂單(價格:100.0)
總價: 100.0
基礎訂單(價格:100.0) + 折扣(10.0%)
總價: 90.0
基礎訂單(價格:100.0) + 折扣(10.0%) + 加急配送(費用:15.0)
總價: 105.0
基礎訂單(價格:100.0) + 折扣(10.0%) + 加急配送(費用:15.0) + 禮品包裝(費用:5.0)
總價: 110.0

業務場景總結

  1. 問題:訂單可能需要添加多種附加服務(如折扣、運費、包裝費等),如果為每種組合創建單獨的類,會導致類爆炸。

  2. 解決方案:使用裝飾器模式,動態地為訂單添加附加服務。

  3. 優點

    • 靈活擴展功能,無需修改訂單類的核心邏輯。

    • 支持動態添加或移除服務,符合開閉原則。

    • 避免類爆炸,組合功能更加簡潔。


其他業務場景

  1. 購物車:為購物車動態添加優惠券、滿減活動等。

  2. 訂閱服務:為用戶訂閱動態添加附加功能(如高級功能、額外存儲等)。

  3. 賬單系統:為賬單動態添加稅費、服務費等。

裝飾器模式在創建訂單場景中的核心思想是動態擴展,它通過組合而非繼承的方式,靈活地為訂單添加功能或服務。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72866.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72866.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72866.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++11新特性 10.初始化列表、initializer_list

目錄 一.初始化列表 使用示例 二.initializer_list 1.基本概念 2.使用示例 一.初始化列表 C11提供的統一初始化方式&#xff0c;實現直接對數據初始化 使用示例 /* 初始化列表 */ #include <iostream> using namespace std; class Person { public:Person(string…

Vue 的 render 函數如何與 JSX 結合使用

在 Vue.js 中&#xff0c;render 函數提供了一種更底層的方式來創建虛擬 DOM 節點&#xff0c;而 JSX 則是一種 JavaScript 的語法擴展&#xff0c;允許開發者在 JavaScript 代碼中直接編寫類似 HTML 的結構。結合使用 render 函數和 JSX 可以帶來更高的靈活性和編程能力&#…

基于DeepSeek的智慧醫藥系統(源碼+部署教程)

運行環境 智慧醫藥系統運行環境如下&#xff1a; 前端&#xff1a; HTMLCSS后端&#xff1a;Java AIGCDeepseekIDE工具&#xff1a;IDEA技術棧&#xff1a;Springboot HTMLCSS MySQL 主要角色 智慧醫藥系統主要分為兩個角色。 游客 尚未進行注冊和登錄。具備登錄注冊、…

南開提出1Prompt1Story,無需訓練,可通過單個連接提示實現一致的文本到圖像生成。

&#xff08;1Prompt1Story&#xff09;是一種無訓練的文本到圖像生成方法&#xff0c;通過整合多個提示為一個長句子&#xff0c;并結合奇異值重加權&#xff08;SVR&#xff09;和身份保持交叉注意力&#xff08;IPCA&#xff09;技術&#xff0c;解決了生成圖像中身份不一致…

BLUEM2引擎源碼2025最新版

BLUE 引擎解析&#xff1a;傳奇私服圈中的熱門引擎 一、BLUE 引擎簡介 BLUE 引擎是傳奇私服圈子中較為知名的一款游戲引擎&#xff0c;它在傳統的傳奇引擎基礎上進行了優化和擴展&#xff0c;使得私服開發者可以更加方便地搭建和管理服務器。相比于早期的 GEE、LEG、Hero 等引…

第53天:Web攻防-SQL注入數據庫類型用戶權限架構分層符號干擾利用過程發現思路

#知識點&#xff1a;(本節課了解即可&#xff09; 1、Web攻防-SQL注入-產生原理&應用因素 2、Web攻防-SQL注入-各類數據庫類型利用 一、數據庫知識&#xff1a; 1、數據庫名&#xff0c;表名&#xff0c;列名&#xff0c;數據 2、自帶數據庫&#xff0c;數據庫用戶及權限 3…

【玩轉MySQL數據字典】MySQL數據字典與常用操作指令

MySQL數據字典簡介與常用操作指令 一、數據字典簡介 數據字典是MySQL 5.7中用于存儲數據庫對象元數據的系統表。在MySQL的早期版本中&#xff0c;元數據存儲在.frm文件及其他文件里。這種存儲方式存在諸多弊端&#xff0c;例如元數據不一致問題&#xff0c;不同文件間元數據的…

如何有效判斷與排查Java GC問題

目錄 一、GC的重要性與對性能的影響 &#xff08;一&#xff09;GC對性能的影響簡要分析 1.GC暫停與應用停頓 2.GC吞吐量與資源利用率 3.GC對內存管理的作用&#xff1a;資源回收 4.GC策略與優化的選擇 &#xff08;二&#xff09;GC的雙刃劍 二、GC性能評價標準 &…

el-table(elementui)表格合計行使用以及滾動條默認樣式修改

一、el-table新增合計行以及el-table展示數據出現的問題 1. 使用合計行 el-table的屬性show-summary設為true&#xff0c;即可在表格尾部展示合計行。默認情況下&#xff0c;第一列不展示數據&#xff0c;而顯示合計二字&#xff0c;可以通過sum-text自己配置&#xff0c;其余…

olmOCR:高效精準的 PDF 文本提取工具

在日常的工作和學習中&#xff0c;是否經常被 PDF 文本提取問題困擾&#xff1f;例如&#xff1a; 想從學術論文 PDF 中提取關鍵信息&#xff0c;卻發現傳統 OCR 工具識別不準確或文本格式混亂&#xff1f;需要快速提取商務合同 PDF 中的條款內容&#xff0c;卻因工具不給力而…

云計算:虛擬化、容器化與云存儲技術詳解

在上一篇中,我們深入探討了網絡安全的核心技術,包括加密、認證和防火墻,并通過實際案例和細節幫助讀者全面理解這些技術的應用和重要性。今天,我們將轉向一個近年來迅速發展的領域——云計算。云計算通過提供按需訪問的計算資源,徹底改變了IT基礎設施的構建和管理方式。本…

免費開源抓包工具Wireshark介紹

一、Wireshark 安裝詳解 Wireshark 是一款跨平臺的網絡協議分析器&#xff0c;支持 Windows、macOS 和 Linux 等操作系統。以下分別介紹在不同操作系統上的安裝步驟&#xff0c;并詳細解釋安裝過程中的選項。 1、Windows 平臺安裝 1.下載 Wireshark 安裝包: 訪問 Wireshark…

藍橋杯備賽:炮彈

題目解析 這道題目是一道模擬加調和級數&#xff0c;難的就是調和級數&#xff0c;模擬過程比較簡單。 做法 這道題目的難點在于我們在玩這個跳的過程&#xff0c;可能出現來回跳的情況&#xff0c;那么為了解決這種情況&#xff0c;我們采取的方法是設定其的上限步數。那么…

2025年滲透測試面試題總結-奇安信安全工程師(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 奇安信安全工程師 1. MVC框架詳細說明 2. SQL注入詳細介紹 3. XSS和CSRF的區別 4. XXE漏洞原理 5. …

【阿里云】控制臺使用指南:從創建ECS到系統診斷測評

前言 隨著云計算技術的快速發展&#xff0c;越來越多的企業和開發者開始使用云服務來部署和管理應用程序。在眾多云服務提供商中&#xff0c;阿里云&#xff08;Alibaba Cloud&#xff09;憑借其強大的基礎設施和豐富的服務&#xff0c;成為了眾多用戶的首選。本文旨在介紹如何…

關于OceanBase與CDH適配的經驗分享

CDH是Cloudera早期推出的一個開源平臺版本&#xff0c;它實質上成為了Apache Hadoop生態系統內公認的安裝與管理平臺&#xff0c;專為企業級需求量身打造。CDH為用戶提供了即裝即用的企業級解決方案。通過整合Hadoop與另外十多項關鍵開源項目&#xff0c;Cloudera構建了一個功能…

電機驅動電路:單橋(H橋)與雙橋(雙H橋)詳解

一、電機驅動電路的作用 電機驅動電路通過控制電流方向和大小,實現電機的正反轉、調速及制動。常見的結構包括單橋(H橋)和雙橋(雙H橋),分別適用于不同場景。 二、單橋(H橋)驅動電路 1. 結構示意圖(文字描述) 開關元件:4個功率開關(如MOSFET或IGBT)組成橋臂,分…

[網絡爬蟲] 動態網頁抓取 — Selenium 入門操作

&#x1f31f;想系統化學習爬蟲技術&#xff1f;看看這個&#xff1a;[數據抓取] Python 網絡爬蟲 - 學習手冊-CSDN博客 0x01&#xff1a;WebDriver 類基礎屬性 & 方法 為模仿用戶真實操作瀏覽器的基本過程&#xff0c;Selenium 的 WebDriver 模塊提供了一個 WebDriver 類…

牛客周賽A:84:JAVA

鏈接&#xff1a;登錄—專業IT筆試面試備考平臺_牛客網 來源&#xff1a;牛客網 題目描述 \hspace{15pt}小紅定義一個數組的陡峭值為&#xff1a;每兩個相鄰的元素&#xff0c;差值的絕對值之和。例如&#xff0c;數組 {2,3,1}\{2,3,1\}{2,3,1} 的陡峭值是 ∣2?3∣∣3?1∣…

Cython編譯去掉符號表

在Cython編譯過程中去掉符號表&#xff08;symbol table&#xff09;可以增加生成代碼的安全性&#xff0c;使其更難被逆向工程。然而&#xff0c;需要注意的是&#xff0c;Cython本身并不直接提供一個開關來去除符號表。通常&#xff0c;這是通過編譯器和鏈接器的選項來實現的…