Categories
程式開發

不要讓“Clean Code”更難維護,請使用“Rule of Three”


“我們如何證明,通過遵循“代碼整潔之道”(Clean Code)就可以編寫更多的代碼呢?”

當人們試圖將“代碼整潔之道(Clean Code)”的原則應用於現有的代碼庫時,我經常會問這個問題。

我認為這是合情合理的。

當我們開始重構遺留代碼時,通常會將內容提取到較小的方法中。然後再將方法提取到類中。很快,我們可能就能感覺到原來30行的方法現在已經分散在不同的類中。

我們想知道的是:這在實際上是否是更容易維護了呢。

也許我們是一個小團隊。也許我們必須支持我們繼承的一個相對較大(並且沒有文檔記錄的)的代碼庫。

尋求代碼可維護性是一件好事。

錯誤在於,認為代碼可維護性與代碼行數(lines of code,LOC)相關。 LOC可能是一個有趣的度量指標,但它並不是關鍵所在!

不要使用LOC作為代碼可維護性的度量指標。

簡短的代碼並沒有更好的可讀性。

如果你對此有所懷疑,那麼應該看看“短碼之美(Code Golf)”。

當我們進行“短碼競賽”時,我們的目標是找到一些聰明的技巧,用最少的代碼字符來實現相同的功能:

// 31 个字符  
Math.floor(Math.random() * 100)

// 21 个字符 
~~(Math.random()*100)

// 19 个字符 
Math.random()*100|0

但當然,這只是一個“strawman”的論點!

我相信我們不會以“短碼競賽”的方式來編寫生產中的代碼。

然而,有一個重要的原則,我們需要記住:

代碼不是我們告訴計算機怎麼做的方式;而是告訴另一個程序員我們想要計算機做什麼的方式。

簡而言之:編寫代碼是要供他人閱讀的

易於理解的代碼才是易於維護的代碼。

還是,難道我們還不夠聰明,而無法閱讀冗長的函數嗎?出於可讀性的考慮,添加一堆一次性使用的助手函數又有什麼好處呢?

如果這些問題能引起我們的共鳴,那麼我們需要知道一個秘密……

過早的重構是項目失敗的根源

任何極端的做法都是有害的。

即使是遵循“代碼整潔之道”的原則。

我們正在嘗試一些事情。當然,我們可以按照最佳實踐來重構代碼,但這同時也會增加了維護的難度。如果我們為了達到此目的而只是封裝了一個條件語句,那麼它可能沒有幫助!

不,我們不應該為了可讀性,而將所有內容都提取到“一次性助手函數”中。如果我們每次閱讀代碼時都需要閱讀這些函數的主體,那麼這一點也沒有幫助。它只會是阻礙。

我們應該做的是,創建正確的抽象。

正確的抽象,正確地劃分職責。它們闡明了代碼的意圖。它們可以防止代碼重複。

當我們找到正確的抽象時,我們會覺得這4個類實際上比原來的30行代碼更易於維護。

但是,要找到正確的抽象確實很困難。因此,這就是我們應該關注的重點。

壞的抽像比重複更糟糕

你是否聽說過“不要重複你自己(Don’t Repeat Yourself,DRY)”原則?

這是一顆共同發展智慧的明珠,而且非常有效。但它也經常被誤解。

兩段代碼看起來是一樣的,但卻代表了不同的概念。不同的抽象。在這種情況下,重複是偶然的。保留重複會更好。

“重複與錯誤的抽象相比,代價要小的多”

—— Sandi Metz, 所有的小事

什麼時候應該將代碼提取到函數/方法/類中?什麼時候應該保留重複?我們怎麼知道我們有正確的抽象呢?

使用“Rule of Three”

Also called Write Everything Twice (WET). Pun intended.

這也稱為“什麼都寫兩遍(Everything Twice,WET)”。這是個雙關語(與DRY原則相對)。

“三次重複攻擊,就重構”

重構原則“Rule of Three”是一條經驗規則,當我們有疑問時可以使用它。

在引入抽象之前,請等待第三次重複的出現。出現重複的次數越多,就越容易找到要提取的共性。

遵循“Rule of Three”原則。它能使我們更容易地找到正確的抽象。

超越“Rule of Three”

這裡的“Rule of Three”原則是為了提醒我們,重複是可以的。

這也有點教條。就像“代碼整潔之道”的原則一樣,不要在任何時候都盲目地100%應用它。

有時,即使出現了3次重複,我們也可能找不到正確的抽象。不要強求對代碼庫進行過度的抽象。如果我們不能給它起一個清晰的名字,它就確實不夠清晰。

毫無疑問,違反規則是可以的。等待更多的重複。

寧可重複,也不要錯誤的抽象。不要為了抽象而創建抽象。

如果抽像不好,則必須使用布爾型的參數和if語句來簡化它的實現,以覆蓋新的用例。這只是一種暗示、一種警告,告訴你你走錯了方向。

如果我們還沒有找到抽象的話,那也沒關係。當我們有了更多的上下文時,仍可以重構它。等著瞧吧!

原文鏈接:

https://understandlegacycode.com/blog/refactoring-rule-of-three/