Spring Boot 策略模式
相信大部分開發者都見過這樣的程式碼:
@Component class RequestReceiver { public Response receiveRequest(Request request) { switch (request.getType()) { case GET: return handleGet(request); case POST: return handlePost(request); case PUT: return handlePut(request); default: throw new IllegalArgumentException("Unknown request type: " + request.getType()); } } } |
乍一看,這個實現沒有任何問題,看起來很乾淨。
但是,假設我們要新增對 DELETE、PATCH 和 HEAD HTTP 方法的支援。為此,我們需要為此類中的每個方法實現處理邏輯,並將它們包含在 switch 塊中。這完全違反了開閉原則,該原則指出:軟體實體應該對擴充套件開放,但對修改關閉。根據我自己的經驗,我看到過一些長達數百行的 switch 語句,我向您保證,這樣的程式碼很混亂且難以測試。如果我們可以在不觸及現有邏輯的情況下新增對新 HTTP 方法的支援,那就太好了。這就是策略設計模式可以幫助我們的地方。
策略模式是一種行為軟體設計模式,可以在執行時選擇演算法。程式碼不是直接實現單個演算法,而是接收關於在一系列演算法中使用哪個的執行時指令。
讓我們嘗試應用此模式並重新實現我們的RequestReceiver 類。首先,我們需要定義一個新的抽象,負責處理單個請求。
interface RequestHandler { Response handle(Request request); RequestType supportedRequestType(); } @Component class GetRequestHandler implements RequestHandler { @Override public Response handle(Request request) {...} @Override public RequestType supportedRequestType() { return RequestType.GET; } } @Component class PostRequestHandler implements RequestHandler { @Override public Response handle(Request request) {...} @Override public RequestType supportedRequestType() { return RequestType.POST; } } @Component class PutRequestHandler implements RequestHandler { @Override public Response handle(Request request) {...} @Override public RequestType supportedRequestType() { return RequestType.PUT; } } |
建立新的抽象後,有幾種方法可以使用它們,我將展示其中的幾種:
- 使用Map儲存策略
- 使用專用登錄檔來儲存策略
1. 使用 Map 實現
@RequiredArgsConstructor class RequestReceiver { private final Map<RequestType, RequestHandler> requestHandlers; public Response receiveRequest(Request request) { if (!requestHandlers.containsKey(request.getType())) { throw new IllegalArgumentException("Unknown request type: " + request.getType()); } return requestHandlers.get(request.getType()).handle(request); } } |
我們需要用策略填充我們的Map,為此,我們建立了一個配置類。
@Configuration class RequestReceiverConfiguration { @Bean public RequestReceiver requestReceiver(List<RequestHandler> requestHandlers) { return new RequestReceiver( requestHandlers.stream() .collect(toMap(RequestHandler::supportedRequestType, Function.identity())) ); } } |
2. 使用專用登錄檔實現
讓我們為RequestHandlers實現一個登錄檔:
@Component @RequiredArgsConstructor class RequestHandlerRegistry { private final List<RequestHandler> requestHandlers; public Optional<RequestHandler> getHandlerFor(Request request) { return requestHandlers.stream() .filter(handler -> handler.supportedRequestType().equals(request.getType())) .findAny(); } } |
RequestReceiver 的最終實現:
@Component @RequiredArgsConstructor class RequestReceiver { private final RequestHandlerRegistry registry; public Response receiveRequest(Request request) { return registry.getHandlerFor(request) .orElseThrow(() -> new IllegalArgumentException("Unknown request type: " + request.getType())) .handle(request); } } |
重構後,這兩種方法都使我們的設計隔離,同時對擴充套件開放,現在我們可以輕鬆地為 DELETE 方法新增新的實現,而無需更改一行現有程式碼:
@Component class DeleteRequestHandler implements RequestHandler { @Override public Response handle(Request request) {} @Override public RequestType supportedRequestType() { return RequestType.DELETE; } } |
結論
在本文中,我們解釋了策略模式,並演示瞭如何在 Spring Boot 應用程式中實現它。
相關文章
- 策略模式、策略模式與Spring的碰撞模式Spring
- Spring中實現策略模式示例Spring模式
- Spring Boot整合Redis叢集(Cluster模式)Spring BootRedis模式
- Spring Boot事務發件箱模式Spring Boot模式
- 使用Spring實施策略模式 - javarevisitedSpring模式Java
- spring注入bean的幾種策略模式SpringBean模式
- 使用spring外掛實現策略模式Spring模式
- Spring Boot:Spring Boot配置MybatisSpring BootMyBatis
- spring boot 2.0 整合 security oauth2 password 模式和credentials 模式Spring BootOAuth模式
- Spring Boot (十三): Spring Boot 小技巧Spring Boot
- Spring Boot:Spring Boot配置SwaggerSpring BootSwagger
- Spring Boot 2.0(八):Spring Boot 整合 MemcachedSpring Boot
- Spring Boot 參考指南(Spring Boot文件)Spring Boot
- Spring Boot學習6:Spring Boot JDBCSpring BootJDBC
- Spring Boot(十八):使用 Spring Boot 整合 FastDFSSpring BootAST
- Spring Boot(五):Spring Boot Jpa 的使用Spring Boot
- Jeecg-Boot Spring BootSpring Boot
- Spring Boot(十三):整合Redis哨兵,叢集模式實踐Spring BootRedis模式
- Spring Boot中五個設計模式最佳實踐Spring Boot設計模式
- Spring BootSpring Boot
- 策略模式模式
- Spring Boot系列(四):Spring Boot原始碼解析Spring Boot原始碼
- Spring Boot系列(一):Spring Boot快速開始Spring Boot
- Spring Boot系列(一):Spring Boot 入門篇Spring Boot
- Spring Boot學習(一)——Spring Boot介紹Spring Boot
- Spring boot學習(三) Spring boot整合mybatisSpring BootMyBatis
- Spring Boot 2.0(四):使用 Docker 部署 Spring BootSpring BootDocker
- Spring Boot(十一):Spring Boot 中 MongoDB 的使用Spring BootMongoDB
- Spring Boot(十六):使用 Jenkins 部署 Spring BootSpring BootJenkins
- Spring Boot(三):Spring Boot 中 Redis 的使用Spring BootRedis
- Spring Boot(七):spring boot測試介紹Spring Boot
- Spring Boot/Spring MVCSpring BootMVC
- Spring Boot —— Spring SecuritySpring Boot
- spring、spring MVC、spring BootMVCSpring Boot
- iOS模式分析 策略模式iOS模式
- 設計模式——策略模式設計模式
- 設計模式(策略模式)設計模式
- 設計模式-策略模式設計模式