代碼的兔子理論
曾經和我一起共事的人都知道,我把源代碼庫的簽入工作擺在非常高的位置。這樣做的理由很簡單:一旦代碼被簽入了,代碼就有了它自己的生命。簽入代碼類似于你和其他人分享代碼,一旦分享出去,就難以預測這些代碼會發揮什么作用。很難,但不是不可能,因為有一種現象實際上是我保證要出現的。
多年來,我和朋友、客戶分享過我所謂的、代碼的兔子理論。這個理論是指,當你沒有留意時,代碼會繁殖,同樣,當你沒有留意時,兔子也會繁殖,二者沒有什么不同。這不是說繁殖代碼是好的,還是壞的——不管質量如何,這是所有代碼的特點。使其優劣的是那些被繁殖的代碼。
支撐代碼的兔子理論的原因在于軟件工程師的工作方式。我們很少,倘若有的話,從一個完全空白的文件開始寫代碼。我們通常從拷貝一個現有文件開始,隨后修改以得到我們想要的結果。重申,這和好與壞無關,它僅僅是創建類似于其它代碼的某種代碼的、最有效方式。
那么,你從哪里去尋找能拷貝的已有代碼呢?在同一個源代碼庫里。你的源代碼庫虛假的承諾是,它包含的每處代碼都是“好的”。為了完成你的任務,就找到類似的代碼、拷貝、修改,然后搞定。深入同一個代碼庫,貌似是代碼質量的一種安全機制,但是實際上,這是無法保證的。
當你簽入一個文件時,另一個相似文件的出現是不需要太長時間的。一旦出現了同樣代碼的兩個例子,那么第三個文件出現的機會就增加了。一旦第三個出現了,代碼就在你的代碼庫建立了基礎,并被視作一種認可模式。畢竟,如果我們在很多地方都在用這種方法做著同樣的事情,那么它一定是做這種事情的正確方法……對吧?
追溯到 2005 年,我找到一些代碼,它們貌似符合我的任務。隨著我高亮這部分代碼以拷貝到我自己的文件,我注意到,我已經跳過了它前面的長注釋。然而我不記得注釋原話了,大意是說:
不要拷貝這段代碼!我沒搞清楚完成這個功能的其它方式,我們只是在一個地方這樣做了,因此看起來是沒事的。如果你覺得你需要在其它地方也這樣做,那么你應該找到正確的方法。你絕對不要將這段代碼拷貝到其它地方。
</blockquote>我笑了笑……然后開始痛心。你是說,我不得不搞清楚該怎樣用其它方法來做同樣的事情?這是不公平的。前任工程師知道他們沒有妥善地解決這個問題,而將其作為地雷留給了其他人。當我踩到它上面時,它就這么發生了,現在我不能挪動我的腳,直到它被安全地拆除。
這就是把糟糕的代碼簽入代碼控制系統所帶來的問題:它增加了人們找到它并拷貝它的可能性。一旦它被拷貝了一次,也就增加了被再次拷貝的可能性,如此反復。在你明白之前,糟糕的代碼已經滲透到了代碼庫的所有部分,難以摘除。
隨著向同樣代碼庫提交代碼的人數增長,這個問題也在增長。當你有一個規模較大的團隊時,對代碼控制里該結束的代碼的管理就顯得尤為重要了,因為它很快就要繁殖了。同樣,你想確保被簽入的代碼有著盡可能高的質量,也體現了你想讓其他人要做到的標準。
為了保持代碼庫的理智,你首先要關注的是怎樣阻止第一段糟糕代碼進入代碼控制。通過自動化的執行或拒絕對于這個結果是重要的。你越是能夠自動化并在物理上阻止代碼進入代碼庫,每個人就越是安全。當然,有一些模式是難以阻止的,尤其是它們之前從來沒有遇見過。這就是代碼審查的原因。和人們的眼睛比起來,沒有什么奇怪的、更好的檢測器了。
當然,某些模式不一定是“糟糕的”,你只是不想讓其他人那樣做。考慮一下第三方資源庫的情況,比如 jQuery。假如你不想讓團隊成員使用 jQuery,因為你已經建立了 jQuery 所能完成的同樣任務的模式。這時候,有人認為,使用 jQuery 會更好,因此加了進來。問題來了:如果 jQuery 加入了代碼庫,一定有其他人也要使用它。這樣,你將做一些不在計劃內的工作,這差不多是一件糟糕的事情,尤其在大型團隊里。引入一種新資源庫,意味著需要學習它的怪癖、bug、最佳實踐等所有方面,并且總是沒有時間去學習。
根據我在 Box 目前的角色,我因為掛在嘴邊的一句話而知名,“沒有意外的標準。”我們不接受“本該是那個樣子”的一些東西,僅僅因為它們在很多地方流行。當我們看到出現這種情況時,我們就加以制止、討論,或者把它定做“規則”或摒棄它。在錯誤情況擴大之前,我們就適當地更新代碼。通過自動化、代碼審查和代碼研討會【注 1】,我們可以密切注視代碼,以確保我們保持一致。
用這種方式管理代碼庫貌似需要大量工作,但是,如果不這樣做,實際上需要更多的工作。讓代碼在人工干預下增長,是對付大麻煩的良方。工程師盡量做正確的事情,他們是通過拷貝代碼控制里的已有代碼完成的。這樣做是完全自然和符合期望的。這就是你為什么想確保被拷貝的代碼代表了你想讓他們去做的以及你準備好了有更多的代碼拷貝出現的原因。
就像兔子,如果你準備繁殖了,就沒有大問題。如果沒有人注意到麻煩出現的苗頭,繁殖卻發生了,這就是問題產生的時候。
- 注1:參考作者在 Box Tech Blog 寫的另一篇文章《Effective learning through code workshops》。
本文由用戶 encn 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!