Clean Code 告訴你什麽是好代碼">Clean Code 告訴你什麽是好代碼

分類:IT技術 時間:2017-10-01

歡迎加QQ群討論:157672725

前言

最近在團隊推行Code Review,遇到一個頭痛的問題。當向夥伴的代碼提一個comment時,他們不解為什麽需要這樣改。細細想來,是他們不知道何為好代碼,也不知道自己的代碼有哪些 “壞味道” 。因此,分享了幾期Clean Code,團隊受益良多,故成此文。

Clean Code

由於Clean Code篇幅較長,故先安排如下我認為較為重要的幾點:

  • 命名
  • 函數(方法)
  • 註釋
  • 對象、數據結構

命名

命名有許多規則,但總結起來就是 “有意義” 才是硬道理。

名副其實

Int d;//逝去的時間

這句代碼的問題在於d沒有表達好逝去的時間這個概念,故需要註釋。請記住 “名副其實就不需要註釋”

Int elapsedTime;

再來看個例子 誰都很難猜出其意義,看看小優化後的結果 基本看清了意義,這就是命名的重要性。細心的朋友還會發現這段代碼的一些瑕疵 :這裏的4是什麽鬼?習慣性我們管它叫 “魔法數字” 還是覺得有點問題,再優化 對比下最早的代碼,相信你會有感覺了。

避免誤導

生活中的場景也常出現在Code中,看下圖,你的Code是否也出現這樣的尷尬呢?那就Make it clean

是否傻傻分不清了呢? 再來個

accountList

我知道你想說,這有什麽問題。是的,如果你不是做Java開發,不會知道鏈表叫List,所以如果你不是用鏈表存儲account,請不要用其修飾,或許這個時候你使用acountGroup會更好些。 該點需要在具體開發環境下因地制宜

有意義的區分

Product
ProductInfo
ProductData

可以想象下,當一個項目中同時出現以上三個類的時候,你是如何區分開的,反正我是沒有這個能力。類似的還有

game
theGame
name
nameString

分享時,夥伴說nameString有什麽問題。我反問說難道你的名字會是Float型的?你懂了吧。

前綴

m_desc

有人提出加m前綴表示該變量為私有變量。 我想說:你的變量很多?需要區分私有的還是公有的?如果你的變量很多,那就要想想是不是沒設計好類,沒有遵循 單一職責原則 ,另外私有和公有變量編譯器會幫忙高亮顯示區分的,不需要自己來區分(若某些編譯器無此特性,怪編譯器去)。

命名慣性

命名需要 註重詞性 類名:名詞 or 名詞短語 方法名: 動詞 or 動詞短語

每個概念對應一個詞

在一個模塊中不要使用兩個相似的概念來表達不同的操作。我在一份代碼中看到過一個類中同時出現以下三個詞打頭的方法

fetch
get
retrieve

請問那個才是真的獲取值的方法?我實在分不清。

使用領域名稱

使用領域命名能讓夥伴更明白你的程序結構(關於 領域 這個概念,不熟悉的可以看下一本書叫 《領域驅動設計》 ,俗稱DDD) 舉個例子,比如你使用訪問者模式來構建用戶系統,那麽

AccountVisitor

就顯得明確、易懂

抵制縮寫誘惑

縮寫需要註意,適當的縮寫是可以的,但是要保證縮寫後的詞語仍然能表達其本意。舉個有意思的例子

ABCDEFG

這也是個縮寫,但是乍看這個真不知道是什麽的縮寫,直接公布答案吧

小結

命名是永恒的難題,我提幾個建議吧

  • 多看開源代碼,積累好的用詞
  • 不懂的詞就查下詞典,好過你自己想的
  • 做個自己的開源項目,讓別人給你建議
  • 做好積累、再積累、還是積累

函數(方法)

函數的第一條規則是要短小,第二條規則還是要短小。

短小

那到底多短合適呢?歷史上出現過幾個標準

  • 一屏
  • 100行
  • 50行
  • 20行 有人問我為什麽會差這麽多,我的回答是:以前的屏幕分辨率那麽低,一屏也就20-50行之間吧,所以以前一屏的說法也是合理的。 對於行數,行業沒有一個固定的標準。我所知道的Oracle建議是50行,Bob大叔的建議是20行。

代碼短小,好處自然很多。

  • 單元測試覆蓋率高
  • 每個函數一目了然,只做一件事
  • 有利於函數中的代碼都在同一個抽象層級

只做一件事

函數應該做一件事。做好這件事。只做一件事。那麽如何判斷只做一件事? 請問這個函數做了幾件事?夥伴的答案是

1.判斷是否為測試頁面
2.加入測試數據
3.渲染頁面

你的答案是多少呢?其實答案是只做了一件事,主要是沒有看清 一件事 OR 一件事的多個步驟 ,關於這點,大家要好好體會。

另外一個判斷是否只做一件事的好方法: 是否能再次分離出新函數

同一個抽象層級

關於層級,比較難講明,直接看例子吧 再看一個版本 你會發現看第二個版本的代碼,明顯舒服很多。因為第二的版本的三句代碼都在同一個層級。而第一個版本的代碼中的第一句是設置roundView的某個屬性,但是最後一句卻是在設置bubbleView,層級不同(roundView與bubbleView才是同層級)

使用描述性名稱

如果長一點的名稱可以更加清晰,不要猶豫,用清晰的吧(註意是要有意義的)

calculate
calculatePrice

相比起來calculatePrice就好很多。 再來看個例子

addComment
addCommentAndReturnCount

你不是說長一點更清晰嗎,那addCommentAndReturnCount很好吧。 關於這點大家要註意,如果你 需要用and、or之類的介詞來修辭函數時,要考慮下你是否違背了單一職責原則

參數個數

0個最好, 1個次之, 2個還行, 3個以上不是太好了。 參數與函數名位於不同的抽象層級,它要求你必須了解目前並不特別重要的細節。 解決辦法有許多,比如某些場景可使用 DTO

嵌套層次、分支過多

嵌套、分支過多會讓代碼變得很難理解,解決的辦法有如下:

  • 衛語句
  • do-while,引入break
  • if-else if-then
  • 提取函數
  • 以子類取代類型代碼
  • 以多態取代條件式
  • … 具體可根據項目特點選用

分割指令與查詢

set這個函數很不明確的是到底是設置成功了返回true,還是名字存在返回true,但真正的問題在於,它是個指令但是摻雜了查詢的功能。 將查詢和命令分離後,代碼便清晰很多了。

小結

如何寫出好的函數

  • 先寫對的,再寫好的
  • 對 =》 單元測試 =》識別壞味道 =》重構

註釋

“別給糟糕的代碼加註釋 — 重新寫吧。” –Brian & P.J. “註釋總是一種失敗” –Bob

用代碼來闡述

感受兩段代碼會發現 代碼即註釋 的美

壞註釋

先來看看什麽是壞的註釋

喃喃自語

這註釋絕對是給自己看的

多余的註釋

解釋跟沒解釋一樣,不如代碼來的簡單明了

誤導性的註釋

你在誤導吧

循規式註釋

這個一定要註意,循環式的註釋完全多余(除了做sdk、開源)

括號後的註釋

如果括號後需要註釋,只表明你這段代碼太長了,需要做的不是加註釋,而是將它變短。

歸屬於署名

Git、SVN知道是你提交的,不用這樣刷存在感

註釋掉代碼

註釋掉的代碼,只會讓修改你代碼的人蒙圈,如果你覺得這段代碼有可能以後會用,也不用擔心,Git、SVN會幫你找回來

信息過多

面向對象講究,暴露操作,隱藏實現,如果你還要註釋這些信息,表示你沒有封裝好。這些信息,可考慮放個鏈接或者其他的簡短提示,太長的註釋,別人懶得讀、也難讀懂

好註釋

看了那麽多壞註釋,來看看什麽是好的註釋

法律信息

提供信息

對意圖的註釋

闡釋

警示

TODO註釋

放大

對象、數據結構

數據抽象

將變量設置為私有(Private),主要是不想讓其他人依賴這些變量。所以,不要隨便給變量添加賦值方法和取值方法(set/get方法),這樣其實是把私有變量公之於眾。 隱藏變量和實現,並不是在變量與外界之間放一個函數層那麽簡單。隱藏關乎抽象。 類並不簡單地用賦值方法和取值方法將其變量推向外間,而是暴露抽象接口,以便用戶 無需了解數據的實現而能操作數據本體。 要以什麽方式呈現對象所包含的數據,需要做嚴肅的思考。隨便加賦值方法和取值方法,是最壞的選擇。

數據、對象的反對稱性

前者是一種過程式代碼,後者是面向對象式代碼。我們會發現假如要添加一個新形狀的話,後者絕對是不錯的選擇,因為以上代碼都不需要修改,只需寫一個新形狀類,這符合“開放–封閉”原則。然而假如添加一個計算周長的功能的話那就杯具了,因為這樣子每個形狀類都得改動。但是假如是用過程式代碼的話只需要添加一個新函數。

過程式代碼(使用數據結構的代碼)便於在不改動既有數據結構的前提下添加新函數。 面向對象代碼便於在不改動既有函數的前提下添加新類。 一切都是對象只是一個傳說

組織

  • 公共靜態變量
  • 私有靜態變量
  • 私有實體變量
  • 公共函數
  • 私有函數 自頂向下原則 這裏為什麽沒有寫公有實體變量是因為,其不建議出現在代碼中。

短小

函數的短小標準是行數,那類是什麽呢?答案是 職責 類需要遵循單一職責原則

內聚

如以上代碼,內聚性高,除了size方法外,其他方法都使用了兩個實例變量。 內聚: 模塊內部各個元素彼此結合的緊密程度(類中方法和變量間的結合程度) 保持內聚會得到許多短小的類 當一個類喪失內聚性時我們應當拆分它

總結

Clean Code能幫助團隊構建代碼質量體系,有助於開發的各個環節(靜態分析、持續集成、Code Review…)。當然,對個人的能力提高也很有好處,建議大家都應該熟悉。等團隊Code Review一段時間後,有其他收獲的話,再給大家分享。 預祝大家國慶節快樂!

  • ← Previous Post

Tags: 代碼 Code 命名 Clean 需要 註釋

文章來源:


ads
ads

相關文章
ads

相關文章

ad