成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

攤牌了!策略模式在項目設計中用的多嗎?

開發 項目管理
日常 Coding 過程中,設計模式三板斧:模版、構建者、策略,今天來說下第三板斧 策略設計模式。

[[381856]]

本文轉載自微信公眾號「源碼興趣圈」,作者龍臺。轉載本文請聯系源碼興趣圈公眾號。  

日常 Coding 過程中,設計模式三板斧:模版、構建者、策略,今天來說下第三板斧 策略設計模式

策略模式還是比較簡單并且使用較多的,平常我們多運用策略模式用來消除 if-else、switch 等多重判斷的代碼,消除 if-else、switch 多重判斷 可以有效應對代碼的復雜性,使設計解耦

如果分支判斷會不斷變化(增、刪、改),那么可以使用技巧讓策略模式滿足開閉原則,提高代碼的擴展性 (策略模式場景主要負責解耦,開閉原則需要額外支持)

下文中會詳細列舉如何使用設計模式做個 Demo 、模式的真實場景以及策略模式的好處

策略設計模式大綱如下:

  1. 什么是策略模式
  2. Spring 項目中真實的應用場景
  3. 框架源碼底層如何玩耍策略模式
  4. 策略模式總結

什么是策略模式

策略模式在 GoF 的《設計模式》一書中,是這樣定義的:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

定義一組算法類,將每個算法分別封裝起來,讓它們可以互相替換。策略模式使這些算法在客戶端調用它們的時候能夠互不影響地變化,客戶端代指使用算法的代碼

看到上面的介紹可能不太明白策略模式具體為何物,這里會從最基本的代碼說起,一步一步徹底掌握此模式。下述代碼可能大家都能聯想出對應的業務,根據對應的優惠類型,對價格作出相應的優惠

 

這段代碼是能夠滿足項目中業務需求的,而且很多已上線生產環境的代碼也有這類代碼。但是,這一段代碼存在存在兩個弊端

  1. 代碼的復雜性,正常業務代碼邏輯肯定會比這個代碼塊復雜很多,這也就 導致了 if-else 的分支以及代碼數量過多。這種方式可以通過將代碼拆分成獨立函數或者拆分成類來解決
  2. 開閉原則,價格優惠肯定會 隨著不同的時期作出不同的改變,或許新增、刪除或修改。如果在一個函數中修改無疑是件恐怖的事情,想想可能多個開發者分別進行開發,雜亂無章的注釋,混亂的代碼邏輯等情況十有八九會發生

如何運用策略模式優化上述代碼,使程序設計看著簡約、可擴展等特性

簡化代碼的復雜性,將不同的優惠類型定義為不同的策略算法實現類

保證開閉原則,增加程序的健壯性以及可擴展性

策略模式示例

將上述代碼塊改造為策略設計模式,大致需要三個步驟

  1. 定義抽象策略接口,因為業務使用接口而不是具體的實現類的話,便可以靈活的替換不同的策略
  2. 定義具體策略實現類,實現自抽象策略接口,其內部封裝具體的業務實現
  3. 定義策略工廠,封裝創建策略實現(算法),對客戶端屏蔽具體的創建細節

 

目前把抽象策略接口、具體的策略實現類以及策略工廠都已經創建了,現在可以看一下客戶端需要如何調用,又是如何對客戶端屏蔽具體實現細節的

 

根據代碼塊圖片得知,具體策略類是從策略工廠中獲取,確實是取消了 if-else 設計,在工廠中使用 Map 存儲策略實現。獲取到策略類后執行具體的優惠策略方法就可以獲取優惠后的金額

通過分析大家得知,目前這種設計確實將應用代碼的復雜性降低了。如果新增一個優惠策略,只需要新增一個策略算法實現類即可。但是,添加一個策略算法實現,意味著需要改動策略工廠中的代碼,還是不符合開閉原則

如何完整實現符合開閉原則的策略模式,需要借助 Spring 的幫助,詳細案例請繼續往下看

項目中真實的應用場景

最近項目中設計的一個功能用到了策略模式,分為兩類角色,筆者負責定義抽象策略接口以及策略工廠,不同的策略算法需要各個業務方去實現,可以聯想到上文中的優惠券功能。因為是 Spring 項目,所以都是按照 Spring 的方式進行處理,話不多說,上代碼

 

可以看到,比對上面的示例代碼,有兩處明顯的變化

  1. 抽象策略接口中,新定義了 mark() 接口,此接口用來標示算法的唯一性
  2. 具體策略實現類,使用 @Component 修飾,將對象本身交由 Spring 進行管理

小貼士:為了閱讀方便,mark() 返回直接使用字符串替代,讀者朋友在返回標示時最好使用枚舉定義

接下來繼續查看抽象策略工廠如何改造,才能滿足開閉原則

 

和之前 責任鏈模式 相同,都是通過 InitializingBean 接口實現中調用 IOC 容器查找對應策略實現,隨后將策略實現 mark() 方法返回值作為 key, 策略實現本身作為 value 添加到 Map 容器中等待客戶端的調用

 

這里使用的 SpringBoot 測試類,注入策略工廠 Bean,通過策略工廠選擇出具體的策略算法類,繼而通過算法獲取到優惠后的價格。小插曲:如果不想把策略工廠注入 Spring 也可以,實現方法有很多

總結下本小節,我們通過和 Spring 結合的方式,通過策略設計模式對文初的代碼塊進行了兩塊優化:應對代碼的復雜性,讓其滿足開閉原則。更具體一些呢就是 通過抽象策略算法類減少代碼的復雜性,繼而通過 Spring 的一些特性同時滿足了開閉原則,現在來了新需求只要添加新的策略類即可,健壯易擴展

源碼底層如何耍策略模式

自己用肯定覺得不夠,必要時候還得看看設計開源框架源碼的大佬們如何在代碼中運用策略模式的

在作者了解中,JDK、Spring、SpringMvc、Mybatis、Dubbo 等等都運用了策略設計模式,這里就以 Mybatis 舉例說明

Mybatis 中 Executor 代表執行器,負責增刪改查的具體操作。其中用到了兩種設計模式,模版方法以及策略模式

 

Executor 代表了抽象策略接口,剛才說到的模版方法模式源自 BaseExecutor

Configuration 代表策略工廠,負責創建具體的策略算法實現類

SimpleExecuto、ReuseExecutor... 表示封裝了具體的策略算法實現類

 

上述代碼塊發生在 Configuration 類中創建執行器 Executor,通過 executorType 判斷創建不同的策略算法。

上述代碼塊并沒有徹底消除 if-else,因為 Mybatis 中執行器策略基本是固定的,也就是說它只會有這些 if-else 判斷,基本不會新增或修改。如果非要消除 if-else,可以這么搞,這里寫一下偽代碼

 

這種方式叫做 "查表法",通過策略工廠實現消除 if-else 分支。最后,Mybatis 太過詳細的設計這里不再贅述,有興趣的小伙伴可以去把源碼下載啃一啃

到了這里可能有讀者看出了問題,策略模式就算消除了 if-else 但是如果添加新的策略類,不還是會違反開閉原則么?

沒錯,因為 Mybatis 本身沒有引入 Spring 依賴,所以沒有辦法借助 IOC 容器實現開閉原則。Spring 是一種開閉原則解決方式,那還有沒有別的解決方式?

解決方式有很多,開閉原則核心就是 對原有代碼修改關閉,對新增代碼開放??梢酝ㄟ^掃描指定包下的自定義注解亦或者通過 instanceof 判斷是否繼承自某接口都可以。不過, 項目如果用了 Spring 還是消停的吧

結言

文章中圖文并茂的方式介紹策略模式,通過價格優惠的場景,進而引用本文的重點:策略設計模式,相信小伙伴看完后都會有一定的收獲

策略模式的本質依然是對代碼設計解耦合,通過三類角色貫穿策略模式:抽象策略接口、策略工廠以及具體的策略實現類。通過細粒度的策略實現類避免了主體代碼量過多,減少了設計中的復雜性。并通過開閉原則特性,添加新策略時可以保證最小、集中化修改代碼

作者聽到過很多小伙伴覺得自己做的都是 CRUD 工作,沒有挑戰性沒意思。其實,我想說的是:業務代碼一樣牛逼,一樣能體現程序員的水平。不一定非要高并發、大數據等場景。頗有一屋不掃何以掃天下的意思

最后拋出一個問題:出現 if-else 的代碼,一定要使用策略模式優化么

如果 if-else 判斷分支不多并且是固定的,后續不會出現新的分支,那我們完全 可以通過抽函數的方式降低程序復雜性;不要想法設法去除 if-else 語句,存在即合理。而且,使用策略模式會導致類增多,沒有必要為了少量的判斷分支引入策略模式

關于策略設計模式本文就講到這里,后面會陸續輸出工廠、原型、享元等模式;如果文章對你有幫助那就點個關注支持下吧,祝好。

文章參考:《設計模式之美:策略模式》

責任編輯:武曉燕 來源: 源碼興趣圈
相關推薦

2017-07-07 10:55:14

數據庫MongoDB設計模式

2022-10-30 17:32:25

設計模式單例模式

2013-11-26 16:09:34

Android設計模式

2012-08-30 09:07:33

設計模式

2021-06-09 08:53:34

設計模式策略模式工廠模式

2015-09-08 13:39:10

JavaScript設計模式

2022-09-21 09:01:27

Spring設計模式框架,

2021-06-08 07:04:46

Dubbo設計模式

2022-05-13 07:26:28

策略模式設計模式

2024-10-06 12:56:36

Golang策略設計模式

2014-12-29 10:39:16

JS

2024-01-29 12:22:07

設計模式策略模式

2020-10-26 13:42:28

Python算法垃圾

2014-03-11 10:03:25

設計模式

2017-03-20 18:03:51

2025-03-26 00:03:00

Go設計模式

2021-05-17 14:57:23

策略模式代碼

2024-08-12 08:15:46

2021-11-22 08:00:00

Kubernetes容器集群

2023-05-22 13:27:17

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 激情在线视频网站 | 欧美成人免费在线 | 久久成人亚洲 | 性生活毛片 | 国产精品久久久久久久7电影 | 日韩欧美在线视频观看 | 一级片毛片 | a视频在线观看 | 99色视频 | 精品久久久久久久久久久久久久 | 国产日韩精品久久 | 久久久久国产一区二区三区四区 | 欧美激情一区二区 | 91精品成人久久 | 日韩中文字幕在线不卡 | 成人精品一区二区 | 啪一啪| 日韩欧美一区二区三区四区 | 91麻豆精品国产91久久久久久久久 | 国产精品高清一区二区 | 天天操欧美 | 伊人伊人网 | 青草福利 | 国产1区| 免费v片| 美国黄色一级片 | 精品一二三 | 91新视频| 亚洲精品在线免费 | 国产精品毛片久久久久久 | www.日本精品 | 国产不卡一区 | 中文字字幕在线中文乱码范文 | 亚洲欧美另类在线 | 国产视频中文字幕 | h肉视频 | 国产精品国产成人国产三级 | 秋霞a级毛片在线看 | 99精品一区二区 | 99视频入口 | 欧美极品在线 |