利用策略模式優(yōu)化過多 if else 代碼
前言
不出意外橘茉,這應(yīng)該是年前最后一次分享闪彼,本次來一點實際開發(fā)中會用到的小技巧昂勉。
比如平時大家是否都會寫類似這樣的代碼:
if(a){
//dosomething
}else if(b){
//doshomething
}else if(c){
//doshomething
} else{
////doshomething
}
條件少還好者甲,一旦 else if
過多這里的邏輯將會比較混亂商佛,并很容易出錯闷愤。
比如這樣:
摘自 cim 中的一個客戶端命令的判斷條件整葡。
剛開始條件較少,也就沒管那么多直接寫的讥脐;現(xiàn)在功能多了導(dǎo)致每次新增一個 else
條件我都得仔細核對遭居,生怕影響之前的邏輯。
這次終于忍無可忍就把他重構(gòu)了旬渠,重構(gòu)之后這里的結(jié)構(gòu)如下:
最后直接變?yōu)閮尚写a俱萍,簡潔了許多。
而之前所有的實現(xiàn)邏輯都單獨抽取到其他實現(xiàn)類中告丢。
這樣每當(dāng)我需要新增一個 else
邏輯枪蘑,只需要新增一個類實現(xiàn)同一個接口便可完成。每個處理邏輯都互相獨立互不干擾芋齿。
實現(xiàn)
按照目前的實現(xiàn)畫了一個草圖腥寇。
整體思路如下:
- 定義一個
InnerCommand
接口,其中有一個process
函數(shù)交給具體的業(yè)務(wù)實現(xiàn)觅捆。 - 根據(jù)自己的業(yè)務(wù)赦役,會有多個類實現(xiàn)
InnerCommand
接口;這些實現(xiàn)類都會注冊到Spring Bean
容器中供之后使用栅炒。 - 通過客戶端輸入命令掂摔,從
Spring Bean
容器中獲取一個InnerCommand
實例。 - 執(zhí)行最終的
process
函數(shù)赢赊。
主要想實現(xiàn)的目的就是不在有多個判斷條件乙漓,只需要根據(jù)當(dāng)前客戶端的狀態(tài)動態(tài)的獲取 InnerCommand
實例。
從源碼上來看最主要的就是 InnerCommandContext
類释移,他會根據(jù)當(dāng)前客戶端命令動態(tài)獲取 InnerCommand
實例叭披。
- 第一步是獲取所有的
InnerCommand
實例列表。 - 根據(jù)客戶端輸入的命令從第一步的實例列表中獲取類類型玩讳。
- 根據(jù)類類型從
Spring
容器中獲取具體實例對象涩蜘。
因此首先第一步需要維護各個命令所對應(yīng)的類類型。
所以在之前的枚舉中就維護了命令和類類型的關(guān)系熏纯,只需要知道命令就能知道他的類類型同诫。
這樣才能滿足只需要兩行代碼就能替換以前復(fù)雜的 if else
,同時也能靈活擴展樟澜。
InnerCommand instance = innerCommandContext.getInstance(msg);
instance.process(msg) ;
總結(jié)
當(dāng)然還可以做的更靈活一些误窖,比如都不需要顯式的維護命令和類類型的對應(yīng)關(guān)系叮盘。
只需要在應(yīng)用啟動時掃描所有實現(xiàn)了 InnerCommand
接口的類即可,在 cicada 中有類似實現(xiàn)霹俺,感興趣的可以自行查看柔吼。
這樣一些小技巧希望對你有所幫助。
以上所有源碼可以在這里查看:
https://github.com/crossoverJie/cim
你的點贊與分享是對我最大的支持
作者: crossoverJie