程序員最重要的技能:知道什么時候不寫代碼
本文指出大多數(shù)程序員都容易犯下的錯是,因為對編程的興奮,不知道什么時候應該對編碼說“不”。程序員需要知道什么時候不需要編碼,并從項目中刪除所有不必要的代碼,這將讓工作變得更容易,并使軟件壽命更持久。
對什么說“不”
學會說“不”是一個好的開端。
但是到底是對什么說“不”,又是什么時候適合說“不”呢?
這的確是大多數(shù)程序員,甚至是那些高級程序員都很容易混淆的一個重點。
作為一名程序員,編寫代碼無疑是你職業(yè)中最重要的部分。在你的編程生涯中,你不可避免的地將會處理各種關于不同類型代碼的請求。而每個請求都可能會迫使你做出一些艱難的決定。這些看上去一切正常,似乎也沒什么錯。畢竟,這是所有人對你的期望:作為程序員就該編寫代碼。然而,這里有一個問題:你是否應該編寫向你請求的所有代碼?
這個問題給我們引入了一個程序員所能學到最重要的技能:
知道什么時候不編碼可能是程序員所能學到最重要的技能。——《可讀代碼的藝術(shù)》
對上面這句話,我完全同意。這是為什么呢?
編程是解決問題的一門藝術(shù)。因此,自然而然地,程序員成為了問題解決者。作為程序員,當我們面前有一個新問題有待解決,或因為任何其他原因需要我們寫出代碼行時,我們會因為使命感而感到興奮。
有這種興奮也是再正常不過的,畢竟我們是程序員,我們就是喜歡寫代碼。
然而,對編寫代碼這件事過于興奮就會讓我們變得盲目。這種情緒會讓我們忽視了一些重要的事實,而這些事實可能導致更大的問題,讓我們在未來不得不再去解決這些更嚴重的問題。
那么,我們往往容易忽略哪些重要的事實呢?
你寫的每一行代碼都是:
- 必須被其他程序員閱讀和理解的代碼
- 必須被測試和調(diào)試的代碼
- 會增加軟件缺陷的代碼
- 可能會在將來引入新 bug 的代碼
正如 Rich Skrenta 所寫的,代碼是我們的敵人:
代碼可謂是邪惡的。代碼會腐爛。代碼需要定期維護。它們總是包含有待發(fā)現(xiàn)的 bug。而新特性的添加總是意味著舊代碼必須進行調(diào)整。
代碼量越大,bug 所能藏身的地方就越多,且 checkout 或編譯代碼所需的時間就越長,而新員工理解這個系統(tǒng)所需要的時間就越長。這還意味著,如果你需要重構(gòu)代碼,需要挪移更多東西。
此外,更多的代碼通常意味著程序擁有更少的靈活性和更少的功能。這一點乍一看是違反直覺的,但確實很多時候,較之一個才華平庸的程序員所編寫的冗長混亂的代碼,一個簡單優(yōu)雅的解決方案能運行更快,且其功能會更通用。
代碼都是由程序員編寫的。所以編寫更多的代碼往往需要更多的程序員。而程序員之間的溝通成本是以 n²的速度增長的,然后,這些程序員寫的所有代碼都添加到系統(tǒng),在擴大系統(tǒng)功能的同時,也會增加整個軟件工程的運營成本。
我說的這些都是真的,難道不是嗎?所以,那些用他們的生產(chǎn)效率和編程思維來激勵你的偉大程序員們,都是那些知道什么時候該說“不”,什么時候不編程的人。易于維護、持續(xù)壽命長、不斷幫助用戶實現(xiàn)功能的那種軟件,應該不包含任何不必要的代碼行。
最好的代碼其實是沒有代碼,而最有效率的程序員知道什么時候不應該編碼。
怎么知道什么時候不應該編碼呢?
當你投身一個項目的時候,很自然地會感到興奮,滿腦子都是所有那些想要實現(xiàn)的炫酷功能。但是程序員往往容易高估了他們的項目真正需要多少特性。于是就造成系統(tǒng)中有許多未完成或未投入使用的特性,甚至有些特性純粹只是讓應用程序變得過于復雜。你應該首先了解什么對你的項目是必要的,以避免犯下這種錯誤。
了解軟件的用途及其核心定義,這是知道什么時候不應該編寫代碼的第一步。
請容許我舉一個例子。假設,你的軟件只有一個目的:管理電子郵件?;谶@個目的,發(fā)送和接收電子郵件是該軟件項目的兩個基本功能。你就不應該期待這個軟件同時也能管理你的待辦事項清單,難道不是這樣嗎?
因此,你應該拒絕與此核心定義無關的任何可能的特性請求。在這種時候,可以確切地肯定你明白什么時候不應該編寫代碼。
永遠不要隨意擴展軟件的用途。
一旦知道了什么內(nèi)容對你的項目是必不可少的,那么在下一次評估所有可能出現(xiàn)的代碼請求時,你會意識到這一點。你將清晰地知道編寫代碼的需求是什么。這個系統(tǒng)應該實現(xiàn)哪些特性?哪些代碼值得編寫?于是,你可以勇敢地去質(zhì)疑一切,因為你確切地明白那些不必要的代碼是如何拖垮你的項目的。
知道什么時候不應該編碼可以使你的代碼庫更小。
當你啟動一個新項目時,一開始系統(tǒng)里只有兩三個源文件。一切看起來都那么簡單明了。而編譯和運行代碼僅僅需要幾秒鐘。這時,你完全清楚在哪里可以找到你想要的東西。
然后,隨著項目的增長,將會有越來越多的源文件填滿你的目錄。其中每個代碼文件動輒就包含數(shù)百行代碼。為了更好地組織這些代碼,你很快就需要設立多個目錄。記住哪個函數(shù)調(diào)用其他函數(shù)變得比以前更加困難,而追蹤 bug 需要付出更多的工作量。管理這個項目變得越來越困難,于是,你需要更多的程序員來幫忙。然后,溝通開銷 隨著程序員數(shù)量的增加而急劇增加。你的項目會變得越來越慢。
最后,這個項目變得非常龐大。添加新特性變?yōu)橐环N痛苦。因為即使是很小的改變也需要花上幾個小時。修復當前的 bug 總是會引入新的 bug。你的項目開始趕不上最后期限……
現(xiàn)在,這個項目對你來說是一場折磨。為什么會變成這樣?
這都是因為你不明白什么時候不應該編碼。于是你對所有可能的特性請求都毫不猶豫地說“是”。你是盲目的。編寫那些不必要的新代碼會讓你忽略軟件最必不可少的核心內(nèi)容。
這聽起來就像恐怖電影一樣,是嗎?
但如果你一直對每件事都說“是”,這種恐怖的情況就會發(fā)生。你需要知道什么時候不需要編碼,并從項目中刪除所有不必要的代碼。這將讓你的工作變得更容易,并使你的軟件的壽命更持久。
我生產(chǎn)效率最高的一天就是扔掉了 1000 行代碼。——Ken Thompson
我知道,要明白什么時候不需要編寫代碼,這點做起來是很難的。即使是高級程序員來說也并不容易。也許,我在這篇文章中所寫的東西對于初級程序員來說很難理解,但我認為本文的敘述方式還是能讓人理解這些要點的。
我明白,有的程序員或許剛剛開始你的編程生涯,想在編碼領域大展身手。你對此感到興奮不已。這點無可厚非。作為軟件從業(yè)者,希望你永遠不要失去這種興奮感,但也請不要忽視重要的事實。我們需要從自己的錯誤中吸取教訓。你和別人一樣,也會犯錯誤,也會從自己的錯誤中吸取教訓。但如果你能從我們的經(jīng)驗中學習,至少能更事半功倍。
請繼續(xù)編碼吧,但要知道什么時候需要對編碼說“不”。