面試官:我想問個問題哈,專案裡比較常見的問題
面試官:我現在有個系統會根據請求的入參,做出不同動作。但是,這塊不同的動作很有可能是會發生需求變動的,這塊系統你會怎麼樣設計?
面試官:實際的例子:現在有多個第三方渠道,系統需要對各種渠道進行訂單歸因。但是歸因的邏輯很有可能會發生變化,不同的渠道歸因的邏輯也不太一樣,此時系統裡的邏輯相對比較複雜。
面試官:如果讓你優化,你會怎麼設計?
候選者:我理解你的意思了
候選者:歸根到底,就是處理的邏輯相對複雜,if else的判斷太多了
候選者:雖然新的需求來了,都可以新增if else進行解決
候選者:但你想要的就是,系統的可擴充套件性和可維護性更強
候選者:想要我這邊出一個方案,來解決類似的問題
候選者:對吧?
面試官:嗯…
候選者:在這之前,一般上網搜如何解決 if else ,大多數都說是 策略模式
候選者:但是舉的例子又沒感同身受,很多時候看完就過去了
候選者:實際上,在專案裡邊,用策略模式還是蠻多的,可能無意間就已經用上了(畢竟面向介面程式設計嘛)
候選者:而我認為,策略模式不是解決if else的關鍵
候選者:這個問題,我的專案裡的做法是:責任鏈模式
候選者:把每個流程單獨抽取成一個Process(可以理解為一個模組或節點),然後請求都會塞進Context中
候選者:比如,之前維護過一個專案,也是類似於不同的渠道走不同的邏輯
候選者:我們這邊的做法是:抽取相關的邏輯到Process中,為不同的渠道分配不同的責任鏈
候選者:比如渠道A的責任鏈是:WhiteListProcess->DataAssembleProcess->ChannelAProcess->SendProcess
候選者:而渠道B的責任鏈是:WhiteListProcess->DataAssembleProcess->ChannelBProcess->SendProcess
候選者:在責任鏈基礎之上,又可以在程式碼裡內嵌「指令碼」
候選者:比如在SendProcess上,內建傳送訊息的指令碼(指令碼可以選擇不同的運營商進行傳送訊息)。有了「指令碼」以後,那就可以做到對邏輯的改動不需要重啟就可以生效。
候選者:有人把這一套東西叫做「規則引擎」。比如,規則引擎中比較出名的實現框架「Drools」就可以做到類似的事
候選者:把易改動的邏輯寫在「指令碼」上(至少我們認為,指令碼和我們的應用真實邏輯是分離)
候選者:(指令碼我這裡指的是規則集,它可以是Drools的dsl,也可以是Groovy,也可以是aviator等等)
面試官:嗯…
候選者:在我之前的公司,使用的是Groovy指令碼。大致的實現邏輯就是:有專門後臺對指令碼進行管理,然後會把指令碼寫到「分散式配置中心」(實時重新整理),客戶端監聽「分散式配置中心」所儲存的指令碼是否有改動
候選者:如果存在改動,則通過Groovy類載入器重新編譯並載入指令碼,最後放到Spring容器對外使用
候選者:我目前所負責的系統就是這樣處理 多變 以及需求變更頻繁的業務(責任鏈+規則引擎)
候選者:不過據我瞭解,我們的玩法業務又在「責任鏈」多做了些事情
候選者:「責任鏈」不再從程式碼裡編寫,而是下沉到平臺去做「服務編排」,就是由程式設計師去「服務編排後臺」上配置資訊(配置責任鏈的每一個節點)
候選者:在業務系統裡使用「服務編排」的客戶端,請求時只要傳入「服務編排」的ID,就可以按「服務編排」的流程執行程式碼
候選者:這樣做的好處就是:業務鏈是在後臺配置的,不用在系統業務上維護鏈,靈活性更高(寫好的責任鏈節點可以隨意組合)
面試官:那我懂了
歡迎關注我的微信公眾號【Java3y】來聊聊Java面試,對線面試官系列持續更新中!
【對線面試官-移動端】系列 一週兩篇持續更新中!
【對線面試官-電腦端】系列 一週兩篇持續更新中!
原創不易!!求三連!!