【設計模式】-策略模式:優雅處理條件邏輯

Java 策略模式之優雅處理條件邏輯

前言

在軟件開發中,我們經常會遇到根據不同的條件執行不同邏輯的情況。這時,策略模式是一種常用的設計模式,能夠使代碼結構清晰、易于擴展和維護。

本文將詳細介紹策略模式的概念及其在Java中的應用,通過代碼示例演示如何使用策略模式來處理條件邏輯,以達到代碼設計的靈活性和可維護性。

什么是策略模式?

策略模式(Strategy Pattern)是一種行為型設計模式,它允許在運行時根據不同的條件選擇不同的算法或行為。它將每個條件分支的邏輯封裝在一個獨立的類中,使得它們可以獨立變化,互不影響。

策略模式使用了面向對象的封裝、繼承和多態等特性,使得代碼具備高內聚低耦合的特點。通過將條件邏輯的變化封裝到策略類中,不僅可以簡化代碼的編寫,還能提高代碼的可維護性、可擴展性和可重用性。

實現原理

策略模式實現原理主要涉及以下幾個部分:

  1. 策略接口(Strategy Interface):定義了各個策略類必須實現的方法。這個接口將算法邏輯進行抽象,并定義了統一的方法或行為。

  2. 策略類(Concrete Strategies)實現(implements)策略接口,并封裝了具體的算法邏輯。每個具體策略類都是獨立的且具體邏輯互相隔離,分別實現不同的算法。

  3. 上下文類(Context):包含一個策略接口成員變量,并在運行時根據需要使用具體的策略類。上下文類通過策略接口與具體的策略類進行交互,并調用策略類中定義的算法。上下文主要用于決定使用哪個策略類

使用策略模式的關鍵在于上下文類與策略類之間的耦合解耦。上下文類通過策略接口具體的策略類進行交互,而不是直接依賴于具體的策略類。這樣,在需要更換或增加新的策略時,只需要修改上下文類的代碼,而不需要修改客戶端的代碼,從而實現了代碼的靈活性和可擴展性。

示例:支付系統中的策略模式

假設我們正在開發一個支付系統,其中有多種支付方式,包括現金支付、信用卡支付和支付寶支付。不同的支付方式計算價格的邏輯可能有所不同,我們可以使用策略模式來實現這一需求。

首先,我們定義一個策略接口PaymentStrategy,它聲明了一個名為calculatePrice的方法用于計算價格:

1.定義策略接口

// 定義策略接口
public interface PaymentStrategy {double calculatePrice(double price);
}

2.定義策略類,實現PaymentStrategy接口的方法:

// 策略類:使用現金支付
public class CashPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 這里是現金支付的價格計算邏輯return price * 0.9; // 打9折}
}// 策略類:使用信用卡支付
public class CreditCardPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 這里是信用卡支付的價格計算邏輯return price * 1.2; // 加收20%手續費}
}// 策略類:使用支付寶支付
public class AlipayPaymentStrategy implements PaymentStrategy {@Overridepublic double calculatePrice(double price) {// 這里是支付寶支付的價格計算邏輯return price * 0.95; // 打95折}
}

3.接下來,我們創建一個上下文類PaymentContext,用于將不同的策略類進行封裝,外部調用時只需關注該上下文類:

// 上下文類
public class PaymentContext {private PaymentStrategy paymentStrategy;public PaymentContext(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}public double calculate(double price) {return paymentStrategy.calculatePrice(price);}
}

4.最后,我們可以通過實例化不同的策略類對象,并將其傳入PaymentContext中,然后調用calculate方法進行價格計算:

public class Main {public static void main(String[] args) {PaymentStrategy cashPayment = new CashPaymentStrategy();PaymentContext cashPaymentContext = new PaymentContext(cashPayment);double cashPrice = cashPaymentContext.calculate(100.0);System.out.println("現金支付價格:" + cashPrice);PaymentStrategy creditCardPayment = new CreditCardPaymentStrategy();PaymentContext creditCardPaymentContext = new PaymentContext(creditCardPayment);double creditCardPrice = creditCardPaymentContext.calculate(100.0);System.out.println("信用卡支付價格:" + creditCardPrice);PaymentStrategy alipayPayment = new AlipayPaymentStrategy();PaymentContext alipayPaymentContext = new PaymentContext(alipayPayment);double alipayPrice = alipayPaymentContext.calculate(100.0);System.out.println("支付寶支付價格:" + alipayPrice);}
}

運行上述代碼可以得到如下輸出:

現金支付價格:90.0
信用卡支付價格:120.0
支付寶支付價格:95.0

在以上示例中,我們定義了三種不同的支付策略:現金支付信用卡支付支付寶支付,它們分別實現了PaymentStrategy接口并實現了自己的價格計算邏輯。通過創建PaymentContext對象并傳入不同的支付策略,我們可以調用calculate方法獲得相應的價格結果。

總結

????????通過策略模式,我們可以優雅地處理條件邏輯,將各個條件分支的邏輯封裝到獨立的策略類中,使得代碼結構清晰、易于擴展和維護。

????????策略模式適用于需求中存在多個條件分支,并且這些條件分支的邏輯會隨時變化的情況。使用策略模式能夠提高代碼的可讀性和可維護性,同時也符合面向對象設計原則中的開閉原則。

????????在實際開發中,我們可以根據具體需求靈活運用策略模式,幫助我們構建出高質量、易于維護的代碼。

參考資料:

  • 《Head First 設計模式》

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

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

相關文章

flume系列之:監控Systemctl托管的flume agent組

flume系列之:監控Systemctl托管的flume agent組 一、需求背景二、相關技術博客三、遠程登陸flume機器四、發送飛書告警五、監控flume agent組狀態一、需求背景 flume接kafka集群,一個kafka集群對應一個flume agent組,會把一組flume agent用systemctl托管每接一個kafka集群會…

pytest 編寫規范

一、pytest 編寫規范 1、介紹 pytest是一個非常成熟的全功能的Python測試框架,主要特點有以下幾點: 1、簡單靈活,容易上手,文檔豐富;2、支持參數化,可以細粒度地控制要測試的測試用例;3、能夠…

差分升級在物聯網水表上的實現與應用(學習)

摘要 當越來越多的物聯網水表加入抄表系統后,實現了水表數據的信息化,并且當水表終端需要技術更新時,通過網絡方式來升級產品可以高效修復設備面臨的問題,減少用戶損失,降低維護成本,但同時也對有限的網絡…

遍歷集合List的五種方法以及如何在遍歷集合過程中安全移除元素

一、遍歷集合List的五種方法 測試數據 List<String> list new ArrayList<>(); list.add("A");list.add("B");list.add("C");1. 普通for循環 普通for循環&#xff0c;通過索引遍歷 for (int i 0; i < list.size(); i) {Syst…

form中表單切換,導致 relus 中的事件無法觸發,原因:頁面切換不要一直切換DOM,會導致問題,需要都顯示出來

修改前&#xff0c;因為重復渲染DOM導致綁定rules失效 修改前代碼使用 computed 計算出渲染的DOM&#xff0c;影響rules事件<el-formref"form"inline:model"billDetailCopy":rules"rules"size"small"label-position"right&quo…

selenium官網文檔閱讀總結(day 4)

1.selenium的工作原理 selenium的工作原理涉及以下主要組件和步驟&#xff1a; &#xff08;1&#xff09;WebDriver:這是selenium的核心組件&#xff0c;它是一個用于控制瀏覽器的API。WebDriver提供了許多方法&#xff0c;用于在瀏覽器中模擬用戶操作。不同的瀏覽器需要相應…

掌握Python的X篇_39_繼承

本篇將會是本專欄關于python基本語法的最后一個知識點&#xff0c;后期將會談python&#xff0c;就會介紹使用python專題&#xff0c;例如&#xff1a;做爬蟲、有架構的網站。 文章目錄 1. 為什么需要繼承2. 繼承的基本概念3. python中繼承的基礎語法4. 總結 1. 為什么需要繼承…

NLP語言模型概覽

語言模型結構分類 Encoder-Decoder&#xff08;Transformer&#xff09;: Encoder 部分是 Masked Multi-Head Self-Attention&#xff0c;Decoder 部分是 Casual Multi-Head Cross-Attention 和 Casual Multi-Head Self-Attention 兼具。比如T5&#xff0c;BART&#xff0c;MA…

騰訊云輕量服務器和云服務器的CPU處理器有差別嗎?

騰訊云輕量應用服務器和CVM云服務器的CPU處理器性能有差別嗎&#xff1f;創建輕量應用服務器時不支持指定底層物理服務器的CPU型號&#xff0c;騰訊云將隨機分配滿足套餐規格的物理CPU型號&#xff0c;通常優先選擇較新代次的CPU型號。而云服務器CVM的CPU處理器型號、主頻都是有…

JAVA設計模式----原型設計模式

文章目錄 一、簡介二、實現方式三、原型模式的注意事項淺拷貝與深拷貝淺拷貝深拷貝一、簡介 定義:用原型實例指定創建對象的種類,并通過拷貝這些原型創建新的對象。 類型:創建類模式 類圖: 原型模式主要用于對象的復制,它的核心是就是類圖中的原型類Prototype。Protot…

下載程序到西門子PLC

更多關于西門子S7-200PLC內容請查看&#xff1a;西門子200系列PLC學習課程大綱 下載西門子200PLC程序分以下兩步&#xff1a; 一.編譯程序 1. 如下圖1-1所示&#xff0c;使用PPI電纜將PLC和電腦連接上&#xff0c;注意筆記本使用USB轉PPI電纜&#xff0c;連接保證給PLC單獨供…

Linux(進程間通信詳解)

進程間通信&#xff0c;顧名思義&#xff0c;就是進程與進程之間互通信交流&#xff0c;OS保證了各進程之間相互獨立&#xff0c;但這不意味著進程與進程之間就互相隔離開&#xff0c;在不少的情況下&#xff0c;進程之間需要相互配合共同完成某項6任務&#xff0c;這就要求各進…

怎樣學會單片機

0、學單片機首先要明白&#xff0c;一個單片機啥也干不了&#xff0c;學單片機的目的是學習怎么用單片機驅動外部設備&#xff0c;比如數碼管&#xff0c;電機&#xff0c;液晶屏等&#xff0c;這個需要外圍電路的配合&#xff0c;所以學習單片機在這個層面上可以等同為學習單片…

JVM:運行時數據區域(白話文)

最近有時間在看一本<深入了解Java虛擬機>的書籍&#xff0c;這本書是一個中國人&#xff0c;名叫周志明的人寫的。相比于其他翻譯過來的技術書籍&#xff0c;這本書還是挺通俗易懂的。先前有和彬哥在聊&#xff0c;他說如果是自己一個人看的話會很枯燥&#xff0c;很難堅…

雙端列表 —— Deque 接口概述,使用ArrayDeque實現隊列和雙端隊列數據結構

Deque接口簡介 Deque譯為雙端隊列&#xff0c;在雙向都能作為隊列來使用&#xff0c;同時可用作棧。Deque接口的方法是對稱成比例的。 Deque接口繼承Queue接口&#xff0c;因此具有Queue&#xff0c;Collection&#xff0c;Iterable的方法屬性。 雙端隊列的工作原理 在常規隊…

前端架構師的能力要求:打造可靠、靈活和可擴展的Web應用

隨著互聯網技術迅猛發展&#xff0c;現代Web應用程序變得越來越復雜且功能強大。作為一名前端架構師&#xff0c;在這個快節奏且競爭激烈的環境中&#xff0c;你需要具備廣泛而深入地技術知識&#xff0c;并且有能力設計、開發和維護高度可靠、靈活和可擴展性強的Web應用。 深入…

前端發送請求和后端springboot接受參數

0.xhr、 ajax、axios、promise和async/await 和http基本方法 xhr、 ajax、axios、promise和async/await都是異步編程和網絡請求相關的概念和技術&#xff01; xhr&#xff1a;XMLHttpRequest是瀏覽器提供的js對象&#xff08;API&#xff09;&#xff0c;用于請求服務器資源。…

百度百科詞條要如何才能符合要求,上百度百科平臺

百度百科詞條對于內容的審核一直是比較嚴格的&#xff0c;因此必須符合百度百科詞條平臺規則&#xff0c;才能夠上百度百科平臺&#xff0c;下面洛希愛做百科網和大家分享百度百科詞條上平臺的內容和規則要求。 1&#xff0c; 首先&#xff0c;百度百科需要知道的是我們要以公益…

Java基礎集合框架學習(上)

文章目錄 初識基礎框架為什么使用集合框架集合框架的繼承關系ArrayList入門案例單元測試和增刪改查單元測試的注意事項LinkedList入門案例ArrayList底層是數組LinkedList底層是鏈表ArrayList和LinkedList選型ArrayList存放DOG對象 初識基礎框架 Java基礎集合框架是Java編程語言…

jvm里的內存溢出

目錄 堆溢出 虛擬機棧和本地方法棧溢出&#xff08;棧溢出很少出現&#xff09; 方法區和運行時常量池溢出 本機內存直接溢出&#xff08;實際中很少出現、了解即可&#xff09; 堆溢出 堆溢出&#xff1a;最常見的是大list&#xff0c;list里面有很多元素 堆溢出該怎么解決…