面試官:我想問個問題哈,項目里比較常見的問題
面試官:我現在有個系統會根據請求的入參,做出不同動作。但是,這塊不同的動作很有可能是會發生需求變動的,這塊系統你會怎么樣設計?
面試官:實際的例子:現在有多個第三方渠道,系統需要對各種渠道進行訂單歸因。但是歸因的邏輯很有可能會發生變化,不同的渠道歸因的邏輯也不太一樣,此時系統里的邏輯相對比較復雜。
面試官:如果讓你優化,你會怎么設計?
候選者:我理解你的意思了
候選者:歸根到底,就是處理的邏輯相對復雜,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,就可以按「服務編排」的流程執行代碼
候選者:這樣做的好處就是:業務鏈是在后台配置的,不用在系統業務上維護鏈,靈活性更高(寫好的責任鏈節點可以隨意組合)
面試官:那我懂了
【對線面試官-移動端】系列 一周兩篇持續更新中!
【對線面試官-電腦端】系列 一周兩篇持續更新中!
原創不易!!求三連!!