
之前有看到同學(xué)寫到自己看了 《Clean Code 》這本書的感受,他說看完這本書基本沒有什么收獲,這本書適合那些已經(jīng)很有工作經(jīng)驗(yàn)的人看 ,可是那些老人們又總是推薦新人來看這本書,這就讓人很費(fèi)解。不過,不同人之間會因?yàn)橹R背景以及理解和領(lǐng)悟能力不同,對同一事物有不同的感受。那我一向是那種不會拿別人的感受當(dāng)結(jié)論的人,那看這本書到底給人的感受是什么,我還是打算自己親自去一探究竟。
什么是整潔代碼?
一些經(jīng)驗(yàn)豐富的程序員認(rèn)為:
- 優(yōu)雅高效
- 有意義的命名
- 只提供一種而非多種做一件事的途徑
- 盡量少的依賴關(guān)系
- 精致和簡單的代碼。
那么我認(rèn)為整潔的代碼應(yīng)該是:干凈的,風(fēng)格統(tǒng)一的,命名語義化的,邏輯結(jié)構(gòu)清晰的,代碼塊短小簡單精致的。
整潔代碼的意義?
易于閱讀理解、重構(gòu), 整潔的代碼也是質(zhì)量的保證,讓別人一目盡覽,而非殫精竭慮的研究。
第一章:整潔代碼
讓營地比你來時更干凈
- 糟糕的代碼的代價: 糟糕的代碼到最后難以維護(hù)和管理,會毀了項(xiàng)目,甚至公司。
- 發(fā)現(xiàn)糟糕的代碼及時修正,因?yàn)楹苡锌赡埽?strong>稍后就等于永不
- 整潔代碼應(yīng)該是:
- 能通過所有的測試
- 沒有重復(fù)代碼
- 包括盡量少的實(shí)體,比如類、方法、函數(shù)等
- 有意義的命名是體現(xiàn)表達(dá)力
第二章 : 有意義的命名
名副其實(shí): 一個好的名字就能體現(xiàn)它的功能,就能輕易知道它做了什么
-
避免使用誤導(dǎo)的名字:
- 使用表意的名字
- 不要在名稱中出現(xiàn)容器類型名,如不要有accountList這樣子的
反例: accountList 、BunchOfAccount 正解:accounts- 不要使用非常相似的命名,即不同之處較小的名稱
-
命名之間做有意義的區(qū)分
反例: Product類、ProductData類 、 ProductInfo類 theMessage、message Data , Info就像a、 an、the一樣,是意義含混的廢話,廢話丟失冗余 這樣的雖然它們的名稱不同,意思卻無區(qū)別,無法區(qū)分它們的意思- 命名時加上【明確的約束】加以區(qū)分 和其它變量的不同之處
-
使用可讀的單詞命名
- 不要自造不存在或者奇奇怪怪的詞
- 使用恰當(dāng)?shù)挠⒄Z單詞
-
避免思維映射
- 一般使用解決方案領(lǐng)域術(shù)語,而不是問題領(lǐng)域術(shù)語 (這個感覺還是有點(diǎn)費(fèi)解的)
類名 、對象名 應(yīng)該是 【名詞 或者名詞短語】
函數(shù)名 應(yīng)該是 動詞 或者動詞短語,如 加上get、set、is前綴
-
別用雙關(guān)語:一詞一意 規(guī)則
- 不要將同一單詞用于不同的目的,同一術(shù)語用于不同的概念
舉個栗子: 有一個add方法,是增加值得作用 還有一個add方法,是連接兩個現(xiàn)存值來獲得新值 這樣就是雙關(guān)語了 正解: 如果是把單個參數(shù)放到群集中,應(yīng)該把和這個方法叫做insert,或者append之類的 -
添加有意義的語境
- 良好的命名應(yīng)該給讀者提供語境
有名為: firstName, secondName,street,houseNumber, city,state 的變量
把它們放一起的時候,很明確是構(gòu)成了一個地址。但是如果在某個方法中看見孤零零一個state變量,就一定不會推斷出它是某個地址的一部分了。
正解:
* 可以添加前綴:addrFirstName,addrSecondName, AddrState等,以此提供語境,至少讀者可以明白這些變量是某個更大結(jié)構(gòu)的一部分。
* 更好的解決方法是:創(chuàng)建類名為Address 的類。
其實(shí)讀了這些感覺還是有感受和收獲的,原來命名還是有這個多的講究,以前都感覺命名很痛苦,不知道從什么角度出發(fā)命名更好更合適,現(xiàn)在起碼是有些sense的了,知道了命名的好壞之分,和命名的出發(fā)點(diǎn)。
對本書的感覺,其實(shí)感覺本書有些地方還是不太能理解的(不包含在本筆記中),好像作者只是一提,甚至都沒有給出結(jié)論,看完就很懵逼。
第三章:函數(shù)
- 短小
- 20行封頂最佳
- if,else等語句塊內(nèi)應(yīng)該是一個函數(shù)調(diào)用
- 函數(shù)只做一件事
- 每個函數(shù)中的語句都要在同一抽象層級上, 一眼就能看出來
(如果混雜不同抽象層級,會讓人迷惑,讀者可能無法判斷某個表達(dá)式是抽象層級還是細(xì)節(jié))
單一權(quán)責(zé)原則:?Single Responsibility Principle,SRP
開放閉合原則:?Open Closed Principle ,OCP - 使用描述性的名稱
- 函數(shù)的名稱應(yīng)該表達(dá)函數(shù)做的事情
- 命名方式保持一致,使用與模塊名一脈相承的短語,名稱、動詞
- 函數(shù)短了也方便起名字
- 函數(shù)參數(shù)盡可能的短,最好不要超過三個
- 如果函數(shù)的參數(shù)大于等于3個,可以考慮將參數(shù)封裝為對象,從而降低參數(shù)數(shù)量
- 函數(shù)命名:函數(shù)名和參數(shù)名能夠形成可以良好的動詞/名詞對 形式:如 AssertExpectedEqualsActual(expected, actual)
- 無副作用:根據(jù)函數(shù)名就知道它做的事情,函數(shù)中不應(yīng)該有其他的操作
- 使用異常代替返回錯誤碼
- 抽離try/catch: 它搞亂了代碼結(jié)構(gòu),把正常流程和錯誤處理混在一起, 應(yīng)該把try 里和catch里的都抽成函數(shù)
- 錯誤處理也是一件事情
- 消除代碼重復(fù) :
面向?qū)ο缶幊?,面向組件編程,也都是在消除重復(fù)
待續(xù)............