聊聊代码整洁之道
摘要:?Any fool can write code that a computer can understand. Good programmers write code that humans can understand. 普通的工程師堆砌代碼,優(yōu)秀的工程師優(yōu)雅代碼,卓越的工程師簡化代碼。
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
普通的工程師堆砌代碼,優(yōu)秀的工程師優(yōu)雅代碼,卓越的工程師簡化代碼。如何寫出優(yōu)雅整潔易懂的代碼是一門學(xué)問,也是軟件工程實(shí)踐里重要的一環(huán)。筆者推薦三本經(jīng)典的書籍《代碼整潔之道?》、《編寫可讀代碼的藝術(shù)》、《重構(gòu):改善既有代碼的設(shè)計(jì)》,下文重點(diǎn)將從注釋、命名、方法、異常、單元測試等多個(gè)方面總結(jié)了一些代碼整潔最佳實(shí)踐,大部分是筆者總結(jié)于以上三本書中的精華,也有部分是筆者工程實(shí)踐的總結(jié)。篇幅有限,本文將總結(jié)性給出一些實(shí)踐建議,后續(xù)會(huì)有文章來給出一些代碼整潔之道的事例。
注釋
- 不要給不好的名字加注釋,一個(gè)好的名字比好的注釋更重要
- 不要“拐杖注釋”,好代碼 > 壞代碼 + 好注釋
- 在文件/類級別使用全局注釋來解釋所有部分如何工作
- 一定要給常量加注釋
團(tuán)隊(duì)統(tǒng)一定義標(biāo)記
- TODO? 待處理的問題
- FIXME? 已知有問題的代碼
- HACK 不得不采用的粗糙的解決方案
- 在注釋中用精心挑選的輸入輸出例子進(jìn)行說明
- 注釋應(yīng)該聲明代碼的高層次意圖,而非明顯的細(xì)節(jié)
- 不要在代碼中加入代碼的著作信息,git可以干的事情不要交給代碼
- 源代碼中的html注釋是一種厭物, 增加閱讀難度
- 注釋一定要描述離它最近的代碼
- 注釋一定要與代碼對應(yīng)
- 公共api需要添加注釋,其它代碼謹(jǐn)慎使用注釋
典型的爛注釋
- 不恰當(dāng)?shù)男畔?/li>
- 廢棄的注釋
- 冗余注釋
- 糟糕的注釋
- 注釋掉的代碼
唯一真正好的注釋是你想辦法不去寫的注釋
- 不要有循規(guī)式注釋,比如setter/getter注釋
- 不要添加日志式注釋,比如修改時(shí)間等信息(git可以做的事情)
- 注釋一定是表達(dá)代碼之外的東西,代碼可以包含的內(nèi)容,注釋中一定不要出現(xiàn)
- 如果有必要注釋,請注釋意圖(why),而不要去注釋實(shí)現(xiàn)(how),大家都會(huì)看代碼
- 適當(dāng)添加警示注釋
命名
- 盡可能使用標(biāo)準(zhǔn)命名方法,比如設(shè)計(jì)模式,通用學(xué)術(shù)名詞等
命名要找更有表現(xiàn)力的詞
- 使用更專業(yè)的詞,比如不用get而使用fetch或者download
- 避免空泛的名字,像tmp
- 使用具體的名字來細(xì)致的描述事物
- 給變量名帶上重要的細(xì)節(jié),比如加上單位ms等
- 為作用域大的名字采用更長的名字,作用域小的使用短名字
- 變量類型為布爾值表達(dá)加上is,has,can,should這樣的詞會(huì)更明確
- 變量名稱長短應(yīng)該與其作用域?qū)?yīng)
- 別害怕長名稱,長而具有描述性的名稱比短而令人費(fèi)解的名稱好
- 函數(shù)名稱應(yīng)該說明副作用,名稱應(yīng)該表達(dá)函數(shù),變量或類的一切信息,請不要掩蓋副作用,比如CreateAndReturnXXX
方法
函數(shù)不應(yīng)該有100行那么長,20行封頂最好
- if else while等控制語句其中代碼塊應(yīng)該只有一行,也就是一個(gè)函數(shù)調(diào)用語句
- 函數(shù)的鎖進(jìn)層次不應(yīng)該多于兩層
- 一個(gè)函數(shù)只做一件事,一個(gè)函數(shù)不應(yīng)該能抽象出另外一個(gè)函數(shù)
- 某個(gè)公共函數(shù)調(diào)用的私有函數(shù)緊隨其后
最理想的參數(shù)是零參數(shù),最長不要超過三個(gè)入?yún)?#xff0c;盡量不要輸出參數(shù)
- 如果函數(shù)傳入三個(gè)及以上參數(shù)最好將其抽象為類
- 標(biāo)識參數(shù)十分丑陋,向函數(shù)傳入布爾值用于區(qū)分不同業(yè)務(wù)的做法很丑陋,應(yīng)該拆分為多個(gè)函數(shù)
- 別返回null值,拋出異常或者返回特殊對象,盡量避免NPE
- 別傳入null值
異常與錯(cuò)誤
- 抽離try catch包含的代碼塊,其中代碼塊抽象為一個(gè)函數(shù)
- 拋出的每個(gè)異常,都應(yīng)當(dāng)提供足夠的環(huán)境說明,已便判斷錯(cuò)誤的來源與處所
- 不要將系統(tǒng)錯(cuò)誤歸咎于偶然事件
并發(fā)
- 分離并發(fā)相關(guān)代碼與其它代碼
- 嚴(yán)格限制對可能被共享的數(shù)據(jù)的訪問
- 避免使用一個(gè)共享對象的多個(gè)同步方法
- 保持同步區(qū)域微小,盡可能少設(shè)計(jì)臨界區(qū)
單元測試
- 不要怕單元測試的方法名字太長或者繁瑣,測試函數(shù)的名稱就像注釋
- 不要追求太高的測試覆蓋率,測試代碼前面90%通常比后面10%花的時(shí)間少
- 使用最簡單的并且能夠完整運(yùn)用代碼的測試輸入
- 給測試函數(shù)取一個(gè)完整性的描述性名字,比如? Test _
- 測試代碼與生產(chǎn)代碼一樣重要
- 如果測試代碼不能保證整潔,你就會(huì)很快失去他們
- 每個(gè)測試一個(gè)斷言,單個(gè)測試中斷言數(shù)量應(yīng)該最小化也就是一個(gè)斷言
FIRST原則
- 快速 Fast
- 獨(dú)立 Independent? 測試應(yīng)該相互獨(dú)立
- 可重復(fù) Repeatable? 測試應(yīng)當(dāng)在任何環(huán)境中重復(fù)通過
- 自足驗(yàn)證 Self-Validating ? 測試應(yīng)該有布爾值輸出
- 及時(shí)? Timely ? 最好的方式是TDD
代碼結(jié)構(gòu)
- 代碼行長度控制在100-120個(gè)字符
- 可能用大多數(shù)為200行,最長500行的單個(gè)文件構(gòu)造出色的系統(tǒng)
關(guān)系密切的代碼應(yīng)該相互靠近
- 變量聲明應(yīng)該靠近其使用位置
- 若某個(gè)函數(shù)調(diào)用了另外一個(gè),應(yīng)該把他們放在一起,而且調(diào)用者應(yīng)該放在被調(diào)用者上面
- 自上向下展示函數(shù)調(diào)用依賴順序
- 應(yīng)該把解釋條件意圖的函數(shù)抽離出來,盡可能將條件表達(dá)為肯定形式
- 不要繼承常量,比如接口中定義常量,不要使用繼承欺騙編程語言的作用范圍規(guī)則
- 模塊不應(yīng)了解它所操作對象的內(nèi)部情況
- DTO(Data Transfer Objects)是一個(gè)只有公共變量沒有函數(shù)的類
- 對象暴露行為,隱藏?cái)?shù)據(jù)
- 不要使用“尤達(dá)表示法” 如 if(null == obj),現(xiàn)代編譯器對if(obj = null)這樣的代碼會(huì)給出警告
- 一般情況使用if else,簡單語句使用三目運(yùn)算符
- 通常來講提早返回可以減少嵌套并讓代碼整潔
設(shè)計(jì)
類應(yīng)該足夠短小
- 類應(yīng)該滿足單一權(quán)責(zé)原則(SRP),類和模塊只有一個(gè)修改理由
- 類應(yīng)該只有少量的實(shí)體變量
- 類應(yīng)該遵循依賴倒置原則 DIP(Dependency Inversion Principle),類應(yīng)該依賴于抽象而不是依賴于具體細(xì)節(jié)
- 類中的方法越少越好,函數(shù)知道的變量越少越好,類擁有的實(shí)體變量越少越好
通過減少變量的數(shù)量和讓他們盡量“輕量級”來讓代碼更有可讀性
- 減少變量
- 縮小變量的作用域
- 只寫一次的變量更好,如常量
最好讀的代碼就是沒有代碼
- 從項(xiàng)目中消除不必要的功能,不要過度設(shè)計(jì)
- 從新考慮需求,解決版本最簡單的問題,只要能完成工作就行
- 經(jīng)常性地通讀標(biāo)準(zhǔn)庫的整個(gè)API,保持對他們的熟悉程度
簡單設(shè)計(jì)
- 運(yùn)行所有測試
- 不可重復(fù)
- 表達(dá)了程序員的意圖
- 盡可能減少類和方法的數(shù)量
- 以上規(guī)則按重要程度排列
- 無論是設(shè)計(jì)系統(tǒng)或者單獨(dú)模塊,別忘了使用大概可工作的最簡單方案
- 整潔的代碼只提供一種而非多種做一件事的途徑,他只有盡量少的依賴。明確定義并提供盡量少的API
- 減少重復(fù)代碼,提高表達(dá)力,提早構(gòu)建,簡單抽象
小結(jié)
作為代碼整潔之道系列的第一篇,本文從注釋、命名、方法,單元測試,并發(fā)等視角簡單給出了一些最佳實(shí)踐,下文我們會(huì)展開來從每個(gè)方面介紹更多的實(shí)踐事例。相信每一個(gè)優(yōu)秀的工程師都有一顆追求卓越代碼的心,在代碼整潔工程實(shí)踐上你有哪些好的建議?數(shù)百人協(xié)作開發(fā)的代碼如何保證代碼整潔一致性?歡迎大家來討論。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
- 上一篇: MaxCompute理解数据、运算和用户
- 下一篇: 基于AliOS Things玩转智能语音