應該有很多人已經知道破窗效應這個社會學(犯罪學)的詞語,破窗效應先由社會學家JamesQ.Wilson和GeorgeL.Kelling在一篇名為《BrokenWindows》的文章中提出:

  “一個房子如果窗戶破了,沒有人去修補,隔不久,其它的窗戶也會莫名其妙地被人打破;一面墻,如果出現一些涂鴉沒有被清洗掉,很快的,墻上布滿了亂七八糟、不堪入目的東西;一個很干凈的地方,人們不好意思丟垃圾,但是一旦地上有垃圾出現之后,人會毫不猶疑地拋,絲毫不覺羞愧。”

  我們一直在喊敏捷開發,其實敏捷開發的一個很重要的目的是消除浪費,防止破窗效應的發生。事情太難,讓它簡單,更簡單。流程太重,讓它輕點,更輕點。盡量掃清開發的障礙,消滅破窗形成的環境。下面我會從軟件構建的很多方面來描述如何防止“軟件開發中的破窗”。

  臟代碼

  如果代碼不整潔,后來人很難看懂,人們往往會對難以看懂的代碼失去耐心,不愿意進一步了解。如果不能進一步了解一部分代碼,也難以改進它,這樣帶來的一個后果可能有兩點:1、這段代碼被拋棄,然后重新編寫。2、直接復制這段代碼在別的地方使用。對于第一點,會帶來軟件開發中的浪費,而且再次編寫也不可能能一部到位的編寫正確,可能會引入新的bug。對于第二點,大家都知道重復代碼是設計走向腐化的根源之一。

  如果我們在編寫代碼時能不斷的應用一些原則,確保我們的代碼易懂,自描述。在開發新特性時還不斷的使用重構手段,讓我們的設計保持一個良好的狀態。我們能防止窗戶被繼續打破。

  測試

  沒有測試,或者混亂的測試代碼都是破窗滋生的環境。

  沒有測試

  沒有測試時,當我們想對一塊代碼進行重構,我們像沒有帶保險繩走鋼絲,步履維艱,生怕一下子失去平衡,掉下懸崖。這樣在我們的心中產生了懼怕重構的陰影,久而久之,我們不去重構。后帶來的結果跟上面一段說的一樣,設計不斷的腐化,然后失去了控制。

  如果有了單元測試,有了驗收測試,當我們每做一下重構時,我們都可以從測試快速獲得反饋,每當紅條亮起時,我們知道我們破壞了一些已有的功能,我們停下來去修復,當綠條亮起時,我們知道現在處于安全狀態,可以安心的繼續重構。一切都在我們的掌控之中,我們會喜歡上重構。

  混亂的測試代碼

  有很多人覺得測試代碼不是交付給用戶的產品代碼,可以區別對待,我們不需要花那么多時間琢磨變量命名,方法命名,我們也不需要關注重復的代碼。但是……

  混亂的測試代碼跟沒有測試是一樣的,甚至比沒有測試更糟糕。我們以為我們有測試,但測試卻給我們虛假的報告,當我們發現我們的重構破壞如此之深時,已經為時已晚。即使測試能給出真實的報告,但如果測試代碼混亂,那么添加新的測試非常困難,我們會越來越懼怕添加新的測試。而且隨著產品代碼的演進,測試代碼也需要伴隨著演進,測試代碼越混亂,我們越難以修改測試,讓它反應出現在產品代碼的狀態。終于到了,大家決定拋棄測試,如是我們又回到了沒有測試作保障的日子。

  實際上,從某種程度上測試代碼的整潔程度比產品代碼的整潔程度更重要,因為有了好的測試我們可以無憂無慮的重構我們的代碼,即使現在我們的產品代碼很糟糕也不怕,因為有了測試的保證,我們知道我們可以重構過去,如果我們只有混亂的測試代碼,我們那一線重構的希望都沒有了。

  難以測試

  可測試性是衡量代碼的一項準則。既然是準則一般都很難達到,如果代碼難以添加測試,在嘗試幾次之后,我們一般都會放棄編寫測試的想法。當我們嘗試對一段代碼編寫測試時發現,這塊代碼鐵板一塊,與太多的其他類耦合,需要傳入很多重型對象的參數,比如與設備交互的代碼,與數據庫交互的代碼相耦合,這些重型對象很難模擬或插樁。沒有辦法,在進度的壓力下我們只有放棄添加測試的想法了,那么如上面一樣,代碼像草原上奔跑的野獸,失去了控制。

  編寫可測試性的代碼是困難的,要將糟糕的代碼改進成可測的代碼尤其困難。但有一個訣竅,我們可以先編寫測試,用測試驅動出我們的產品代碼,這樣一開始我們獲得了一個個測試套件,將我們的產品代碼穩穩的固定在那里,像走鋼絲時的保險繩;不僅如此,我們還獲得了可測試性的代碼。