1. 好代碼必須是看起來(lái)很舒服典蝌,很干凈
象一篇好文章曙砂,不羅嗦,容易懂骏掀,有頭有尾
各個(gè)層次鸠澈,模塊及函數(shù)分工明確,各司其職, 望文知義
接口即契約截驮,要足夠簡(jiǎn)單笑陈,易懂易用, 窄接口好過(guò)寬接口
其實(shí)只要符合代碼規(guī)范侧纯,命名簡(jiǎn)單易懂新锈,代碼就沒(méi)那么丑
參見(jiàn) Google 的代碼風(fēng)格指南
看看重構(gòu)那本書中的臭味介紹, 可以提高品味
2. 好代碼要符合基本的編碼原則
首先我們先談?wù)剮讉€(gè)軟件開(kāi)發(fā)的普適原則
KISS
KISS: Keep It Simple and Straight 保持簡(jiǎn)單和直接, 適當(dāng)隱藏復(fù)雜性
或者
KISS: Keep It Simple and Stupid 保持簡(jiǎn)單, 象傻瓜一樣, 不要讓別人多加思考
軟件接口或 API 的設(shè)計(jì)要讓人一看就明白, 一看就知道作者的意圖和想法, 如何使用它, 有什么結(jié)果和可能的異常及副作用. 看過(guò)很多代碼, 踩過(guò)許多坑眶熬, 大多是作者或者我自己使用了出乎意料的實(shí)現(xiàn)妹笆, 不做好必要的抽象和封裝块请, 復(fù)雜的判斷和算法到處都是
DRY – Don't Repeat Yourself
別重復(fù)你自己, 如有重復(fù)代碼, 請(qǐng)抽象或重用
SRP - Single Responsibility Principle
單一職責(zé)原則: 就一類而言, 應(yīng)該僅有一個(gè)引起它變化的原因
也有一個(gè)別稱 DOTADIW - Do One Thing and Do It Well 就做一件事并做好它
OCP - Open Close Principle
開(kāi)放封閉原則: 軟件實(shí)體(類,模塊,函數(shù)等)應(yīng)該是可以擴(kuò)展的, 但是不可修改
LSP
LSP替換基類原則: 子類型應(yīng)該可以替換掉它們的基類型
DIP
DIP依賴倒置原則: 抽象不應(yīng)該依賴于細(xì)節(jié), 細(xì)節(jié)應(yīng)該依賴于抽象
ISP
ISP接口隔離原則: 不應(yīng)該強(qiáng)迫客戶依賴于它們不用的方法, 接口屬于客戶, 不屬于它所在的類層次結(jié)構(gòu)
REP
REP重用發(fā)布等價(jià)原則: 重用的粒度就是發(fā)布的粒度
CCP
CCP共同封閉原則: 包中的所有類對(duì)于同一類性質(zhì)的變化應(yīng)該是共同封閉的. 一個(gè)變化若對(duì)一個(gè)包產(chǎn)生影響, 則將對(duì)包中所有的類產(chǎn)生影響, 而對(duì)于其他的包不造成任何影響
CRP
CRP共同重用原則: 一個(gè)包中的所有類應(yīng)該是共同重用的. 如果重用了包中的一個(gè)類, 那么就要重用包中的所有類
ADP
ADP無(wú)環(huán)依賴原則: 在包的依賴關(guān)系圖不允許存在環(huán)
SDP
SDP穩(wěn)定依賴原則: 朝著穩(wěn)定的方向進(jìn)行依賴.
SAP
SAP穩(wěn)定抽象原則: 包的抽象程度應(yīng)該和其穩(wěn)定程度一致
設(shè)計(jì)模式和面向?qū)ο笤O(shè)計(jì)中講了很多,不再贅述
3. 好代碼要易于理解拳缠,測(cè)試和修改
封裝好復(fù)雜性墩新,區(qū)分開(kāi)經(jīng)常變化與基本不變的代碼, 適當(dāng)抽取易變參數(shù)作為配置
還是書里那句話,高內(nèi)聚窟坐,低耦合海渊,依賴倒置
例如最常用的 MVC 模式,為什么我們要分成模型哲鸳,視圖和控制器三塊臣疑,原因之一就在于分開(kāi)易變的與不易變的,分開(kāi)不會(huì)在一起變化的部分徙菠,減小每次修改的范圍讯沈。
如果某個(gè)方面的功能需要修改,最好是改個(gè)配置婿奔, 其次是加幾行代碼或傳個(gè)不同參數(shù)缺狠,最差的就是改多個(gè)地方,加多個(gè)判斷萍摊, 作霰彈式修改
4. 好代碼要考慮周到
各種邏輯流程和意外情況的處理要面面俱到, 單元和模塊測(cè)試要覆蓋異常邏輯和邊界
對(duì)于服務(wù)質(zhì)量 SLA 要考慮周全, 簡(jiǎn)單說(shuō)起來(lái)就是滿足用戶的以下基本需求
- 功能性
- 穩(wěn)定性
- 可靠性
- 性能
- 可維護(hù)性
- 可移植性
- 靈活性
5. 好代碼要與時(shí)俱進(jìn)挤茄,自我蛻變
人會(huì)變老,代碼也會(huì)冰木,新業(yè)務(wù)穷劈,新技術(shù),新架構(gòu)片酝,新框架層出不窮囚衔,要大膽試驗(yàn),小心引入雕沿,逐步演進(jìn)练湿,不必抱殘守缺,也不要盲目沖動(dòng)
一般來(lái)說(shuō)审轮,要封裝好業(yè)務(wù)邏輯肥哎,核心業(yè)務(wù)不會(huì)大變,即使推到重寫也要理解和參照老系統(tǒng)的業(yè)務(wù)流程
最后疾渣,引述一下,Python 之禪
Python 之禪
雖然說(shuō)的是Python, 其實(shí)適用于多數(shù)編程語(yǔ)言
英文 | 中文 |
---|---|
Beautiful is better than ugly. | 美比丑好 |
Explicit is better than implicit. | 明顯比隱晦好 |
Simple is better than complex. | 簡(jiǎn)單比復(fù)雜好 |
Complex is better than complicated. | 復(fù)雜比難懂好 |
Flat is better than nested. | 扁平比嵌套好 |
Sparse is better than dense. | 稀疏比稠密好 |
Readability counts. | 可讀性很重要 |
Special cases aren't special enough to break the rules. | 特例也不要打破這個(gè)原則 |
Although practicality beats purity. | 盡管實(shí)踐會(huì)破壞純潔性 |
Errors should never pass silently. | 錯(cuò)誤還是不能讓其悄然滑過(guò) |
Unless explicitly silenced. | 除非你明確聲明不用理會(huì)它 |
In the face of ambiguity, refuse the temptation to guess. | 別讓人來(lái)猜測(cè)不確定的可能性 |
There should be one-- and preferably only one --obvious way to do it. | 應(yīng)該有一個(gè)且只有一個(gè)比較好的明顯的方法來(lái)做事 |
Although that way may not be obvious at first unless you're Dutch. | 盡管那個(gè)方法可能并非一開(kāi)始就顯而易見(jiàn) |
Now is better than never. | 現(xiàn)在就做比永遠(yuǎn)不做好 |
Although never is often better than right now. | 盡管永遠(yuǎn)不做經(jīng)常比馬上就動(dòng)手做好 |
If the implementation is hard to explain, it's a bad idea. | 如果實(shí)現(xiàn)很難解釋清楚, 那它不是一個(gè)好主意 |
If the implementation is easy to explain, it may be a good idea. | 如果實(shí)現(xiàn)很容易說(shuō)清楚, 那它是個(gè)好主意 |
Namespaces are one honking great idea – let's do more of those! | 命名空間是個(gè)絕妙點(diǎn)子, 讓我們那樣做得更多 |
簡(jiǎn)單總結(jié)一下
- 文學(xué)化編程杈女,想清楚,整明白达椰,胸有成竹翰蠢,下手千行
- 測(cè)試驅(qū)動(dòng),不做額外的無(wú)用功啰劲,不追求覆蓋率,為的是增強(qiáng)自信心
- 度量驅(qū)動(dòng)蝇裤,代碼上線怎么辦,如何易于度量和調(diào)優(yōu)
- 為未來(lái)設(shè)計(jì)有限的靈活性栓辜,高聚低耦恋拍,無(wú)需多改容易擴(kuò)展
- 考慮周全,足夠的健壯藕甩,不易出錯(cuò)城须,不怕出錯(cuò)
參考
- Agile Software Development, Principles, Patterns, and Practices by Robert C. Martin
- Clean code by Robert C. Martin
- Refactoring: Improving the Design of Existing Code Martin Fowler