工作一年多了,項(xiàng)目中真正寫代碼的時(shí)間其實(shí)并不多,更多時(shí)候是在調(diào)試代碼或者維護(hù)已有代碼。調(diào)試代碼或者維護(hù)已有代碼難免要去讀代碼,如果是自己寫的代碼,那么讀不懂只能怪自己寫得不好,如果是別人寫的代碼,讀不懂也只能怪自己,技不如人唄,開個(gè)玩笑而已,讀不懂別人的代碼說(shuō)不定不是你的問題,也許是別人寫的代碼易讀性和可維護(hù)性都不好,才導(dǎo)致你讀起來(lái)費(fèi)勁,難以理解。所以我結(jié)合自己的coding和debug經(jīng)驗(yàn),談?wù)勔恍╆P(guān)于寫代碼的想法,先從以下3點(diǎn)談起:
- DRY(Don't Repeat Yourself)原則
- 一致性
- 可讀性
別看都是一些很簡(jiǎn)單的規(guī)則,但你未必就遵循。
1) DRY原則
寫代碼如果不遵守DRY原則,可以說(shuō)代碼就是“bug之源”。編程很大程度上就是為了讓電腦代替人類進(jìn)行一些重復(fù)性的工作。作為一個(gè)程序員,你連自己的重復(fù)性工作都解決不了,還指望你開發(fā)的軟件能很好代替人類工作,說(shuō)出來(lái)真的怕被笑話。為什么需要定義類和方法,為什么需要定義函數(shù),為什么需要庫(kù),為什么需要框架,這些東西存在的部分原因就是為了消滅重復(fù)代碼,提高代碼的可維護(hù)性。如果你寫的代碼中遍布重復(fù)的代碼,那么當(dāng)你需要修改重復(fù)部分代碼時(shí),必須修改所有重復(fù)的部分,少一個(gè)地方都會(huì)導(dǎo)致bug,這絕對(duì)是代碼維護(hù)人員的噩夢(mèng)。
所以,如果在代碼中有很多重復(fù)的數(shù)據(jù),應(yīng)該將這些數(shù)據(jù)封裝成類或者結(jié)構(gòu)體,減少重復(fù)代碼;如果代碼中有部分重復(fù)了,那么就應(yīng)該將重復(fù)部分抽取成一個(gè)函數(shù),供重復(fù)地方調(diào)用;如果項(xiàng)目中幾個(gè)人開發(fā)的代碼有很多重復(fù)性代碼,那么就應(yīng)該將重復(fù)部分代碼抽取出來(lái),定義成一個(gè)庫(kù)或者模塊,供大家調(diào)用??傊?jǐn)記,千萬(wàn)不要寫重復(fù)的代碼。
2) 一致性
再來(lái)聊聊一致性,一致性為什么那么重要,先用公交卡舉個(gè)例子,我們每天上班坐公交都需要刷公交卡,如果刷完公交卡,隨手就將公交卡放進(jìn)口袋里面或者錢包里面,又或者隨聲攜帶的包里面。也就是說(shuō)每次刷完卡后,沒有將公交卡放在一個(gè)固定的地方,那么當(dāng)某天你急匆匆的趕上公交車,滿身搜尋公交卡時(shí),你就會(huì)明白一致性的重要性。如果每次刷完公交卡都放固定的地方,就不會(huì)出現(xiàn)找不到的情況。這個(gè)例子也許有點(diǎn)牽強(qiáng),但確實(shí)能說(shuō)明前后一致是多么重要。
那么在寫代碼時(shí),何為一致性呢?舉個(gè)例子,比如剛開始定義了2個(gè)常量,并且是以大寫字母加下劃線構(gòu)成常量名稱,例如:
MAX_NAME_LEN = 10000
DEFAULT_NAME = "DEFAULT"
再過段時(shí)間,又定義常量:
MaxArrayLen = 10000
DefaultItem = "Item"
又定義常量:
max_id_len = 10000
default_id = 0
可以看見,三次常量定義的命名規(guī)則都不一樣,別人讀你的代碼時(shí),都分不清什么是常量什么是變量。如果你遵循一種命名規(guī)則定義常量,那么一看就知道這是變量還是常量,也許你覺得這個(gè)例子很簡(jiǎn)單,一般人都會(huì)遵守,我再舉個(gè)例子,變量定義:
int hostNum;
上面定義了一個(gè)變量hostNum,表示host的數(shù)量。這時(shí)候你又定義了一個(gè)變量,表示資源數(shù)量,例如:
int numResource
兩次定義的變量中,表示數(shù)量的number單詞一個(gè)在前,一個(gè)在后,別人讀起來(lái)就容易產(chǎn)生誤解。因?yàn)橐话闱闆r下num放在變量尾部表示索引,即hostNum表示第幾個(gè)host,num放在變量開始位置表示總數(shù),即numHost表示有多少個(gè)host。
所以,平時(shí)寫代碼時(shí),保持前后一致性是非常重要的,如果是在現(xiàn)有項(xiàng)目基礎(chǔ)上開發(fā),那么最好和之前的編碼風(fēng)格保持一致;如果是一個(gè)從零開始構(gòu)建的新項(xiàng)目,那么最好在項(xiàng)目開始之前就統(tǒng)一編碼風(fēng)格,否則到項(xiàng)目后期階段再修改代價(jià)就大了。
3) 可讀性
可讀性這個(gè)話題其實(shí)包含了上面提到DRY原則和一致性原則,寫代碼時(shí)遵循DRY原則和一致性原則,在一定程度上肯定能提高代碼的可讀性。但是我個(gè)人認(rèn)為,可讀性不單指代碼的可讀性,如果是一個(gè)比較大的項(xiàng)目,可讀性還體現(xiàn)在代碼目錄結(jié)構(gòu)、模塊劃分、目錄命名和文件命名等上面。所以我認(rèn)為可讀性好的代碼,至少應(yīng)該在以下6個(gè)方面得到體現(xiàn):
- 變量命名,比如totalHost、hostIndex、hostId;
- 類或者結(jié)構(gòu)體命名,比如Encoder、Decoder、Marshaler;
- 函數(shù)或者方法命名,比如ToLower、ToUpper、ToTitle;
- 庫(kù)或者模塊命名,比如os、sys、file;
- 源代碼文件命名,比如io.go、ioutil.go、log.go;
- 源代碼目錄命名,比如lib、bin、api;
本次分享就到這里,下次再繼續(xù)~
本次薦書:編程人生
