爲何咱們不該該寫長方法

初學者在學習了語法和一堆的 API 以後,就會嘗試本身寫一些具備完整功能的程序。這個過程中很容易養成寫一個上百行甚至幾百行的方法的習慣。總的來講,這是思惟當中缺乏抽象、設計和封裝的表現。隨着編程經驗的豐富,總會有克服的一天。java

但若是想盡早克服這種狀況,像專業程序員那樣去思考,那麼要多讀一些設計代碼可讀性方面的書。業界有不少經典的書,好比《設計模式》、《重構》、《代碼整潔之道》、《實現模式》等。我強烈推薦這四本,由於我我的從中受益不淺,以爲它們都是必讀的。程序員

當一個屏幕裝不下你的方法體時,就要小心了。

長方法的壞處很是多,主要體如今如下幾個方面:數據庫

1、長方法中會包含特別多的變量。

長的方法邏輯多,變量天然也多。太多的變量常常會伴隨下面的問題:編程

一、命名困難。當你要定義4個元素類型爲 UnfinishedCustomOrder 的 List,以及4個元素類型爲 FinishedCustomOrder 的 List 時,這些變量的名字會很是長,並且眼神很差的話,後面還容易用錯,出現 bug。設計模式

二、重(chong)用變量。 初學者對變量的命名存在隨意性,同時使用變量也存在隨意性。好比定義一個 boolean flag 變量,在這段邏輯裏面用過一遍,而後在那段邏輯裏面再用一遍。學習

三、重複的變量。 一個方法長到必定程度後,常常會出現寫到後面忘了前面的狀況。因而出現好比說,又從新去數據庫查詢以前已經查過一次的內容的狀況。這種現象特別容易出如今反覆修改過屢次,並且每次都是不一樣的人來改的代碼中。編碼

四、改了變量內容可是忘了。 好比下面這種:設計

public void processAllOrders() {
    List allOrders = ...;  // 查詢全部訂單
    ...
    // 排除掉已完成訂單。注意這條語句甚至可能被委託到
    // 另外一個方法執行,本方法中徹底看不到。
    allOrders.removeAll(finishedOrders); 
    ...
    ... // 兩百行代碼後
    ...
    ...
    ...
    // 此時另外一個程序員接手實現需求變動。他只關注這部分要改的,
    // 僅看變量名就認爲 allOrders 依舊包含全部訂單,因而出錯
    allOrders.forEach(order -> {...});
    ...
}

這屬於嚴重違反編碼原則的狀況。有人說,是否是接手的這個程序員閱讀代碼不認真啊?請注意,閱讀代碼自己是很是消耗心智的。讀代碼不是讀小說,要嚴絲合縫的理解代碼的行爲。若是代碼可讀性不好,那麼理解出錯的機率天然也會大,更別說上面的例子中,變量名存在誤導性,這能怪閱讀者嗎?調試

2、長方法會有不少出口。

一個長方法的執行過程其實是分幾個階段完成的,每一個階段可能有本身的遠程調用、數據校驗和拋出異常,這會致使長方法中有不少出口。一個方法有多個出口,大多數狀況下是很差的編程習慣,主要體如今:code

一、調試斷點會出現不肯定性。 好比你在某行打了個斷點,但調試的時候發現沒有執行,由於方法在這以前就經過某個出口結束了。反覆嘗試尋找斷點下降了開發效率。

二、反覆構建返回值。 若是方法是有返回值的,那麼多個出口的返回值固然是不同的,它們的前面必然會出現相同的構建這些返回值的過程。一旦這個過程須要改動,那麼遺漏某處就意味着BUG。

三、有的 return 語句寫在層層縮進當中,會給閱讀帶來困難。 由於當你讀到這裏時,會發現腦海中構建的一層層的邏輯,到了這裏忽然被完全中斷了,在某個場景下,方法在這裏結束。因而你必須牢記,後面的代碼中的全部邏輯都要排除這個場景。這樣的結束若再來個兩三次,恐怕能把你逼瘋。

我以前說的是大多數狀況。那麼剩下的狀況是指什麼呢?主要是校驗方法,好比:

public boolean validate(Order order) {
  if (order == null) {
    return false;
  }
  if (order.isCancelled()) {
    return false;
  }
  ...
  return true;
}

此類方法有多個出口我以爲是能夠接受的。

3、閱讀長方法很是費神。

咱們閱讀方法時,會在腦海中構建每一個參數和變量,理解它們的演變過程。這個時候每多一個變量,都是增長了一分腦力負擔。要知道,人與人之間的腦力承受能力是不一樣的,就算同一我的,在不一樣的精神狀態下的承受能力也有差異。因此,若是一個軟件產品或項目,想要在整個生命週期中減小出錯的可能,那麼就有必要提高代碼可讀性,換句話說,就是減小閱讀代碼的腦力負擔。代碼可讀性是風險控制的一部分,長方法爲項目增長了風險。

如何克服

上面說的就是一個方法太長會帶來哪些問題。要克服的話,首先是看我最開始推薦的那幾本書,其次是培養本身的抽象思惟,從具體的功能中提取出多個層次的抽象邏輯,將功能的實現拆分到不一樣的抽象層。

相關文章
相關標籤/搜索