高質(zhì)量的軟件是否值得投入
從以下幾個緯度探討高質(zhì)量軟件是否值得投入:

生產(chǎn)高質(zhì)量的軟件,一直是每一位工程師追求的目標,在日常工作中大家也投入了很多精力和時間來提升軟件的質(zhì)量,比如編寫單測、對代碼進行Review、以及重構(gòu)等等。但有時候受功能交付壓力的影響,也難免產(chǎn)生疑問(業(yè)界工程師共同的疑問):花時間提高軟件質(zhì)量,還是專注于發(fā)布更有價值的功能。Martin Fowler通過《Is High Quality Software Worth the Cost?》這篇文章針對這個疑問做了闡述,以下為文章的主要內(nèi)容。
Martin Fowler,世界級著名軟件專家,ThoughtWorks首席科學(xué)家,曾獲Jolt生產(chǎn)力大獎。起草《敏捷軟件開發(fā)宣言》,著有《重構(gòu)》、《企業(yè)應(yīng)用架構(gòu)模式》、《分析模式》、《UML精粹》等書。
Martin Fowler寫的大部分的文章是針對軟件開發(fā)工程師的,但閱讀這篇文章不需要專業(yè)的軟件開發(fā)知識,希望這篇文章對每一個關(guān)注軟件工作的人都有價值,特別是那些軟件開發(fā)團隊客戶的商業(yè)領(lǐng)袖。
貝特里奇的標題定律告訴我們,任何以問號結(jié)尾的標題都可以用“不”回答,但Martin的這篇文章打破了這條定律,他通過闡述進一步顛覆了問題本身,這個問題假定質(zhì)量和成本之間存在權(quán)衡,但在Martin看來,這種權(quán)衡并不適用于軟件——“高質(zhì)量的軟件實際上生產(chǎn)成本更低”。

通常我們會受到軟件開發(fā)不可能三角影響,在談到軟件質(zhì)量和成本的時候,往往會下意識的提到,都是緊急需求,研發(fā)周期不允許。我們來深刻討論下這個問題:
1.我們習(xí)慣于在質(zhì)量和成本之間進行權(quán)衡
Martin 指出,人們習(xí)慣在質(zhì)量和成本之間進行權(quán)衡。比如,當(dāng)更換智能手機時,可以選處理器更快、屏幕更好、內(nèi)存更大但同時也更昂貴的機型,或者可以放棄一些質(zhì)量換取更低的價格。但他也認為事無絕對,有時候也可以花更少的錢買到高質(zhì)量的東西。同時,Martin 也承認,在多數(shù)情況下,更高的質(zhì)量意味著更多的花費。

2.軟件質(zhì)量意味著很多事情
在討論軟件質(zhì)量之前,Martin 首先對“軟件質(zhì)量”做出了界定。他認為這是個復(fù)雜的問題,有很多方面可以囊括在“軟件質(zhì)量”范圍內(nèi):比如,用戶界面清晰嗎?是否簡單易用?軟件足夠可靠嗎?是否有功能上的缺陷?架構(gòu)合理、明確嗎?開發(fā)工程師是否可以輕松的找到并理解需要處理的代碼?
用戶可以判斷用戶界面是否良好;高管可以判斷軟件是否使工作更加高效;消費者會注意到系統(tǒng)是否存在缺陷,特別是當(dāng)軟件出故障時。但用戶可能無法體會軟件的架構(gòu)——這對軟件工程師來說是軟件質(zhì)量的判定標準之一。

所以,這篇文章將軟件質(zhì)量屬性劃分為外部(例如 UI 和缺陷)和內(nèi)部(架構(gòu))。區(qū)別在于,用戶和消費者可以看到什么使軟件產(chǎn)品具有高外部質(zhì)量,但不能辨別內(nèi)部質(zhì)量的高低。

3.內(nèi)部質(zhì)量看似對用戶無關(guān)緊要
換句話說,為外部質(zhì)量買單是有意義的,但為內(nèi)部質(zhì)量買單是沒意義的。用戶可以判斷他是否要為更好的用戶界面支付更多的費用,因為他們能夠評估用戶界面的好壞。但是用戶無法看到軟件的內(nèi)部模塊結(jié)構(gòu),更無法判斷它的好壞。試想一下,如果有兩個功能完全相同的軟件,且都擁有同樣優(yōu)雅的用戶界面,一個賣 6 美元,另一個售價 10 美元,區(qū)別僅僅在于后者的代碼整潔有序而前者的混亂。用戶看不到源代碼,并且它不影響程序正常運行,客戶為何要多花 4 美元購買后者,一般來說,沒有必要為更高的內(nèi)部質(zhì)量支付更多的費用?既然如此,為什么軟件開發(fā)人員還要花時間和精力來提高軟件的內(nèi)部質(zhì)量?

4.內(nèi)部質(zhì)量使軟件改進更加容易
為什么軟件開發(fā)人員會在內(nèi)部質(zhì)量上大做文章呢?程序員大部分時間都在修改代碼。即使在新系統(tǒng)中,幾乎所有編程都是在現(xiàn)有代碼庫上完成的。Martin 在此引出了“技術(shù)債務(wù)”(Technical Debt)及Cruft的概念。他認為邏輯混亂,數(shù)據(jù)難以理解,命名不規(guī)范等等,都可以稱之為Cruft,即當(dāng)前代碼與理想情況之間的差異。
Cruft :指的是程序源代碼中隨時間累積而變得無用的過時垃圾程序代碼。隨著軟件的發(fā)展,以及經(jīng)歷了修改 Bug 和重構(gòu)的若干周期之后,軟件的部分代碼已不再使用,但這些代碼仍然保留在源碼中,這種代碼稱為 Cruft。Cruft 可能是一兩行無用的代碼,也可能是整個源文件模塊。

技術(shù)債務(wù)是 Cruft 的一個常見的比喻。添加功能的產(chǎn)生的額外費用就像支付利息。清理雜物就像償還本金。這一比喻鼓勵許多人相信:與實際情況相比,Cruft 更容易測量和控制。
內(nèi)部質(zhì)量的一個主要特征之一是使開發(fā)工程師更容易弄清楚程序的工作原理,可以在幾個模塊中快速找到幾百行,能快速了解代碼的各個部分,很容易地理解它與客戶服務(wù)端的請求之間的關(guān)系,這樣就可以快速添加新功能。
存在大量技術(shù)債務(wù)的系統(tǒng),工程師需要花費更多的時間理解如何做出更改,同時提升了犯錯誤的概率。如果發(fā)現(xiàn)問題,則需要花費更多的時間去定位和解決它們。如果沒有發(fā)現(xiàn)這些問題,就會遇到生產(chǎn)故障,以后會花更多的時間來修復(fù)它們。技術(shù)債務(wù)的積累,使任何一個微小的改動都需要花費數(shù)周的時間。
5.客戶關(guān)心新功能的快速推出
Martin 指出,兩個擁有相同的功能的軟件,一個因為擁有高內(nèi)部質(zhì)量,可以每周都添加新功能。而另外一個因為內(nèi)部質(zhì)量不高,需要在技術(shù)債務(wù)中增加新功能,從而導(dǎo)致開發(fā)速度大大降低。很快,擁有高內(nèi)部質(zhì)量的軟件功能就強大得多。即便提升了價格,客戶也都卸載了低內(nèi)部質(zhì)量的軟件,轉(zhuǎn)而購買了高內(nèi)部質(zhì)量的軟件。

用戶非常關(guān)注新功能是否可以快速推出,由此看來,內(nèi)部質(zhì)量實際上對用戶和消費者來說至關(guān)重要。因為更好的內(nèi)部質(zhì)量使添加新功能變得更加容易、快速、低成本。
6.內(nèi)部質(zhì)量影響的可視化
Martin表示,內(nèi)部質(zhì)量的基本作用是降低未來變更的成本,但是編寫好的軟件需要付出額外的努力,這在短期內(nèi)確實會產(chǎn)生一些成本。他提供了兩張圖表,以可視化的方式呈現(xiàn)將內(nèi)部質(zhì)量對未來開發(fā)速度的影響。在下面的兩幅圖片中,縱坐標為軟件累積的功能,橫坐標為實現(xiàn)它的時間(成本)。對于大多數(shù)軟件來說,曲線看起來會如下圖所示。

上圖是軟件內(nèi)部質(zhì)量較差的情況??梢钥吹?,在最初一段時間內(nèi),工作進展的很快,但隨著時間的推移,添加新功能變得越來越困難。即使很小的變更也需要程序員理解大量晦澀難懂的代碼。當(dāng)修改代碼時,會產(chǎn)生意外的破壞,導(dǎo)致測試時間延長,以及出現(xiàn)需要修復(fù)的缺陷。
專注于提高內(nèi)部質(zhì)量就是為了降低生產(chǎn)力的下降。事實上,高質(zhì)量的產(chǎn)品使開發(fā)人員可以基于先前的工作輕松的構(gòu)建新功能。但這種令人愉悅的情況很罕見,因為它需要一支技術(shù)精湛,訓(xùn)練有素的團隊來實現(xiàn)這一目標。

在上圖中,增加了高內(nèi)部質(zhì)量的曲線做對比,通過比較可以看到,在一段時間內(nèi),開發(fā)低內(nèi)部質(zhì)量的產(chǎn)品比開發(fā)高內(nèi)部質(zhì)量的產(chǎn)品更具有生產(chǎn)力。那么,問題來了:這段時間有多長?Martin通過收集一些資深開發(fā)人員的意見發(fā)現(xiàn):質(zhì)量差的代碼會在幾周內(nèi)大大降低開發(fā)速度,擁有高內(nèi)部質(zhì)量的軟件隨后將遠遠反超。因此,從長遠看來,在內(nèi)部質(zhì)量和成本之間不需要花時間進行權(quán)衡。Martin根據(jù)他自己的工作經(jīng)歷發(fā)現(xiàn),即使很小的軟件工作也能從良好軟件實踐中受益。
7.即使最好的團隊也會產(chǎn)生技術(shù)債務(wù)
很多人認為,只有當(dāng)開發(fā)團隊粗心大意或犯錯時才會產(chǎn)生技術(shù)債務(wù),但實際上,即使是最優(yōu)秀的團隊也會在工作時不可避免地產(chǎn)生一些技術(shù)債務(wù)。Martin通過和最好的技術(shù)團隊的負責(zé)人聊天,證實了這一點:一個被廣泛認為是非常成功的項目,無論是在功能,時間和成本方面,客戶對交付的系統(tǒng)都感到非常滿意。同事們對在此項目的工作經(jīng)驗給出了非常積極的評價。技術(shù)負責(zé)人非常高興,但也承認系統(tǒng)的架構(gòu)并不是太好。同時給出任何一位經(jīng)驗豐富的軟件架構(gòu)師都熟悉的解釋:我們做出了很好的決策,但現(xiàn)在才明白應(yīng)該如何構(gòu)建它。
許多人將構(gòu)建軟件比作建造摩天大樓,這也是為什么我們稱資深開發(fā)工程師為“架構(gòu)師”的原因。但構(gòu)建軟件與物理世界不同,它是存在于充滿不確定性世界中。軟件的客戶只是粗略地了解在產(chǎn)品中需要哪些功能,并在構(gòu)建軟件時了解更多信息(特別是早期版本發(fā)布給用戶后)。軟件開發(fā)的構(gòu)建模塊(語言,庫和平臺)每隔幾年就會發(fā)生重大變化。映射到物理世界中就是,當(dāng)建筑物被建造和使用后,客戶要添加新樓層并改變樓層平面圖,混凝土的基本屬性也每隔一年就會發(fā)生變化。
Dora 對精英團隊的研究表明,精英軟件團隊每天多次更新產(chǎn)品代碼,在不到一個小時的時間內(nèi),即可完成將代碼從開發(fā)狀態(tài)更改為生產(chǎn)狀態(tài)。當(dāng)他們這樣做時,他們更改失敗率明顯低于低效團隊,因此他們從錯誤中恢復(fù)的速度要快得多。此外,這些精英軟件交付組織與更高的組織績效相關(guān)。
鑒于這種變化,軟件項目總是推陳出新。我們幾乎從來沒有發(fā)現(xiàn)自己在解決一個以前已經(jīng)解決過的問題。在構(gòu)建解決方案的過程中,對這個問題了解得最多,所以,團隊在花了一年左右的時間構(gòu)建它之后,才能真正理解軟件的架構(gòu)。即使是最好的團隊在他們的軟件中也會有技術(shù)債。
Martin指出,不同的是,最好的團隊其技術(shù)債較少,也及時消除了足夠多的技術(shù)債務(wù),以支撐繼續(xù)快速添加新功能。他們花時間完成自動化測試,以便能夠快速解決問題并減少時間的浪費。他們經(jīng)常進行重構(gòu),以便持續(xù)的償還技術(shù)債務(wù)。

8.高質(zhì)量的軟件生產(chǎn)成本更低
總結(jié)如下:
忽視內(nèi)部質(zhì)量會導(dǎo)致技術(shù)債務(wù)快速累積;
技術(shù)債務(wù)降低了功能的開發(fā)速度;
即使最優(yōu)秀的團隊也會產(chǎn)生技術(shù)債,但是通過保持高內(nèi)部質(zhì)量可以使其變得可控;
高內(nèi)部質(zhì)量可以最小化技術(shù)債,使得添加新功能的工作量、時間和成本都更少;
Martin強調(diào)在考慮內(nèi)部質(zhì)量時,我們只應(yīng)該將它作為一個經(jīng)濟論點來看待。高內(nèi)部質(zhì)量降低了未來功能的開發(fā)成本,這意味著花時間編寫好的代碼實際上降低了成本。
Martin再次指出,為構(gòu)建軟件高內(nèi)部質(zhì)量所帶來的“損耗”實際上是在降低損耗。我們在生活中做大多數(shù)決策的時候,習(xí)慣于在成本和質(zhì)量之間進行權(quán)衡,但對于軟件的內(nèi)部質(zhì)量來說,這種權(quán)衡是沒有意義的。因為成本和內(nèi)部質(zhì)量之間的關(guān)系不是一種尋常和直覺的關(guān)系,它很難理解,但了解它對于以最高效率開發(fā)軟件來說至關(guān)重要。

9、實際案例分析

10、拋磚引玉


