1. 程式人生 > 實用技巧 >你寫的程式碼就是你的犯罪證據

你寫的程式碼就是你的犯罪證據

你寫的 if 就是你的犯罪證據

業務的複雜性,導致了架構的複雜性。在這些程式碼故事裡,發生得最多的地方就是 if 語句。所以,你可以從大部分的 if 語句裡,看到一些程式碼上的壞味道。

業務條件複雜

你先寫了一個 if 語句裡面只有一個條件,沒問題。但是後來的人,又加了一個條件,因為業務上確實需要這麼做。於是,後來,又不得加了一個if 語句,導致了這個條件變得更加複雜。

if (isCondition && isNotASwitchCase && .... && ....) {
}

所以,完了,這些程式碼越來越難以維護。

於是,我們應對於這類條件判斷,有兩種做法:提取變數

提取方法。當你的判斷條件是一個方法的時候,你可以想象一下它的架構是多麼的複雜。

難以閱讀的字串判斷

開始的人加了一個簡單的條件判斷,因為當時真的只有這麼一種業務場景。你又不能過度設計,成一個 switch-case。但是,後來又多了好多個場景。

if (aCondition == "A")  {
} else if (bCondition == "B")  {

}

更不要提有人在每個 if 裡寫一個: if (myString.toUpperCase().equals(myOtherString.toUpperCase()))。

針對於有限的 if 語句來說,可以轉為 switch case(在 IDEA 裡只需要 alt + enter 就可以自動完成)。

隨著時間的推移我們的條件越來越複雜,我們的 if 語句會越來越複雜。

多層巢狀 if 語句

隨著 if 條件進一步擴大化,我們的條件語句就變成了一個多層巢狀的迴圈語句。每多一層巢狀程式碼複雜度就 * 2,它的閱讀難度就越來越大。於是乎:

if (condition) {
     if (blabla) {
         ...
     }
}

面對這一類 if 條件語句,我們能所做的就是:

  • 提供方法
  • 反轉 if 語句

諸如於:

if (!condition) {return}; // 為了演示方便
if(blabla){...}

又或者是諸如於三元表示式,不過我討厭難以閱讀的三元表示式——但是,只是 true 和 false 的情況下,還是相當不錯的。

複雜的 if 塊內邏輯

當業務進一步複雜化的時候,我們的 if 條件裡就充斥著各種各樣的邏輯。

if (conditionA) {
    blablaA();
    blaA(blabla).blabla();
}

我們的 if 方法隨之變得越來越長,於是嘗試去抽成一個方法。但是,當你又遇到一個新的場景時,你又加了一個 if 語句。後來,又又加了一個 if 語句。你才發現說,『咦,不對,這些 If 語句違反了開閉原則』。

於是,你嘗試把程式碼重構成多型以替換 if 語句。

你開心的話,還可以轉為 Factory + Strategy。

你開心的話,你也可以將它轉為 HashMap 。

但是,在你寫下第一個 if 的時候,你並不知道它會變成什麼樣的。所以,不要提前去把它轉為這麼複雜的架構。

上帝 if

如果你的業務場景真的超級複雜,那麼你可能會看到一個非常長的 if 程式碼。它可能有幾十個條件,有幾百行到幾千行的規模。

那麼,你可以嘗試使用登錄檔模式+ 註解,通過反射的方式來重構你的 if 語句。

重構

在你進一步修改程式碼之前,讓我們來又雙叕明確一下什麼叫重構

重構(Refactoring)就是通過調整程式程式碼改善軟體的質量、效能,使其程式的設計模式和架構更趨合理,提高軟體的擴充套件性和維護性。

換句話來說,重構只是在改善現有的程式碼,使其更易於閱讀,換句話來說就是:Clean Code。而當我們說整潔的程式碼(Clean Code),說的是易於理解、修改和測試的。易於理解和修改意味著:

  • 易於理解整個系統的架構
  • 易於理解整個應用程式的執行流程
  • 易於理解不同物件如何相互協作
  • 易於理解理解每種方法的作用
  • 易於理解每個表示式和變數的目的是什麼

而易於理解的前提便是能讓每個團隊成員快速理解。(PS:當然了,若是有些人智商不夠或者經驗不夠,他/她需要去需要去增強這方面的能力)。這便意味著,出於這樣的目的,你不能編寫過於抽象、簡練的邏輯。而你又不能寫得過於繁瑣,充滿大量地無用字元。

若是想使程式碼易於測試,則要先使程式碼可測試。而在這沒有測試之前,我們是難以對程式碼進行大規模重構。所以,我們就陷入了一個死迴圈,沒有測試,測試不了,沒法重構。

WHY

等等,那我們為什麼要進行重構呢?為了 ¥¥¥¥¥¥¥$$$$$$$$$ => 快速釋出軟體。

當軟體是一個產品而不是一個專案的時候,我們就需要不斷髮布新功能,以滿足客戶的要求。而為了快速釋出應用,我們需要讓每次的改動最小,測試最少,才能實現快速釋出。基於這樣一個目標,我們會發現我們的諸多實踐都是以此為出發點的。比如說,我們採用外掛化、微服務化、元件化的方式,都是為了將軟體的改動變小,這樣一來,就減少了相應部分的測試工作,從某種意義上來說,就加快了軟體釋出的流程,從而更好的實現業務價值。因此,我們的第一步就是使二進位制改動最小。而要做到二進位制改動最小,那麼我們就要做到高內聚、低耦合

因此,不論是在程式設計還是在設計架構的時候,我們都要儘量滿足 SOLID 五項原則中的:

  • 單一職責原則:它規定一個類應該只有一個發生變化的原因。
  • 開閉原則: 軟體中的物件應該對於擴充套件是開放的,但是對於修改是封閉的。

資源搜尋網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com

回到問題上

既然,我們都已經知道了,如何去重構,如何用設計模式來解決問題。那麼,我們會讓我們的程式碼變得更好嗎?不會,因為在流水線式的生產裡,每個人都能找到合理的理由。

我們日常開發的模式是:紅-綠-重構。而因為時間的原因,我們少去了重構這一步。

上吊繩驅動開發

在上吊繩(deadline)的驅動下,我寫了一這篇文章。儘管預先寫好了文章的大綱,但是有很多字是打錯的。

而對於真實的業務開發來說,要事先設計好相關功能的架構,意味著你得有充足的時間。這樣一來說,你在大的方面上才不會犯錯。可是呢,你真的有那麼多的時間可以設計嗎?你今天加的班,還好嗎?

程式碼所有權

改動了你的程式碼,我就要負責。所以,我不去修改別人的程式碼。

懼怕修改

沒有測試,難以理解程式碼背後的業務原因。外加之組織文化,導致的溝通障礙;又或者是大家都很忙,沒人願意解釋/回顧一下這一塊的程式碼。

能力不夠

對,大部分的問題本質都是人的問題。

因為你只需要按下 IDEA 的快捷鍵,就能完成上面的大部分重構工作。當然了,需要有技巧的按,而不是像 Monkey 一樣彈鋼琴。