常用設計模式在 Spring Boot 項目中的實戰案例

引言?

在當今的軟件開發領域,Spring Boot 以其高效、便捷的特性成為構建 Java 應用程序的熱門框架。而設計模式作為軟件開發中的寶貴經驗總結,能夠顯著提升代碼的可維護性、可擴展性和可復用性。本文將深入探討幾種常用設計模式在 Spring Boot 項目中的實際應用,通過具體案例幫助讀者更好地理解和掌握這些設計模式在實際開發中的運用技巧。

一、工廠模式

場景描述?

假設我們正在開發一個電商系統,其中有多種不同類型的訂單,如普通訂單、促銷訂單、團購訂單等。每種訂單在處理時都有一些獨特的邏輯,例如促銷訂單需要計算優惠金額,團購訂單需要處理成團邏輯等。我們可以使用工廠模式來根據訂單類型創建不同的訂單處理對象。?

代碼實現

1.定義訂單處理接口

public interface OrderProcessor {void processOrder();
}

2.創建具體的訂單處理類

  • 普通訂單處理類
@Component
public class NormalOrderProcessor implements OrderProcessor {@Overridepublic void processOrder() {System.out.println("Processing normal order...");}
}
  • 促銷訂單處理類
@Component
public class PromotionOrderProcessor implements OrderProcessor {@Overridepublic void processOrder() {System.out.println("Processing promotion order, calculating discounts...");}
}

3.創建訂單工廠類

@Component
public class OrderFactory {@Autowiredprivate Map<String, OrderProcessor> orderProcessorMap;public OrderProcessor getOrderProcessor(String orderType) {return orderProcessorMap.get(orderType);}
}

4.在服務層使用工廠類

@Service
public class OrderService {@Autowiredprivate OrderFactory orderFactory;public void process(String orderType) {OrderProcessor orderProcessor = orderFactory.getOrderProcessor(orderType);if (orderProcessor != null) {orderProcessor.processOrder();} else {System.out.println("No suitable order processor found for type: " + orderType);}}
}

優勢分析?

通過工廠模式,我們將對象的創建和使用分離,當需要新增訂單類型時,只需創建新的訂單處理類并在配置中注冊,無需修改大量現有代碼,提高了系統的可擴展性。?

二、單例模式?

場景描述?

在 Spring Boot 項目中,經常會有一些資源或對象只需要一個實例,例如數據庫連接池、日志記錄器等。以日志記錄器為例,我們希望整個應用程序中只有一個日志記錄器實例,以確保日志記錄的一致性和高效性。?

代碼實現

1.使用 Spring 的注解實現單例

@Component
public class CustomLogger {private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CustomLogger.class);public void logMessage(String message) {logger.info(message);}
}

在 Spring 中,默認情況下,通過@Component注解創建的 Bean 就是單例模式。當其他組件需要使用CustomLogger時,直接注入即可。

@Service
public class SomeService {@Autowiredprivate CustomLogger customLogger;public void doSomething() {customLogger.logMessage("Service is doing something...");}
}

優勢分析?

單例模式確保了系統中特定資源或對象的唯一性,避免了資源的重復創建和浪費,提高了系統性能和資源利用率,同時也方便了對共享資源的管理和維護。?

三、代理模式?

場景描述?

假設我們有一個業務方法,在調用該方法前后需要添加一些通用的邏輯,比如權限驗證、日志記錄等。我們可以使用代理模式來實現這些橫切關注點,而無需在每個業務方法中重復編寫相同的代碼。?

代碼實現

1.定義業務接口

public interface UserService {void doBusinessLogic();
}

2.創建真實業務類

@Service
public class UserServiceImpl implements UserService {@Overridepublic void doBusinessLogic() {System.out.println("Doing business logic...");}
}

3.創建代理類

@Aspect
@Component
public class UserServiceProxy {@Around("execution(* com.example.demo.service.UserService.doBusinessLogic(..))")public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("Before business logic - checking permissions");Object result = joinPoint.proceed();System.out.println("After business logic - logging");return result;}
}

優勢分析?

代理模式將核心業務邏輯與輔助性的橫切邏輯分離,使代碼更加清晰、可維護。通過代理類,我們可以方便地在不修改原有業務代碼的基礎上添加新的功能,符合開閉原則。

四、策略模式?

場景描述?

繼續以電商系統為例,系統中有多種不同的運費計算方式,如按重量計算、按訂單金額計算、固定運費等。為了能夠靈活地切換和管理這些運費計算方式,我們可以運用策略模式。?

代碼實現

1.定義運費計算策略接口

public interface ShippingFeeStrategy {double calculateShippingFee(double weight, double orderAmount);
}

2.創建具體的運費計算策略類

  • 按重量計算運費策略類
@Component
public class WeightBasedShippingStrategy implements ShippingFeeStrategy {@Overridepublic double calculateShippingFee(double weight, double orderAmount) {// 假設每千克運費為10元return weight * 10;}
}
  • 按訂單金額計算運費策略類
@Component
public class OrderAmountBasedShippingStrategy implements ShippingFeeStrategy {@Overridepublic double calculateShippingFee(double weight, double orderAmount) {// 假設訂單金額滿100免運費,否則收取10元運費return orderAmount >= 100? 0 : 10;}
}
  • 固定運費策略類
@Component
public class FixedShippingStrategy implements ShippingFeeStrategy {@Overridepublic double calculateShippingFee(double weight, double orderAmount) {// 固定運費為5元return 5;}
}

3.創建運費計算服務,使用策略模式

@Service
public class ShippingFeeService {@Autowiredprivate Map<String, ShippingFeeStrategy> shippingFeeStrategyMap;public double calculate(String strategyType, double weight, double orderAmount) {ShippingFeeStrategy strategy = shippingFeeStrategyMap.get(strategyType);if (strategy != null) {return strategy.calculateShippingFee(weight, orderAmount);} else {throw new IllegalArgumentException("No suitable shipping fee strategy found for type: " + strategyType);}}
}

優勢分析?

策略模式使得不同的運費計算算法可以獨立變化,符合開閉原則。當需要新增運費計算方式時,只需創建新的策略類并實現接口,然后在配置中注冊即可,無需修改現有業務代碼,大大提高了系統的靈活性和可維護性。同時,不同的策略類可以被復用,提高了代碼的復用性。

補充

也可以自定義Match接口實現策略模式,大致思路如下:

1.定義Match接口

public interface Match<T> {boolean match(T var1);
}

2.業務接口繼承Match接口

public interface BusinessHandler extends Match<String> {/*** 業務執行方法** @param context 上下文*/void execute(BusinessContext context);
}

3.特定策略類實現業務接口

類一:

@Slf4j
@Component
public class ExactMatchSort implements BusinessHandler {@Setter(onMethod_ = @Autowired)BusinessService businessService;/*** {@inheritDoc}*/@Overridepublic boolean match(String value) {return RuleEnum.EXACT_MATCH.getCode().equals(value);}/*** {@inheritDoc}*/@Overridepublic void execute(BusinessContext context) {// 自定義業務邏輯businessService.exactMatch(context);}
}

類二:

@Slf4j
@Component
public class FuzzyMatchSort implements BusinessHandler {@Setter(onMethod_ = @Autowired)BusinessService businessService;/*** {@inheritDoc}*/@Overridepublic boolean match(String value) {return RuleEnum.FUZZY_MATCH.getCode().equals(value);}/*** {@inheritDoc}*/@Overridepublic void execute(BusinessContext context) {// 自定義業務邏輯businessService.fuzzyMatch(context);}
}

4.定義抽象策略管理器

public abstract class AbstractProcessorManage<T, P extends Match<T>> {private List<P> processorList;public AbstractProcessorManage() {}@Autowiredpublic void setProcessorList(List<P> processorList) {this.processorList = processorList;}public abstract String getCannotMatchMessage();public P getProcessor(T t) {for(P p : this.processorList) {if (p.match(t)) {return p;}}throw new RuntimeException(this.getCannotMatchMessage());}
}

5.定義業務策略管理器

/*** 策略管理器*/
@Component
public class BusinessManger extends AbstractProcessorManage<String, BusinessHandler> {/*** {@inheritDoc}*/@Overridepublic String getCannotMatchMessage() {return "非法的策略";}
}

6.業務流程調用

/*** 業務執行類**/
@Slf4j
@Component
public class StockFilterManager {@Setter(onMethod_ = @Autowired)private BusinessManger businessManger;private void businessExcute(BusinessContext context) {businessManger.getProcessor(context.value).execute(context);}
}

這僅是基礎架構,也可以在內層嵌套更多的設計模式,以保證代碼的可讀性與可維護性。

結論

通過以上在 Spring Boot 項目中的實戰案例,我們看到了工廠模式、單例模式、代理模式以及策略模式在不同場景下的應用及其帶來的顯著優勢。在實際項目開發中,合理運用設計模式能夠極大地提升代碼質量,使項目更加健壯、靈活和易于維護。希望讀者通過本文的學習,能夠在自己的 Spring Boot 項目中熟練運用這些設計模式,打造出更優秀的軟件系統。

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

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

相關文章

《饒議科學》閱讀筆記

《饒議科學》 《偷竊的生物學機制&#xff1a;&#xff08;有些&#xff09;小偷有藥可治》閱讀筆記 核心內容&#xff1a;探討偷竊狂&#xff08;kleptomania&#xff09;的生物學機制及相關研究。具體要點 偷竊狂的特征&#xff1a;患者不可抑制地反復偷竊個人不需要、與金錢…

從零開始搭建第一個Spring Boot應用:從入門到精通

1. Spring Boot簡介與核心概念 1.1 什么是Spring Boot&#xff1f; Spring Boot是Spring框架的一個擴展&#xff0c;它簡化了基于Spring的應用程序的初始搭建和開發過程。通過自動配置和約定優于配置的原則&#xff0c;Spring Boot讓開發者能夠快速啟動和運行項目。 通俗理解…

c# LINQ-Query01

文章目錄 查詢數據源標準查詢分兩類即時查詢已推遲流式處理非流式處理分類表聚合Aggregate<TSource,TAccumulate,TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>, Func<TAccumulate,TResult>)Aggregate<TSour…

AI惡魔之眼使用說明書

AI惡魔之眼使用說明書 產品簡介 1.1 產品介紹 AI惡魔之眼是一款具備動態視覺效果與仿生眼睛模擬功能的智能顯示產品&#xff0c;可實現以下特性&#xff1a; 真實人眼模擬&#xff1a;支持虹膜樣式變換、眨眼動畫、瞳孔縮放等動態特效&#xff0c;仿真度高自定義內容上傳&am…

CAN報文逆向工程

在沒有DBC文件的情況下解析CAN報文獲取物理信息需要逆向工程和系統分析。以下是詳細步驟&#xff1a; 1. 數據采集與基礎分析 采集原始數據&#xff1a; 使用CAN分析工具&#xff08;如PCAN-Explorer、SavvyCAN或USB-CAN適配器配套軟件&#xff09;記錄車輛在不同狀態下的CAN數…

KL散度(Kullback-Leibler Divergence):概率分布差異的量化利器

目錄 1. 什么是KL散度?關鍵特點:2. KL散度的數學公式離散分布的KL散度公式:連續分布的KL散度公式:3. KL散度的計算示例示例1:離散分布示例2:連續分布(高斯分布)4. KL散度的核心性質1. 非對稱性2. 非負性3. 與熵的關系5. KL散度與相關性的關系1. KL散度 ≠ 相關性2. 間接…

二叉樹的遍歷與構造

唉&#xff0c;好想回家&#xff0c;我想回家跟饅頭醬玩&#xff0c;想老爸老媽。如果上天再給我一次選擇的機會&#xff0c;我會選擇當一只小動物&#xff0c;或者當棵大樹也好&#xff0c;或者我希望自己不要有那么多多余的情緒&#xff0c;不要太被別人影響&#xff0c;開心…

leetcode 141. Linked List Cycle

題目描述&#xff1a; 代碼&#xff1a; 用哈希表也可以解決&#xff0c;但真正考察的是用快慢指針法。 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Soluti…

AI輔助DevOps與自動化測試:重構軟件工程效率邊界

隨著AI技術滲透至軟件開發生命周期&#xff0c;DevOps與自動化測試領域正經歷顛覆性變革。本文系統性解析AI在需求分析、測試用例生成、部署決策、異常檢測等環節的技術實現路徑&#xff0c;結合微軟Azure DevOps、Tesla自動駕駛測試等典型場景&#xff0c;探討AI如何突破傳統效…

5月7號.

flex布局: 表單標簽: 表單標簽-表單項:

【AI面試準備】中文分詞與實體抽取技術詳解

分詞&#xff0c;詞性標準 目錄 一、分詞與詞性標注1. **分詞&#xff08;Word Segmentation&#xff09;**2. **詞性標注&#xff08;Part-of-Speech Tagging&#xff09;** 二、實體抽取&#xff08;Named Entity Recognition, NER&#xff09;1. **實體類型示例**2. **輸出…

【AI落地應用實戰】Amazon Bedrock 零門檻使用 DeepSeek-R1:在 Amazon Bedrock 上部署與調用的完整實踐指南

隨著大語言模型&#xff08;LLM&#xff09;技術的快速發展&#xff0c;企業和開發者對具備更強理解與生成能力的模型需求也愈加旺盛。DeepSeek-R1 作為 DeepSeek 公司推出的一款強大開源模型&#xff0c;不僅在多項評測中表現優異&#xff0c;更具備出色的推理能力和長文本處理…

阿里云平臺與STM32的物聯網設計

基于阿里云平臺與STM32的物聯網設計方案可結合硬件選型、通信協議、云端配置及功能實現等多個維度進行設計。以下是綜合多個參考案例的詳細設計方案&#xff1a; 一、硬件選型與架構設計 主控芯片選擇 STM32系列&#xff1a;推薦使用STM32F103&#xff08;如STM32F103ZET6、STM…

IBM BAW(原BPM升級版)使用教程Toolkit介紹

本部分為“IBM BAW&#xff08;原BPM升級版&#xff09;使用教程系列”內容的補充。 一、系統Toolkit 在 IBM Business Automation Workflow (BAW) 中&#xff0c;System Toolkit 是一組預先定義和配置好的工具、功能和組件&#xff0c;旨在幫助流程設計者和開發人員快速構建…

力扣-hot100 (矩陣置零)

73. 矩陣置零 中等 給定一個 *m* x *n* 的矩陣&#xff0c;如果一個元素為 0 &#xff0c;則將其所在行和列的所有元素都設為 0 。請使用 原地 算法。 示例 1&#xff1a; 輸入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 輸出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示…

安裝并運行第一個Spark程序

安裝并運行第一個Spark程序需要完成以下步驟&#xff1a;安裝Java和Spark&#xff0c;配置環境變量&#xff0c;編寫并運行Spark程序。以下是詳細的教程&#xff1a; 1. 安裝Java Spark需要Java運行環境&#xff08;JRE&#xff09;或Java開發工具包&#xff08;JDK&#xff…

Python Selenium爬蟲功能使用介紹

本文介紹python selenium 爬蟲的功能以及使用 1. 基礎核心功能 瀏覽器控制 from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager# 自動管理瀏覽器驅動 driver webdriver.Chro…

Cloudera CDP 7.1.3 主機異常關機導致元數據丟失,node不能與CM通信

問題描述 plaintext ERROR Could not load post-deployment data from /var/run/cloudera-scm-agent/process/ccdeploy_hadoop-conf_etchadoopconf.cloudera.yarn_-8903374259073700469 IOError: [Errno 2] No such file or directory: /var/run/cloudera-scm-agent/proce…

Nginx安全防護與HTTPS部署

目錄 Nginx 隱藏版本號 限制危險請求方法 請求限制&#xff08;CC攻擊防御&#xff09; 壓力測試 防盜鏈 防止防盜鏈 動態黑名單 自動添加黑名單 HTTPS配置 HTTPS 概念 安全通信的四大原則 HTTPS的幾種加密方式 nginx https的作用 Nginx 隱藏版本號 &#xff01;&#xff01;&a…

C++類對象的隱式類型轉換和編譯器返回值優化

文章目錄 前言1. 隱式類型轉換1.1 單參數的隱式類型轉換1.2 多參數的隱式類型轉換1.3 explicit關鍵字 2. 編譯器的優化2.1 普通構造優化2.2 函數傳參優化2.3 函數返回優化 前言 在類與對象的學習過程中&#xff0c;一定會對隱式類型轉換這個詞不陌生。對于內置類型而言&#x…