精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何在Java中使用Spring Boot設計模式

譯文 精選
開發 前端
在軟件開發領域,隨著項目規模的不斷擴大和復雜度的日益提升,如何確保代碼的組織性、可維護性和可擴展性成為了開發者們面臨的重大挑戰。

譯者 | 劉濤

審校 | 重樓

在軟件開發領域,隨著項目規模的不斷擴大和復雜度的日益提升,如何確保代碼的組織性、可維護性和可擴展性成為了開發者們面臨的重大挑戰。為了應對這一挑戰,設計模式應運而生并成為發揮作用的關鍵所在。它為常見的軟件設計難題提供了經過實踐檢驗的、可重復使用的解決方案,從而能夠顯著提升編寫代碼的效率并更易管理。

在本指南當中,我們將會深入剖析一些備受歡迎的設計模式,并詳盡闡述如何在Spring Boot框架里有效地實施這些模式。當完成本指南的學習之后,不但會對這些設計模式的概念有著深刻的理解,還能夠信心十足地將它們融入到自己的項目之中。

目錄

  • 設計模式簡介
  • 如何搭建Spring Boot項目
  • 什么是單例模式?
  • 什么是工廠模式?
  • 什么是策略模式?
  • 什么是觀察者模式?
  • 如何使用Spring Boot的依賴注入
  • 最佳實踐與優化建議
  • 結論與要點總結

設計模式簡介

設計模式是針對軟件設計中常見問題的可用解決方案,是從成功項目中提煉出的最佳實踐模板。雖然設計模式具有跨語言的適用性,不局限于某一種特定的編程語言。但因其基于面向對象的設計原則,在Java等具有強大面向對象特性的語言的使用發揮的作用尤為強大

在本指南中,我們將涵蓋如下內容:

  • 單例模式:確保一個類僅有一個實例。
  • 工廠模式:在不指明具體類的情形下創建對象。
  • 策略模式:許程序在運行時選取算法。
  • 觀察者模式:構建發布-訂閱關系。我們不只會講解這些模式的工作原理,還會探討如何在Spring Boot框架下將它們應用于實際應用程序當中。

如何搭建Spring Boot項目

在我們深入研究這些模式之前,先來搭建一個Spring Boot項目:

儲備知識

確定你已經掌握:

  • Java 11+
  • Maven
  • Spring Boot CLI (optional)
  • Postman or curl (for testing)

項目初始化

可以使用Spring Initializr快速創建一個Spring Boot項目:

curl https://start.spring.io/starter.zip \
-d dependencies=web \
-d name=DesignPatternsDemo \
-d javaVersion=11 -o design-patterns-demo.zip
unzip design-patterns-demo.zip
cd design-patterns-demo

什么是單例模式?

單例模式Singleton pattern是一種設計模式,它確保一個類只有一個實例,并提供一個全局訪問點來訪問該實例。該模式通常用于日志記錄、配置管理或數據庫連接等服務。

如何在Spring Boot中實現單例模式

Spring Boot中的BeanBean 是由Spring容器管理的對象實例默認都是單例的,這意味著Spring會自動管理這些Bean的生命周期,以確保只存在一個實例。然而,了解單例模式在底層是如何工作的仍然很重要,尤其是當沒有使用Spring管理的Bean或需要對實例管理進行更多控制時

我們通過手動實現單例模式來演示如何在應用程序中控制單個實例的創建。

第1步:創建一個LoggerService類

在這個示例場景中,我們將使用單例模式創建一個簡單的日志服務。目標是確保應用程序的所有部分都共享并使用一個統一的日志記錄實例

public class LoggerService {
 // The static variable to hold the single instance
 private static LoggerService instance;
// Private constructor to prevent instantiation from outside
 private LoggerService() {
 // This constructor is intentionally empty to prevent other classes from creating instances
 }
// Public method to provide access to the single instance
 public static synchronized LoggerService getInstance() {
 if (instance == null) {
 instance = new LoggerService();
 }
 return instance;
 }
// Example logging method
 public void log(String message) {
 System.out.println("[LOG] " + message);
 }
}
  • 靜態變量(實例):這個變量持有LoggerService類的唯一實例。
  • 私有構造函數:構造函數被標記為私有,以防止其他類直接創建新的實例。
  • 同步getInstance()方法:該方法被同步以確保線程安全,即使多個線程同時嘗試訪問它,程序也只會創建一個實例。
  • 延遲初始化:實例只有在首次被請求時才被創建(延遲初始化),這種方式在內存使用方面非常高效。

實際應用:單例模式通常用于需要共享資源的場景,如日志記錄、配置設置或管理數據庫連接等,在這些情況下,通過控制訪問來確保整個應用程序只使用一個實例,以避免資源浪費和潛在沖突

第2步:在Spring Boot控制器中使用單例模式

現在,讓我們看看如何在Spring Boot控制器中使用已經創建好的LoggerService單例。這個控制器會公開一個端點(endpoint),每當有請求訪問該端點時,就會通過LoggerService記錄一條消息。

import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;
 
@RestControllerpublic class LogController {
 
@GetMapping("/log") public ResponseEntity<String> logMessage() { // Accessing the Singleton instance of LoggerService LoggerService logger = LoggerService.getInstance(); logger.log("This is a log message!"); return ResponseEntity.ok("Message logged successfully"); }}


  • GET 端點:我們創建了一個/log端點,當對該端點進行訪問時,會使用LoggerService記錄一條消息。
  • 單例使用:我們并未創建LoggerService的新實例,而是調用 getInstance()方法,以此確保每次所使用的都是同一個實例。
  • 響應:在記錄消息之后,端點會返回一個表示成功的響應。

第3步:測試單例模式

現在,讓我們使用Postman(一款功能強大的 API開發工具,主要用于接口測試、接口開發和接口文檔生成等場景)或瀏覽器測試此端點:

GET http://localhost:8080/log

預期輸出:

  • 控制臺日志:[LOG] This is a log message!
  • HTTP響應:Message logged successfully

可以多次調用這個端點,通過觀察日志輸出的連續性,可以驗證每次調用時使用的都是同一個LoggerService實例。

單例模式在實際環境中的應用場景

以下實際環境中的應用程序可能使用單例模式的情況:

  1. 配置管理:確保應用程序始終使用一組統一的配置設定,尤其是在這些設定是從文件或者數據庫加載的情況下。這有助于維持應用程序在不同環境中的一致性,避免因配置差異導致的運行問題。
  2. 數據庫連接池:要對數量有限的數據庫連接的訪問進行管控,確保整個應用程序能夠共享同一個連接池。
  3. 緩存:維護一個單獨的緩存實例,防止數據出現不一致的情況。
  4. 日志服務:如本例所示使用單一的日志服務來對應用程序不同模塊的日志輸出進行集中式管理。

關鍵要點

  • 單例模式是一種簡潔的設計方案,旨在確保一個類只有一個實例被創建。
  • 倘若多個線程正在訪問單例,那么線程安全性就極為關鍵,這便是為何在示例中使用synchronized關鍵字來保障線程安全
  • Spring Boot框架中,Bean默認是單例,然而了解如何手動實現它有助特定場景下獲取更多的控制權。以上就是對單例模式的實現和應用的介紹。接下來,我們將一起探索工廠模式,看看它如何幫助簡化對象的創建過程

什么是工廠模式?

工廠模式(Factory Pattern)支持在不明確指定具體類的情況下創建對象。當需要根據某些輸入來實例化不同類型的對象時,這個模式非常有用。

如何在Spring Boot中實現工廠模式

需要根據一定的標準來創建對象,同時又希望將對象的創建流程與主應用程序邏輯相分離時,工廠模式就顯得尤為重要。

為了更直觀地理解這一點,本節中我們設想這樣一個場景:構建一個NotificationFactory,用于發送電子郵件或短信通知。如果預見到未來可能會增加更多類型的通知方式,比如推送通知或應用內警告,并且希望在添加這些新功能時無需改動現有的代碼,那么工廠模式就能派上大用場。

步驟1:創建Notification界面

首先,我們需要定義一個公共接口,這個接口能被所有類型的通知(如電子郵件、短信等)實現,旨在確保每一種通知類型都具備一個統一的send()方法,從而保證在使用上的一致性和互換性。

public interface Notification {
 void send(String message);
}
  • 目的:Notification接口為發送通知的行為定義了一個明確的契約任何實現此接口的類都必須為send()方法提供實現。
  • 可擴展性:采用接口的設計方式,為應用程序的未來擴展提供了極大的便利。在便捷的擴展應用程序以包含其他類型的通知的同時,而無需修改現有代碼。

步驟2:實現EmailNotification和SMSNotification

接下來,讓我們實現兩個具體的類,一個用于發送電子郵件,另一個用于發送短信。

public class EmailNotification implements Notification {
 @Override
 public void send(String message) {
 System.out.println("Sending Email: " + message);
 }
}
public class SMSNotification implements Notification {
 @Override
 public void send(String message) {
 System.out.println("Sending SMS: " + message);
 }
}

步驟3:創建一個NotificationFactory

NotificationFactor類負責根據指定的類型創建Notification實例。這種設計的好處在于,它確保NotificationController不需要了解對象創建的具體細節

public class NotificationFactory {
 public static Notification createNotification(String type) {
 switch (type.toUpperCase()) {
 case "EMAIL":
 return new EmailNotification();
 case "SMS":
 return new SMSNotification();
 default:
 throw new IllegalArgumentException("Unknown notification type: " + type);
 }
 }
}
  • 工廠方法(createNotification()):工廠方法(Factory Method)接收一個字符串(類型)作為輸入參數,并返回相應通知類的實例。
  • Switch語句:Switch語句根據輸入參數選擇適當的通知類型。
  • 異常處理:如果客戶端傳入的類型字符串無法被識別,則工廠方法會拋出IllegalArgumentException異常。這確保無效類型能夠被系統及時捕獲和處理。

為什么使用工廠模式?

  • 解耦:工廠模式的核心優勢之一在于它實現了對象創建與業務邏輯的解耦。這使得代碼更加模塊化,從而更易于維護。
  • 可擴展性:如果想要添加一種新的通知類型,只需更新工廠方法即可,而無需更改控制器邏輯。這種設計方式使得代碼更加靈活,能夠輕松應對未來可能出現的新需求。

步驟4:在 Spring Boot 控制器中使用工廠模式

現在,我們要創建一個Spring Boot控制器,以此將之前的所有內容整合起來。這個控制器會運用NotificationFactory,按照用戶的請求來發送通知。通過這樣的方式,我們能夠把之前關于通知創建和處理的各個部分組合成一個完整的、可運行的功能模塊,在Spring Boot框架下實現根據用戶需求進行通知發送的功能。

import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;
@RestController
public class NotificationController {
@GetMapping("/notify")
 public ResponseEntity<String> notify(@RequestParam String type, @RequestParam String message) {
 try {
 // Create the appropriate Notification object using the factory
 Notification notification = NotificationFactory.createNotification(type);
 notification.send(message);
 return ResponseEntity.ok("Notification sent successfully!");
 } catch (IllegalArgumentException e) {
 return ResponseEntity.badRequest().body(e.getMessage());
 }
 }
}

GET 端點 (/notify):

  • 控制器公開了一個 /notify 端點,該端點接受兩個查詢參數:type(值為 "EMAIL" 或 "SMS")和 message。
  • 使用 NotificationFactory 來創建相應的通知類型,并發送消息。

錯誤處理:如果提供了無效的通知類型,控制器會捕獲 IllegalArgumentException 異常,并返回400 Bad Request響應。

步驟5:測試工廠模式

讓我們使用 Postman 或瀏覽器測試端點

1.發送電子郵件通知

GET http://localhost:8080/notify?type=email&message=Hello%20Email

輸出:Sending Email: Hello Email

2.發送SMS通知

GET http://localhost:8080/notify?type=sms&message=Hello%20SMS

輸出:Sending SMS: Hello SMS

3.使用無效類型進行測試

GET http://localhost:8080/notify?type=unknown&message=Test

輸出:Bad Request: Unknown notification type: unknown

工廠模式在實際環境中的應用場景

Factory 模式在以下情況下特別有用:

  1. 動態對象創建:當你需要根據用戶輸入來創建對象時,例如,在發送不同類型的通知、生成各種格式的報告或處理不同的支付方式等場景中,工廠模式可以根據實際需求動態地創建相應的對象。
  2. 對象創建的解耦:通過使用工廠模式可以將主要業務邏輯與對象創建邏輯相分離,從而提高代碼的可維護性。
  3. 可擴展性:工廠模式還帶來了易于擴展的好處。例如,在需要支持新的通知類型時,只需添加一個新的實現Notification接口的類,并升級工廠模式即可,而無需修改現有的代碼。這使得應用程序能夠輕松地適應新的需求和變化。

什么是策略模式?

需要在多個算法或行為之間實現動態的切換時,策略模式無疑是一個極佳的選擇。此模式支持定義一系列算法,并將每個算法都封裝在獨立的類中,從而在運行時能夠輕松地在這些算法之間進行切換。這種特性在需要根據特定條件選擇算法時尤為有用,它能夠幫助保持代碼的清晰、模塊化和靈活性。

實際應用例:設想一個電子商務系統,它需要能夠支持多種支付方式,比如信用卡支付、PayPal支付或銀行轉賬等。通過巧妙地運用策略模式,可以非常便捷地添加或修改支付方式,而無需對現有的代碼進行任何改動。這種設計方式能夠確保在引入新功能或對現有功能進行更新時,的應用程序依然能夠保持良好的可擴展性和可維護性。

接下來,我們將通過一個Spring Boot的實例來具體展示策略模式的應用。在這個實例中,我們將使用信用卡支付和PayPal支付兩種策略來處理支付事務。

步驟1:定義PaymentStrategy接口

首先,我們需要定義一個通用的接口,這個接口將作為所有支付策略的基礎。這個接口會聲明一個支付方法,具體的支付策略類將會實現這個方法。

public interface PaymentStrategy {
 void pay(double amount);
}

PaymentStrategy接口為所有的支付策略定義了一個統一的規范可以確保實現了這個接口的支付策略步調一致。

步驟2:實現支付策略

為信用卡支付和PayPal支付分別創建具體的實現類。

public class CreditCardPayment implements PaymentStrategy {
 @Override
 public void pay(double amount) {
 System.out.println("Paid $" + amount + " with Credit Card");
 }
}

public class PayPalPayment implements PaymentStrategy {
 @Override
 public void pay(double amount) {
 System.out.println("Paid $" + amount + " via PayPal");
 }
}

每個類都會實現PaymentStrategy接口中聲明的pay()方法,并且這個方法會包含各自支付方式特有的行為邏輯

步驟3:在控制器中應用策略

創建一個控制器(controller),用于根據用戶的輸入來動態地選定支付策略。

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PaymentController {

@GetMapping("/pay")
 public ResponseEntity<String> processPayment(@RequestParam String method, @RequestParam double amount) {
 PaymentStrategy strategy = selectPaymentStrategy(method);
 if (strategy == null) {
 return ResponseEntity.badRequest().body("Invalid payment method");
 }
 strategy.pay(amount);
 return ResponseEntity.ok("Payment processed successfully!");
 }

private PaymentStrategy selectPaymentStrategy(String method) {
 switch (method.toUpperCase()) {
 case "CREDIT": return new CreditCardPayment();
 case "PAYPAL": return new PayPalPayment();
 default: return null;
 }
 }
}

服務端點會接收支付方法和支付金額作為查詢參數,并根據這些參數選擇合適的支付策略來處理支付請求。

步驟4:測試端點

1.信用卡支付

GET http://localhost:8080/pay?method=credit&amount=100

輸出:Paid $100.0 with Credit Card

2.PayPal支付

GET http://localhost:8080/pay?method=paypal&amount=50

輸出:Paid $50.0 via PayPal

3.無效方法

GET http://localhost:8080/pay?method=bitcoin&amount=25

輸出:Invalid payment method

策略模式的應用場景

  • 支付處理:在不同支付網關之間動態切換。
  • 排序算法:根據數據規模選擇最佳的排序方法。
  • 文件導出:以多種格式(PDF、Excel、CSV)導出報告。

關鍵要點

  • 策略模式能夠使代碼保持高度的模塊化,并嚴格遵循開閉原則,即在不修改現有代碼的基礎上擴展新功能。
  • 當需要添加新的策略時,只需簡單地創建一個新的類,該類實現PaymentStrategy接口即可這種設計方式使得策略模式的擴展性極強,能夠輕松應對未來可能出現的新需求。
  • 策略模式非常適合那些需要在運行時根據具體情況靈活選擇算法的場景。通過定義一系列算法,并將它們封裝起來,策略模式使得算法可以獨立于使用它的客戶端而變化,從而提高了代碼的可維護性和可擴展性。
    接下來,我們將探索觀察者模式( observer pattern),它最適用的場景是處理事件驅動型架構。

什么是觀察者模式?

觀察者模式極為適用于一種場景:當一個對象(即主題)的狀態發生變化時,需要通知多個其他對象(即觀察者)。此模式在事件驅動系統中尤為適用,因為它能夠在不造成組件間緊密耦合的情況下,將更新信息推送至各個組件。觀察者模式有助于構建清晰的系統架構,特別是當系統的不同部分需要獨立響應變化時,其優勢尤為明顯。

在實際應用中,觀察者模式廣泛應用于需要發送通知或警報的系統,例如聊天應用程序或股票價格跟蹤器。這些系統需要實時向用戶推送更新信息。通過采用觀察者模式,可以輕松地添加或刪除通知類型,而無需對核心邏輯進行大幅修改。

為了更直觀地展示如何在Spring Boot中實現觀察者模式,我們將構建一個簡單的通知系統示例。該系統在用戶注冊時,會觸發電子郵件和短信通知。通過這一示例,我們將展示如何利用觀察者模式,實現用戶注冊事件的通知分發,同時保持系統架構的清晰與靈活。

步驟1:創建observer接口

我們首先需要定義一個通用接口,這個接口將被所有的觀察者實現,能夠以一種統一的方式接收通知并作出相應的反應。

public interface Observer {
 void update(String event);
}

該接口充當了一個合約的角色,它明確要求所有觀察者對象都必須實現一個名為 update() 的方法。每當主題發生變化時,該方法就會觸發。

步驟2:實現EmailObserver和SMSObserver

接下來,我們創建Observer接口的兩個具體實現,分別處理電子郵件和短信通知。

EmailObserver類

public class EmailObserver implements Observer {
 @Override
 public void update(String event) {
 System.out.println("Email sent for event: " + event);
 }
}

EmailObserver負責在接到事件通知時發送電子郵件通知

SMSObserver類

public class SMSObserver implements Observer {
 @Override
 public void update(String event) {
 System.out.println("SMS sent for event: " + event);
 }
}

SMSObserver類負責在收到通知時處理發送SMS(短消息服務)通知。

步驟3:創建UserService類(主題)

我們將創建一個UserService類作為觀察者模式中的“主題”,該類在用戶注冊時會主動通知所有已注冊的觀察者(如郵件服務、短信服務等),告知它們用戶注冊的信息。

import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserService {
 private List<Observer> observers = new ArrayList<>();
// Method to register observers
 public void registerObserver(Observer observer) {
 observers.add(observer);
 }
// Method to notify all registered observers of an event
 public void notifyObservers(String event) {
 for (Observer observer : observers) {
 observer.update(event);
 }
 }
// Method to register a new user and notify observers
 public void registerUser(String username) {
 System.out.println("User registered: " + username);
 notifyObservers("User Registration");
 }
}
  • 觀察者列表:跟蹤所有已注冊的觀察者。
  • registerObserver()方法:將新的觀察者添加到列表中。
  • notifyObservers()方法:當事件發生時,通知所有已注冊的觀察者。
  • registerUser()方法:注冊新用戶,并觸發對所有觀察者的通知。

步驟4:在控制器中使用觀察者模式

最后,我們將創建一個Spring Boot控制器,以公開一個用于用戶注冊的端點。該控制器將在UserService中注冊EmailObserver和SMSObserver。

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class UserController {
 private final UserService userService;
public UserController() {
 this.userService = new UserService();
 // Register observers
 userService.registerObserver(new EmailObserver());
 userService.registerObserver(new SMSObserver());
 }
@PostMapping("/register")
 public ResponseEntity<String> registerUser(@RequestParam String username) {
 userService.registerUser(username);
 return ResponseEntity.ok("User registered and notifications sent!");
 }
}
  • 端點(/register):接收username參數并據此完成用戶的注冊流程,同時觸發對所有觀察者的通知。
  • 觀察者:EmailObserver和SMSObserver都已注冊到UserService中,因此每當有新用戶注冊時,它們都會收到通知。

測試觀察者模式

現在,讓我們使用Postman或瀏覽器測試觀察者模式:

POST http://localhost:8080/api/register?username=JohnDoe

控制臺中的預期輸出:

User registered: JohnDoe
Email sent for event: User Registration
SMS sent for event: User Registration

系統在注冊用戶的同時能夠通知Email和SMS觀察者,這一過程很好地展示了觀察者模式所具備的靈活性。

觀察者模式的實際應用

  1. 通知系統:當特定事件發生時,能夠通過不同渠道(如電子郵件、短信、推送通知)向用戶發送更新信息。
  2. 事件驅動架構:當執行特定操作(如用戶活動或系統警報)時,通知多個子系統。
  3. 數據流:實時向各種消費者廣播數據變化(例如,實時股票價格或社交媒體動態)。

如何使用Spring Boot的依賴注入

到目前為止,我們的示例一直是手動創建對象來演示設計模式的工作原理。但在實際的Spring Boot應用程序開發中,我們更傾向于使用依賴注入(DI:Dependency Injection)這一強大的機制來管理對象的創建和裝配。依賴注入不僅讓Spring框架能夠自動處理類的實例化和依賴關系裝配,還極大地提升了代碼的模塊化程度、可測試性和可維護性。

現在,讓我們以策略模式為例,通過重構來充分利用Spring Boot的依賴注入能力。這將使我們能夠借助Spring的注解來靈活地管理依賴關系,并便捷地在不同的支付策略之間進行動態切換。

使用Spring Boot的依賴注入更新策略模式

為了重構策略模式的示例,我們將采用Spring的@Component、@Service和@Autowired等注解來簡化依賴注入的流程。以下是具體的步驟:

步驟1:使用@Component注解標注支付策略

首先,我們需要在策略的實現類上使用@Component注解進行標記。這樣做可以讓Spring能夠自動檢測并管理這些策略類。

@Component("creditCardPayment")public class CreditCardPayment implements PaymentStrategy { @Override public void pay(double amount) { System.out.println("Paid $" + amount + " with Credit Card");
 }
}

@Component("payPalPayment")
public class PayPalPayment implements PaymentStrategy {
 @Override
 public void pay(double amount) {
 System.out.println("Paid $" + amount + " using PayPal");
 }
}
  • @Component注解:通過添加@Component,我們告訴Spring將這些類視為Spring管理的Bean。字符串值(“creditCardPayment"和"payPalPayment”)作為Bean的標識符。
  • 靈活性:這種設置允許我們通過使用適當的Bean標識符在策略之間切換。

步驟2:重構PaymentService以使用依賴注入

接下來,讓我們修改PaymentService,以便使用@Autowired和@Qualifier注入特定的支付策略。

@Service
public class PaymentService {
 private final PaymentStrategy paymentStrategy;
@Autowired
 public PaymentService(@Qualifier("payPalPayment") PaymentStrategy paymentStrategy) {
 this.paymentStrategy = paymentStrategy;
 }
public void processPayment(double amount) {
 paymentStrategy.pay(amount);
 }
}
  • @Service注解:將PaymentService標記為Spring管理的服務Bean。
  • @Autowired:Spring會自動注入所需的依賴。
  • @Qualifier:指定要注入的PaymentStrategy的實現。在本例中,我們使用的是"payPalPayment"。
  • 配置的便捷性:只需更改@Qualifier的值,即可在不更改任何業務邏輯的情況下切換支付策略。

步驟3:在控制器中使用重構后的服務

為了看到重構的好處,讓我們更新控制器以使用我們的PaymentService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class PaymentController {
 private final PaymentService paymentService;
@Autowired
 public PaymentController(PaymentService paymentService) {
 this.paymentService = paymentService;
 }
@GetMapping("/pay")
 public String makePayment(@RequestParam double amount) {
 paymentService.processPayment(amount);
 return "Payment processed using the current strategy!";
 }
}
  • @Autowired:控制器會自動接收帶有已注入支付策略的PaymentService。
  • GET端點(/pay):當訪問此端點時,它會使用當前配置的支付策略(在本例中為PayPal)來處理支付。

使用依賴注入測試重構的策略模式

現在,讓我們使用Postman或瀏覽器測試新的實現:

GET http://localhost:8080/api/pay?amount=100

預期輸出:Paid $100.0 using PayPal

如果將PaymentService中的限定符改為“creditCardPayment”,輸出將相應地改變:

Paid $100.0 with Credit Card

使用依賴注入的優勢

  • 松耦合:服務和控制器不需要知道支付處理的具體過程和細節。它們僅僅依靠Spring的依賴注入功能來自動獲取正確的支付處理實現。
  • 模塊化:你可以便捷地添加新的支付方法(例如,銀行轉賬支付、加密貨幣支付),方法是通過創建帶有@Component注解的新類并調整@Qualifier。
  • 可配置性:通過利用Spring配置文件(Spring Profiles是Spring框架中提供的一種機制,它允許開發者根據不同的環境或配置來管理應用程序的不同部分),你可以根據環境(例如,開發環境與生產環境)切換策略。

示例:你可以使用@Profile根據活動的配置文件自動注入不同的策略:

@Component
@Profile("dev")
public class DevPaymentStrategy implements PaymentStrategy { /* ... */ }
@Component
@Profile("prod")
public class ProdPaymentStrategy implements PaymentStrategy { /* ... */ }

關鍵要點

  • 通過使用Spring Boot的依賴注入(DI),可以簡化對象的創建并提高代碼的靈活性。
  • 策略模式與依賴注入相結合,使能夠便捷地在不同的策略之間切換,而無需更改核心業務邏輯。

通過使用@Qualifier注解以及Spring的配置文件(Profiles),可以獲得根據不同環境或特定需求靈活配置應用程序的能力。

這種方法不僅使的代碼更加清晰,而且還為代碼進行高級配置和擴展做好了準備。在下一節中,我們將探討最佳實踐和優化技巧,從而的Spring Boot應用程序提升到新的水平。

通過遵循這些最佳實踐和優化技巧,可以進一步提高Spring Boot應用程序的性能、可維護性和可擴展性。這些技巧可能包括優化數據庫訪問、使用緩存、減少不必要的依賴注入、以及利用Spring Boot提供的各種內置功能來簡化配置和部署等。記住,持續學習和探索新技術是成為一名優秀開發者的關鍵。

最佳實踐與優化建議

最佳實踐通用原則

  • 適度使用設計模式:設計模式是解決特定問題的有效方案,但不應過度使用。過度使用設計模式會導致代碼變得復雜,增加理解和維護的難度
  • 優先選擇組合而非繼承:在軟件設計中,組合通常比繼承更具優勢策略模式和觀察者模式很好地體現了這一原則。
  • 保持設計模式的靈活性: 利用接口是保持設計模式靈活性的重要手段。接口可以將實現與定義分離,從而使代碼解耦。

性能考慮

  • 單例模式:通過使用synchronized 關鍵字或比爾·普格(Bill Pugh)單例模式來確保線程安全。
  • 工廠模式:如果在工廠模式中創建對象的成本較高,那么對創建的對象進行緩存是一種提高性能的有效方法。
  • 觀察者模式:在觀察者模式中,如果存在大量的觀察者,當被觀察對象狀態發生變化時通知所有觀察者可能會導致阻塞。為了避免這種情況,可以使用異步處理。

高級主題

  • 在工廠模式中使用反射進行動態類加載。
  • 利用Spring Profiles根據環境切換策略。
  • 的API端點添加Swagger文檔。

結論與要點總結

在本指南中,我們深入探討了幾種極為強大的設計模式——單例模式、工廠模式、策略模式和觀察者模式,并展示了它們在Spring Boot框架中的實現方法。接下來,讓我們對每種模式進行簡要總結,并提煉出它們各自最適用的應用場景:

單例模式:

  • 總結:此模式確保一個類僅有一個實例存在,并提供一個全局的訪問點。
  • 佳適用場景用于管理共享資源,例如配置設置、數據庫連接或日志服務等。當希望在整個應用程序中嚴格把控對某一共享實例的訪問時,單例模式無疑是理想之選。

工廠模式:

  • 總結:該模式提供了一種創建對象的方式,而無需明確指定要實例化的具體類。它成功地將對象創建邏輯與業務邏輯解耦
  • 佳適用場景在需要根據輸入條件動態創建不同類型對象的場景中,如通過電子郵件、短信或推送方式發送通知。工廠模式能夠顯著提升代碼的模塊化和可擴展性。

策略模式:

  • 總結:此模式允許定義一系列算法,并將每個算法獨立封裝,使它們能夠互換使用。此模式有助于在運行時靈活選擇算法。
  • 最佳適用場景需要動態切換不同行為或算法的場景,例如在電子商務應用中處理多樣化的支付方式。策略模式使代碼更加靈活,并嚴格遵循開閉原則。

觀察者模式:

  • 總結:該模式定義了對象間的一對多依賴關系,當一個對象的狀態發生變化時,其所有依賴者都會自動接收到通知。
  • 最佳適用場景事件驅動系統,如通知服務、聊天應用中的實時更新或需要響應數據變化的系統。觀察者模式能夠很好地解耦組件,并顯著提升系統的可擴展性。

接下來要做什么?

現在已經掌握了這些基礎的設計模式,建議嘗試將它們融入到的現有項目中,親身體驗它們如何優化的代碼結構和提升可擴展性。以下是一些建議,供進一步探索:

  • 嘗試:嘗試實現其他設計模式,如裝飾器模式(Decorator)、代理模式(Proxy)和構建器模式(Builder),以豐富的設計模式工具箱。
  • 實踐:使用這些模式對現有項目進行重構,從而提升其可維護性。
  • 分享:如果有任何疑問或想分享的實踐經驗,請隨時與我們聯系!

我希望本指南能夠助一臂之力,讓更加深入地理解如何在Java中高效使用設計模式。繼續探索和實踐,祝編碼之旅充滿樂趣!

譯者介紹

劉濤,51CTO社區編輯,某大型央企系統上線檢測管控負責人。

標題:How to Use Design Patterns in Java with Spring Boot – Explained with Code Examples,作者:Birks Sachdev

責任編輯:華軒 來源: 51CTO
相關推薦

2022-07-26 16:54:08

QuartzJava

2021-01-18 05:18:18

C# 8模式C# 7

2021-09-10 10:30:22

Java代碼

2018-08-03 08:37:31

設計模式IT項目GDPR

2023-01-28 17:41:07

Java代碼

2020-01-07 09:50:41

Windows 10上帝模式Windows

2017-05-09 10:34:21

Spring BootDubbo Activ擴展

2022-06-23 08:00:53

PythonDateTime模塊

2024-01-18 08:37:33

socketasyncio線程

2021-06-09 09:36:18

DjangoElasticSearLinux

2021-03-09 07:27:40

Kafka開源分布式

2015-08-27 09:46:09

swiftAFNetworkin

2022-05-17 08:25:10

TypeScript接口前端

2011-08-10 09:31:41

Hibernateunion

2019-09-16 19:00:48

Linux變量

2024-09-06 11:34:15

RustAI語言

2020-11-30 11:55:07

Docker命令Linux

2014-07-02 09:47:06

SwiftCocoaPods

2020-04-09 10:18:51

Bash循環Linux

2012-03-08 10:18:33

JavaOracle
點贊
收藏

51CTO技術棧公眾號

欧美一区二区视频| 男人的午夜天堂| 粉嫩av一区| 视频一区二区欧美| 中文字幕日韩高清| 在线观看av网页| 中文字幕资源网在线观看| 国内精品伊人久久久久av影院| 久久视频中文字幕| 97免费公开视频| av免费不卡| 久久久综合激的五月天| 国产成人一区二区三区小说| 欧美xxxooo| 91成人在线精品视频| 亚洲精品自拍动漫在线| 精品乱色一区二区中文字幕| 久久精品偷拍视频| 婷婷激情综合| 精品第一国产综合精品aⅴ| 男人揉女人奶房视频60分| 国产大片在线免费观看| 国精产品一区一区三区mba视频| 日韩视频在线一区| 蜜臀视频在线观看| 精品国模一区二区三区| 亚洲伦理在线精品| 精品国产一区二区三区日日嗨| 老熟妇一区二区三区啪啪| 一区二区三区在线电影| 日韩电影中文字幕| 天天色综合天天色| 操喷在线视频| 亚洲欧美中日韩| 国内精品视频在线播放| 91影院在线播放| 欧美一级一区| 欧美大片网站在线观看| 久久免费手机视频| 美女国产精品久久久| 狠狠躁夜夜躁人人爽天天天天97| 国产a级片免费看| 四虎国产精品永远| 国产一区高清在线| 国产精品video| 久久久精品视频在线 | 欧美一区二三区| frxxee中国xxx麻豆hd| 欧美精品国产白浆久久久久| 在线观看91av| 欧美精品无码一区二区三区| av在线免费观看网址| 国产日韩欧美a| 精品不卡一区二区三区| 国产三级小视频| 免费在线看成人av| 日韩美女激情视频| 日本熟妇成熟毛茸茸| 欧美成人日本| 在线播放日韩精品| 亚洲性猛交xxxx乱大交| 欧美性生活一级片| 欧美精品一区二| 日本wwwxx| 亚洲精品成人一区| 欧美色图12p| 午夜在线观看av| 日韩三级影视| 91成人网在线| 久久美女福利视频| 99热99re6国产在线播放| 中文字幕va一区二区三区| 欧洲亚洲一区二区| 欧美色18zzzzxxxxx| 91麻豆福利精品推荐| 国产精成人品localhost| 国产夫妻自拍av| 国产精品18久久久久| 成人精品网站在线观看| 国产精品欧美激情在线| 九九九久久久精品| 亚洲free嫩bbb| 国产成人毛毛毛片| 成人精品视频.| 精品国产乱码久久久久久郑州公司| 亚洲av无码国产综合专区 | 亚洲夂夂婷婷色拍ww47| 欧美少妇在线观看| 精精国产xxxx视频在线中文版| 一区二区三区不卡视频在线观看| 天天操天天干天天玩| av在线导航| 亚洲国产欧美在线| 日韩在线视频在线观看| 黄色综合网址| 欧美日本一区二区三区| 激情图片中文字幕| av男人一区| 国产视频在线观看一区二区| 色哟哟视频在线| 偷窥自拍亚洲色图精选| 国产亚洲精品美女| 久久99久久99精品免费看小说| 日韩成人免费| 久久97久久97精品免视看| 欧美极品aaaaabbbbb| 日韩视频二区| 热久久美女精品天天吊色| 又污又黄的网站| 国产精品一级片在线观看| 国产精品一区在线播放| 国产黄在线观看| 亚洲欧美日韩在线| 男人日女人逼逼| 久久av影院| 日韩精品影音先锋| 亚洲自拍偷拍图| 中文字幕乱码亚洲无线精品一区| 91精品国产91久久久久福利| 日批视频免费观看| 国产盗摄精品一区二区三区在线 | 国产l精品国产亚洲区久久| av亚洲一区| 精品国产凹凸成av人网站| 性高潮久久久久久久| 一区二区不卡| 国产精品久久久久久久久久东京| 精品二区在线观看| 国产免费久久精品| 国产一区二区视频播放| 亚洲欧美专区| 亚洲天堂av综合网| 精品深夜av无码一区二区老年| 肉肉av福利一精品导航| 国产精品伊人日日| av电影在线观看| 午夜电影网亚洲视频| 不卡中文字幕在线观看| 亚洲成aⅴ人片久久青草影院| 久久综合88中文色鬼| 成人一二三四区| 99热精品一区二区| 国产激情片在线观看| 日本蜜桃在线观看视频| 日韩一区二区三区电影| 日韩精品久久久久久久的张开腿让 | 免费在线成人| 国产精品成人一区二区三区| 男女在线观看视频| 精品国产一区二区三区久久久蜜月| 欧美黄色aaa| 国产成人精品午夜视频免费| 69精品丰满人妻无码视频a片| 欧美专区一区| 欧美国产日韩一区二区在线观看| 好吊色在线观看| 亚洲一区二区三区免费视频| 亚洲午夜久久久久久久久| 亚洲午夜伦理| 九9re精品视频在线观看re6| 亚洲人成午夜免电影费观看| 一本色道久久综合狠狠躁篇的优点| 久久久久久久久久一级| 国产精品免费看片| 欧美日韩久久婷婷| 影音先锋久久精品| 麻豆传媒一区二区| 桃色一区二区| 丝袜一区二区三区| av一区二区三| 精品久久久国产精品999| 粉嫩av蜜桃av蜜臀av| 日本女人一区二区三区| 中文精品一区二区三区| av成人app永久免费| 欧日韩在线观看| 欧美成人三区| 亚洲第一av网站| 久久久蜜桃一区二区| 国产精品日韩精品欧美在线| avtt中文字幕| 校园激情久久| 色中文字幕在线观看| 国产香蕉精品| 国产精品免费网站| 日本中文字幕中出在线| 亚洲美女视频网| 国产精品爽爽久久久久久| 亚洲国产日韩在线一区模特| 免费污网站在线观看| 国产乱国产乱300精品| 男人日女人下面视频| 欧美丝袜丝交足nylons172| 97中文在线| 欧美aa视频| 欧美贵妇videos办公室| 国产美女视频一区二区三区 | 潘金莲一级淫片aaaaa| 久久激情久久| 免费高清一区二区三区| 精品久久中文| 国产一区免费| 国产精品va视频| 热草久综合在线| 免费看电影在线| 色婷婷综合久久久久| 五月婷婷在线观看视频| 91精品国产综合久久精品app| 日本一区二区三区精品| 伊人色综合久久天天| 国产性猛交xx乱| 欧美挠脚心网站| 午夜精品久久一牛影视| 登山的目的在线| 久久久久久免费网| 国产精品麻豆入口| 激情五月婷婷综合网| 欧美午夜性生活| 一区二区91| 91成人综合网| 亚洲一区欧美| 亚洲欧美在线网| 精品一区免费| 国内精品视频在线播放| 91精品国产自产精品男人的天堂 | 欧美18免费视频| 99久久99久久| 伊人久久大香线蕉综合影院首页| 国产精品99导航| 91精品产国品一二三产区| 久久久久久久影院| 在线观看免费视频你懂的| 日韩视频免费看| 国产精品麻豆一区二区三区| 亚洲第一区第一页| 精品久久久久成人码免费动漫| 欧美高清视频一二三区 | 亚洲国产精品久久久久婷婷老年| 伊人春色之综合网| 久久偷看各类wc女厕嘘嘘偷窃| 精品少妇3p| 久久国产主播精品| 日韩三区视频| 久久国产精品一区二区三区| 天堂99x99es久久精品免费| 黑人巨大精品欧美一区二区小视频| 中文字幕日韩高清在线| 粉嫩av一区二区三区免费观看| 国产亚洲精aa在线看| 91九色视频在线观看| 欧美成人一级| 国产精品99久久久久久久| 国产精品qvod| 麻豆精品传媒视频| 精品视频免费| 一个色的综合| 中文无码久久精品| 精品无码国产一区二区三区av| 国产综合久久| 久久9精品区-无套内射无码| 老司机精品福利视频| www.这里只有精品| 国产很黄免费观看久久| 中文字幕乱妇无码av在线| 成人免费精品视频| 精品国产av无码| 中文字幕一区二区三区不卡在线 | 日本精品在线| 久久6免费高清热精品| 老司机深夜福利在线观看| 日韩美女主播视频| 日本久久一区| 成人av资源网| 久草在线成人| 国产成人三级视频| 国产欧美一区二区三区国产幕精品| www黄色av| 久久99热狠狠色一区二区| 超碰人人cao| 91麻豆国产福利精品| 久久视频精品在线观看| 亚洲乱码一区二区三区在线观看| 国产精品变态另类虐交| 在线观看国产一区二区| av官网在线观看| 亚洲精品中文字幕av| 欧美私人网站| 91精品国产91久久久久久不卡| 黄色成人在线观看网站| 国产精品久久久对白| av中文一区| 超碰成人免费在线| 久久精品99久久久| 97人妻精品一区二区三区免 | 亚洲人午夜精品| 2021国产在线| 日韩免费av在线| 凹凸成人在线| 一区二区免费电影| 亚洲制服少妇| 日本少妇激三级做爰在线| 久久久久久久久久久99999| 精品国产精品国产精品| 色综合久久综合| 99精品国产99久久久久久97| 亚洲国产成人91精品| 免费大片黄在线观看视频网站| 97视频免费看| 亚洲精品午夜| 只有这里有精品| 日本欧美在线观看| 制服丝袜第二页| 亚洲精品水蜜桃| 伊人网中文字幕| 亚洲美女av网站| 波多野一区二区| www.久久艹| 婷婷久久一区| 午夜免费看视频| 国产欧美日韩另类一区| 亚洲国产成人精品激情在线| 日韩欧美成人一区二区| 国产欧美久久久久久久久| 国产精品爽黄69| 国产探花在线精品| 欧美日韩二三区| 99久久精品久久久久久清纯| 久久久久久久久艹| 欧美一区二区美女| 国产素人视频在线观看| 国产一区二区色| 91一区二区三区四区| 久久午夜夜伦鲁鲁一区二区| 91免费观看在线| 国产精品500部| 亚洲精品久久在线| 国产一二在线播放| 国产一区二区中文字幕免费看| 黑人一区二区| 国产白袜脚足j棉袜在线观看| 亚洲综合网站在线观看| 性生交生活影碟片| 久久久久久香蕉网| 白嫩白嫩国产精品| 欧美视频在线观看视频| 成人av网址在线观看| 日韩精品成人在线| 亚洲福利在线观看| 国产精选在线| 精品在线不卡| 日韩av在线发布| 四虎国产成人精品免费一女五男| 欧美日韩在线综合| caopo在线| 国产精品区一区二区三在线播放 | 五月激情综合婷婷| 色资源在线观看| 国产99视频精品免视看7| 欧美视频网址| 日韩欧美中文视频| 亚洲国产精品一区二区www在线| 亚洲 精品 综合 精品 自拍| 欧美在线免费看| 久久国产影院| 少妇性l交大片7724com| 一区二区不卡在线播放| 午夜性色福利视频| 国产精品第3页| 一本一道久久a久久精品蜜桃| 青青草视频网站| 色综合久久综合网97色综合| 男人影院在线观看| 91久久国产综合久久蜜月精品| 亚洲精品三级| 天天操天天干天天操天天干| 欧美一区2区视频在线观看| 极品在线视频| 亚洲区一区二区三区| 国产成人h网站| 色老头在线视频| 欧美久久久精品| 色婷婷综合久久久久久| 成人综合久久网| 午夜av电影一区| 1769视频在线播放免费观看| 成人91视频| 视频在线观看一区| 91日韩中文字幕| 亚洲欧洲第一视频| 精品国产亚洲日本| 麻豆av免费在线| 亚洲美女偷拍久久| 伦理片一区二区三区| 3d动漫啪啪精品一区二区免费| 午夜亚洲视频| 永久免费看片直接| 亚洲欧美色图片| av男人一区| 视色视频在线观看| 岛国av一区二区三区|