這麼用 if-else,小鹿差點被辭退!

記得去年 11 月份,剛入職的時候,領導把我分配到一個翻新老項目的項目組中。設計模式

當初,剛進入公司仍是蠻激動的,看到這個有點年紀的老項目,打開編輯器,看了看代碼,我差點忍不住哭了。編輯器

內心暗想,「這是哪位離職的老前輩寫的代碼,這口鍋我真不想背」,功能模塊沒有任何註釋,業務邏輯從頭至尾寫下來的,沒有代碼規範,看着這一堆老代碼,我無從下手。ide

這時背後一我的,拍了拍我肩膀,我一會兒緩過神來,原來是項目組的負責人。函數

鹿呀,咱們這個老項目,在此基礎上,要增長一個功能,這個功能就交給你去作了,項目快到上線了,今天儘快完成吧。而後把大致功能和我說了一通。測試

沒辦法,只能硬着頭皮去搞,我找到了那個功能頁面的代碼,正開始屢屢業務邏輯,下面一個代碼結構讓我眼前一亮。設計

1if(type == 'fn1'){  // 功能1
 2  let a = 1;
 3  let arr = [];
 4  // 具體功能實現
 5  // ...
 6
 7}else if(type == 'fn2'){ // 功能2
 8  // 具體功能實現
 9  // ...
10
11}else if(type == 'fn3'){ // 功能3
12  // 具體功能實現
13  // ...
14
15}else if(type == 'fn4'){ // 功能4
16  // 具體功能實現
17  // ...
18
19}else if(type == 'fn5'){  // 功能5
20  // 具體功能實現
21  // ...
22
23}else if(type == 'fn6'){ // 功能6
24  // 具體功能實現
25  // ...
26
27}else if(type == 'fn7'){  // 功能7
28  // 具體功能實現
29  // ...
30
31}else if(type == 'fn8'){ // 功能8
32  // 具體功能實現
33  // ...
34
35}else{
36  // 具體功能實現
37  // ...
38}

哎呀個人媽呀,這一長串,看的我有點暈,這不是人們傳說中的
if-else 調用俠客嗎?調試

並且我又仔細看看了看每一個 else if 內部功能代碼實現,基本每一個功能全部邏輯代碼都堆砌在 else-if 中。代碼規範

並且好像這些功能的實現並非一我的完成的,而是通過了好幾輪前輩的接手,每當增長一個需求,該項目開發者就增長一個 else-if,因此纔有了今天我所看到的結果。code

本來我也能夠輕鬆增長個 else-if 就完成任務的,但我這我的有強迫症,不想再當一個 if-else 俠客了,好吧,開始寫個人新功能。對象

寫完以後的代碼以下:

1function readNewFile(file){
 2  // 具體功能封裝
 3  // ...
 4}
 5
 6const modelObj = {
 7  fn1(file){  // 功能1
 8    // ... 
 9  },
10  fn2(file){  // 功能2
11    // ...
12  },
13  fn3(file){  // 功能3
14    // ...
15  },
16  readNewFile(file){  // 功能4
17    // 新增長的功能
18    // ...
19  },
20
21  // 其餘功能封裝
22  // ...
23}
24
25function main(type, file){
26  modelObj[type](file)
27}

寫完以後,我把代碼提交給個人負責人看,看完以後,沒錯,大家看完可能也會問,你這不是沒事給本身找事幹嗎,明明能夠增長一個 else-if 完事,你卻額外增長了這麼多代碼?

沒錯,功能我實現了,代碼多出了幾乎一倍,反倒被要求從新改回原來的 else-if。鹿哥性格大家又不是不知道。我說,對不起,這是個人寫代碼習慣,正當我解釋爲何要這樣寫的時候,負責人說,行了,先這樣吧。

雖然內心有一萬句不爽,可是我仍是默默的轉身離開了。

小結

這就是我剛剛實習的時候,碰到的第一件比較棘手的事情,我很理解負責人的心情,畢竟項目快速上線要緊,可是我認爲給別人留條後路,就是給本身留條後路。

鹿哥,此話怎說,怎麼感受你話裏有話。並且你尚未說爲何你要這麼麻煩的去增長功能?

好吧,不賣關子了,其實這樣的寫法並非我本身發明的,而是設計模式中的策略模式,能夠說是老前輩在幾十年的項目中總結出來,至於爲何這麼寫,確定是有它的道理的。

咱們先分析一下,上方原始代碼的缺陷有哪些?

一、最明顯的缺陷就是每一個 else-if 中的代碼有一堆實現功能的邏輯。一旦 else-if 出現問題,整個 else-if 中的其餘功能全都不能用了。

二、若是增長一個功能,須要無限的疊加 else-if。

這兩個看起來並無什麼毛病呀?別急,聽我慢慢細說。

爲何把每一個功能抽離成函數?由於像這種老項目,已經被不少前輩寫過,項目很容易出現問題,一旦出現問題,很難定位代碼,咱們更不可能找到離職的員工詢問具體哪出錯誤了。

若是咱們單獨抽離成函數,當該函數內部出現問題的時候,咱們經過斷點調試,能夠直接定位問題出如今哪裏。而不像之前在if-else 海洋裏探索定位問題。

並且每一個函數單獨封裝起來,由於遵循設計模式原則之一,單一功能原則。每一個函數只能幹一件事,每一個功能都是獨立分離的,這樣盡最大可能實現功能函數之間的解耦。

有關第二點,爲何會設置一個對象映射,而不是繼續增長 else-if?

此次咱們增長一個功能,可能幾年以後,客戶需求有變,須要再增長一個功能,而增長功能的人換了,那麼這個增長功能的人,沒必要擔憂原來的功能邏輯實現,只須要在這個對象中增長一個函數,在函數內部增長一個功能實現就 OK 了。

並且總體看起來,代碼規範和總體的代碼結構很是的清晰,不止於一旦出現問題,在修改過程當中致使其餘地方出現問題,從而影響項目的開發進度。

作完以後,我直接把個人代碼扔給了咱們公司的測試小姐姐,小姐姐對我笑了笑,咳咳,後來.....

可想而知,測試小姐姐在測試的時候,不用再把整個 else-if 拿過來測試了,而是直接拿我寫的功能函數,只測試增長的功能就完成了。

回到最初那句話,給別人留條後路,就是給本身留條後路。我給測試小姐姐留了一條後路,後來就... (大家懂得)

最後

這件事情,讓我產生深入的感悟。若是能用哲學中老子的「道」去闡述的話,將複雜的問題轉化爲最簡單的哲學思想,而後直至事物的核心與本質。

老子同時將「道」稱爲「無」和「有」,「由於它沒有形象,因此是「無」;由於它真實存在,因此是「有」。

那麼實際開發項目中,項目最初的本質就是設計模式的運用,設計模式的核心思想就是「封裝變化」。就是變與不變,變化的是擴展,不變的是穩定。變與不變又可相互轉化。所謂有形化爲無形,有法化爲沒法。

正所謂,道可道,很是道,名可名,很是名。玄之又玄,衆妙之門也。

相關文章
相關標籤/搜索