轉(zhuǎn)載自公眾號(hào):趣談編程
來(lái)源:zsx躍遷路
作者:試心
讓軟件能工作和讓軟件保持整潔缝龄,是截然不同的工作柒竞,后者需要投入的更多。
大多數(shù)人只能更多地把精力放在讓代碼能工作轻庆,而沒(méi)辦法保持代碼有組織更整潔韧骗。能做到代碼整潔嘉抒,說(shuō)明你已經(jīng)不是一般人了。
本文內(nèi)容主要分以下幾點(diǎn):
1. 什么樣的代碼是整潔的
2. 取個(gè)好名字
3. 讓函數(shù)再整潔一點(diǎn)
4.注釋的好與壞
5. 格式化
6. 異常處理和邊界
7. 整潔的類
1.什么樣的代碼是整潔的
如上圖所示袍暴,衡量代碼質(zhì)量的唯一標(biāo)準(zhǔn)些侍,是別人閱讀你代碼時(shí)的感受隶症。
不整潔的代碼,閱讀體驗(yàn)是這樣的:
1.亂(組織亂岗宣,職責(zé)亂蚂会,名稱亂起)
2.邏輯不清晰(if-else 太多)
3.繞彎子(簡(jiǎn)單的事寫的很復(fù)雜)
4.看不懂(只有寫的人能理解)
5.難修改(耦合嚴(yán)重,各種寫死)
整潔的代碼耗式,閱讀體驗(yàn)是這樣的:
1.清晰(是什么胁住,做了什么,一眼看得出來(lái))
2.簡(jiǎn)單(職責(zé)少刊咳,代碼少彪见,邏輯少)
3.干凈(沒(méi)有多余的邏輯)
4.好拓展(依賴的比較少,修改不會(huì)影響很多)
接下來(lái)介紹一些寫整潔代碼的方法娱挨。
2.取個(gè)好名字
先看幾個(gè)壞命名的例子:
正如上圖所示余指,壞命名具有這樣的特點(diǎn):
1.使用縮寫(讓使用者誤解其用途)
2.描述性差(通過(guò)命名無(wú)法理解他的作用)
3.相似(使用類似的、難分辨的名稱)
4.使用專業(yè)術(shù)語(yǔ)做名稱容易誤會(huì)跷坝,比如使用 Activity 表達(dá)活動(dòng)酵镜,容易被理解成安卓里的組件
5.需要借注釋解釋,名稱本身就是解釋柴钻,如果還需要借助注釋淮韭,就已經(jīng)說(shuō)明這個(gè)命名有問(wèn)題,對(duì)應(yīng)的類贴届、函數(shù)靠粪、屬性職責(zé)不清晰
好的命名具有這樣的特點(diǎn):
1.名副其實(shí)
閱讀名稱就知道它為什么存在、做什么事毫蚓、應(yīng)該怎么用庇配,如果需要通過(guò)注釋來(lái)回答,那就不算名副其實(shí)
2.不容易混淆
避免使用非常相似的名稱绍些,尤其是類型還相同,比如小寫 l 和1耀鸦、o 和 0柬批、專有名詞
3.讀的出來(lái)
不要因?yàn)楹ε旅Q過(guò)長(zhǎng)而使用縮寫,那樣不便于和別人討論
4.方便搜索
名稱長(zhǎng)度和其作用范圍成正比袖订,作用范圍比較大的氮帐,長(zhǎng)名稱也可以,只要能表達(dá)清楚
3.讓函數(shù)再整潔一點(diǎn)
1.函數(shù)的第一要?jiǎng)t:短小 (多短才算可以洛姑?不超過(guò) 10 行上沐,縮進(jìn)層級(jí)不該大于兩層) **
2.只做一件事 (要判斷函數(shù)是否做了不止一件事,就看它里面的代碼楞艾,是否能再拆出一個(gè)函數(shù))
3.函數(shù)變大的頭號(hào)兇手:switch 語(yǔ)句
switch 語(yǔ)句天生要做多件事参咙,我們能做的龄广,就是減少 switch 語(yǔ)句的次數(shù),把它埋藏在較低的抽象層級(jí)蕴侧,同時(shí)不重復(fù)使用 switch
如果有類似的 switch 出現(xiàn)多次择同,就要考慮使用多態(tài)來(lái)減少 switch 語(yǔ)句出現(xiàn)的次數(shù)
4.定義的函數(shù)的參數(shù)越多,你耗費(fèi)函數(shù)使用者的青春就越多净宵,使用者需要花時(shí)間搞清楚每個(gè)參數(shù)的具體含義和順序
最理想的參數(shù)數(shù)量是1~2
從測(cè)試的角度看敲才,參數(shù)越多,可能出現(xiàn)的用例就越多择葡,就越容易出錯(cuò)
保持參數(shù)列表短小的方法: 參數(shù)升為全局變量紧武、多個(gè)參數(shù)封裝成一個(gè)類
5.不要有副作用(副作用就是做了名稱以外的工作)
6.Android Studio 提供了 Refactor Extract ,幫助我們做代碼拆分
4.注釋的好與壞
在這些場(chǎng)景下敏储,使用注釋比較好:
1.彌補(bǔ)代碼表達(dá)意圖的失敗
代碼本身無(wú)法說(shuō)明意圖阻星,這時(shí)使用注釋,說(shuō)明這段代碼需要被修改
2.提供信息
提供代碼以外的信息虹曙,比如產(chǎn)品相關(guān)信息
3.復(fù)雜實(shí)現(xiàn)的 簡(jiǎn)要概括
讓閱讀者快速了解某個(gè)復(fù)雜的系統(tǒng)
4.警示迫横、提醒
比如某個(gè)不起眼的代碼是為了解決某個(gè) bug,防止別人誤刪
5.TODO
IDE可以定位 TODO 注釋酝碳,我們需要定期查看這些注釋矾踱,刪除不再需要的,讓代碼整潔
這些注釋是壞注釋:
1.令人費(fèi)解的注釋
讀懂花費(fèi)的時(shí)間比看代碼的時(shí)間還長(zhǎng)疏哗,差評(píng)
2.誤導(dǎo)性注釋呛讲,老舊的注釋
代碼才是真相,注釋有可能是謊言返奉,還是要”少寫注釋贝搁!“
3.日志型注釋
比如記錄修改日志,放到 git commit 日志里吧
4.廢話注釋
變量名芽偏、函數(shù)名已經(jīng)很清晰雷逆,就不需要注釋,注釋里不要放一些奇怪的東西污尉,比如如來(lái)佛祖
5.注釋掉的代碼
沒(méi)用的代碼及時(shí)刪除
別給糟糕的代碼寫注釋膀哲,重構(gòu)!
5.格式化 Coding Style
1.團(tuán)隊(duì)最好統(tǒng)一格式化標(biāo)準(zhǔn)
那樣就可以避免某人只修改了一點(diǎn)被碗,但順手格式化了一下某宪,整個(gè)類都產(chǎn)生了變動(dòng),那樣會(huì)覆蓋真正的提交日志锐朴。
2.一行代碼列數(shù)不超過(guò) 100
Android Studio 里的豎線默認(rèn)是 100兴喂,不要超過(guò)這條線。
3.代碼抽象層級(jí)逐漸遞減
最頂應(yīng)該給出高層次概念和算法,向下逐漸展開(kāi)細(xì)節(jié)衣迷。
4.用好空行
每個(gè)空行代表思路的重新開(kāi)始畏鼓,用空白行隔開(kāi)思路和不同作用的代碼,和寫文章一樣蘑险,及時(shí)分段滴肿。
5.物以類聚
關(guān)系密切的代碼應(yīng)該靠近。
6.異常處理和邊界
1.使用異常替代返回錯(cuò)誤碼
2.抽離錯(cuò)誤處理
如果錯(cuò)誤處理很重要的話佃迄,可以考慮把錯(cuò)誤處理單獨(dú)放到一個(gè)方法里泼差。
3.盡量不要返回 null
返回空對(duì)象好于返回 null,盡可能的避免空指針的出現(xiàn)呵俏。
4.慎用 CheckedException
定義異常時(shí)堆缘,要考慮它會(huì)被如何捕獲。CheckedException 如果不處理普碎,就得強(qiáng)制拋出去吼肥,那樣會(huì)影響所有調(diào)用鏈。
邊界:
1.處理邏輯前麻车,優(yōu)先處理邊界和異常
2.快速了解某個(gè)框架的邊界
在使用的框架代碼里使用關(guān)鍵字 throw new 進(jìn)行搜索缀皱,看看什么情況下會(huì)拋出什么異常,最后整理出來(lái)动猬。
3.創(chuàng)建邊界代碼啤斗,隔離第三方
使用我們控制不了的代碼時(shí),必須加倍小心赁咙,確保未來(lái)修改的代碼不會(huì)太大钮莲。
創(chuàng)建邊界代碼,隔離第三方彼水,避免我們的代碼對(duì)第三方框架內(nèi)部了解過(guò)多崔拥。
7.整潔的類
整潔的類應(yīng)該具有以下特點(diǎn):
1.職責(zé)少,等于短小
評(píng)價(jià)類職責(zé)的多少凤覆,看它對(duì)外暴露的方法個(gè)數(shù)链瓦,多于 5 個(gè)就可以拆分了。
2.只有一條被修改的理由
根據(jù)單一職責(zé)原則盯桦,類應(yīng)該只有一條被修改的理由澡绩。
3.隔離改變
依賴抽象而非具體;減少對(duì)外暴露公有變量俺附,使用 getter 代替。
4.拆分不是壞事
有同學(xué)可能會(huì)擔(dān)心了:拆分類太多會(huì)不會(huì)更復(fù)雜了溪掀?
假如你有很多東西事镣,是希望根據(jù)分類放放到不同的小抽屜格子里,還是希望一起放到幾個(gè)大抽屜里?