年薪十萬與年薪百萬程序員寫的代碼的區(qū)別
導(dǎo)讀:編程是一門創(chuàng)造性的工作,是一門藝術(shù)。我們每天與代碼打交道,為什么普通碼農(nóng)辛苦一年只拿十萬,而高級架構(gòu)師年薪百萬。最主要的就是我們敲出來的代碼有差別,差別在意大部分碼農(nóng)敲出來壞的代碼,而高級架構(gòu)師能敲出優(yōu)雅的好的代碼。我們每天都會敲代碼,但當(dāng)被問道什么是好的優(yōu)雅的代碼時,大家可能會先愣一下,然后給出的回答要么比較空泛,要么比較散,沒辦法簡單明了地概括出來。顯然,這個問題并沒有唯一的標(biāo)準(zhǔn)答案,誰都可以談?wù)撟约旱睦斫?。要成為合格的架?gòu)師最基本的要求是能寫好的優(yōu)雅的代碼,所以必須要知道什么是優(yōu)雅代碼。這篇文章我來分享一下阿里系高級架構(gòu)師對于好的優(yōu)雅代碼的理解。

一句話概括
衡量代碼質(zhì)量的唯一有效標(biāo)準(zhǔn):WTF/min —— Robert C. Martin

Martin(Bob大叔)曾在《代碼整潔之道》一書中說:當(dāng)你的代碼在做 Code Review 時,審查者要是憤怒地吼道:“What the fuck, is this shit?”、“Dude, What the fuck!”等言辭激烈的詞語,那說明你寫的代碼是 Bad Code,如果審查者只是漫不經(jīng)心的吐出幾個:“What the fuck?”,那說明你寫的是 Good Code。
衡量代碼質(zhì)量的唯一標(biāo)準(zhǔn)就是每分鐘罵出“WTF”的頻率。
我敢打賭每個人都遇到過這樣的情況:過幾周或者幾個月之后,再看到自己寫的代碼,感覺一團(tuán)糟,不禁懷疑人生。
我們自己寫的代碼,一段時間后自己看尚且如此,更別提拿給別人看了。
一、好的優(yōu)雅的代碼
我們?nèi)绾蝸硇稳莺玫膬?yōu)雅的代碼?好的優(yōu)雅的代碼一定具備以下特征:
- 精簡代碼,可讀性高
- 邏輯清晰
- 高內(nèi)聚,低耦合
- OOP三大特征(封裝、繼承、多態(tài))
1、精簡代碼,可讀性高
任何一個傻瓜都能寫出計(jì)算機(jī)可以理解的代碼。唯有寫出人類容易理解的代碼,才是優(yōu)秀的程序員。—— Martin Fowler
assert((!(bucket = findBucket(key))) || !bucket.isOccupied());
上面這行代碼雖然比較短,但是難以閱讀。為了更好地閱讀,我們做如下修改:
- bucket = findBucket(key);if(bucket != null){
- assert(!bucket.isOccupied());}
減少代碼行數(shù)是一個好目標(biāo),但是讓閱讀代碼的事件最小化是個更好的目標(biāo)。
但是這些詞沒有任何指導(dǎo)意義,我準(zhǔn)備從最基本的概念入手。
所以,談到好代碼,首先跳入自己腦子里的一個詞就是:精簡。
好的代碼一定是精簡的,給閱讀的人一種輕松愉快感覺。
2、邏輯清晰
對代碼的邏輯層次要有感覺。
比如大體上,一個程序會分三個層次:界面層,邏輯層,數(shù)據(jù)層。簡化后一般也有兩個層次:界面和邏輯層。
邏輯層是去掉外表的,內(nèi)在的,實(shí)質(zhì)的東西。一般來說,就是表現(xiàn)為對數(shù)據(jù)的一組操作。
而界面層,是關(guān)注程序應(yīng)該如何和用戶溝通的。比如可視的視窗,圖表,控件等。它是內(nèi)部邏輯的呈現(xiàn),也是用戶和內(nèi)部邏輯溝通的橋梁。
區(qū)分這兩個層次的好處,一個是這兩個層次所注重的核心內(nèi)容有所不同,用到的技巧或者指導(dǎo)方法有所差別。第二點(diǎn)是,可以將問題解構(gòu)和局部化,減輕開發(fā)難度。第三點(diǎn),有助分開來修改內(nèi)容,比如界面層挪動一下,改變一下形式,并不需要修改邏輯層的;而邏輯層改進(jìn)一下算法,也不會影響界面層的代碼。
對代碼的邏輯層次有感覺,以上的要求只是很基本的,編寫代碼要時時刻刻對當(dāng)前代碼所代表的邏輯層次要有“感覺”,要能意識到這段代碼和上一段代碼是否在某種標(biāo)準(zhǔn)下,處在同一個層次。比較經(jīng)典的范例如:互聯(lián)網(wǎng)的7層協(xié)議,還有操作系統(tǒng)的層次分部等。編寫代碼要善于歸納這些層次,才能建構(gòu)一個優(yōu)美的結(jié)構(gòu)。
3、高內(nèi)聚低耦合
高內(nèi)聚低耦合幾乎是每個程序員員都會掛在嘴邊的,但這個詞太過于寬泛,太過于正確,所以聰明的編程人員們提出了若干面向?qū)ο笤O(shè)計(jì)原則來衡量代碼的優(yōu)劣:
- 開閉原則 OCP (The Open-Close Principle)
- 單一職責(zé)原則 SRP (Single Responsibility Principle)
- 依賴倒置原則 DIP (Dependence Inversion Principle)
- 最少知識原則 LKP (Least Knowledge Principle)) / 迪米特法則 (Law Of Demeter)
- 里氏替換原則 LSP (Liskov Substitution Principle)
- 接口隔離原則 ISP (Interface Segregation Principle)
- 組合/聚合復(fù)用原則 CARP (Composite/Aggregate Reuse Principle)
這些原則想必大家都很熟悉了,是我們編寫代碼時的指導(dǎo)方針,按照這些原則開發(fā)的代碼具有高內(nèi)聚低耦合的特性。換句話說,我們可以用這些原則來衡量代碼的優(yōu)劣。
但這些原則并不是死板的教條,我們也經(jīng)常會因?yàn)槠渌臋?quán)衡(例如可讀性、復(fù)雜度等)違背或者放棄一些原則。比如子類擁有特性的方法時,我們很可能打破里氏替換原則。再比如,單一職責(zé)原則跟接口隔離原則有時候是沖突的,我們通常會舍棄接口隔離原則,保持單一職責(zé)。只要打破原則的理由足夠充分,也并不見得是壞的代碼。
4、OOP三大特征
4.1封裝
盡可能隱藏一個模塊的實(shí)現(xiàn)細(xì)節(jié)(屬性名稱,屬性是否可變,算法,數(shù)據(jù)結(jié)構(gòu),數(shù)據(jù)類型)
訪問控制只是為了防止程序員的無意誤用,不打算,也無法防止程序員的故意破壞
4.2繼承
繼承使用不當(dāng)會破壞封裝,造成信息泄露
先考慮組合,在考慮繼承
繼承是 behaves-like-a, is-substitutable-for 的關(guān)系,不是 is-a 或 is-a-kind-of 的關(guān)系
4.3多態(tài)
- 相同的實(shí)現(xiàn)代碼適用不同的場合
- 不同的實(shí)現(xiàn)代碼適用相同的場合
二、如何判斷不是好的代碼
討論了好代碼的必要條件,我們再來看看好代碼的否定條件:什么不是好的代碼。Kent Beck 使用味道來形容重構(gòu)的時機(jī),我認(rèn)為當(dāng)代碼有壞味道的時候,也代表了其并不是好的代碼。
代碼的壞味道
► 重復(fù)
重復(fù)可能是軟件中一切邪惡的根源。—— Robert C.Martin
Martin Fowler 也認(rèn)為壞味道中首當(dāng)其沖的就是重復(fù)代碼。
很多時候,當(dāng)我們消除了重復(fù)代碼之后,發(fā)現(xiàn)代碼就已經(jīng)比原來整潔多了。
► 函數(shù)過長、類過大、參數(shù)過長
過長的函數(shù)解釋能力、共享能力、選擇能力都較差,也不易維護(hù)。
過大的類代表了類做了很多事情,也常常有過多的重復(fù)代碼。
參數(shù)過長,不易理解,調(diào)用時也容易出錯。
► 發(fā)散式變化、霰彈式修改、依戀情結(jié)
如果一個類不是單一職責(zé)的,則不同的變化可能都需要修改這個類,說明存在發(fā)散式變化,應(yīng)考慮將不同的變化分離開。
如果某個變化需要修改多個類的方法,則說明存在霰彈式修改,應(yīng)考慮將這些需要修改的方法放入同一個類。
如果函數(shù)對于某個類的興趣高于了自己所處的類,說明存在依戀情結(jié),應(yīng)考慮將函數(shù)轉(zhuǎn)移到他應(yīng)有的類中。
► 數(shù)據(jù)泥團(tuán)
有時候會發(fā)現(xiàn)三四個相同的字段,在多個類和函數(shù)中均出現(xiàn),這時候說明有必要給這一組字段建立一個類,將其封裝起來。
► 過多的 if...else 或者使用 switch
過多的 if...else 或者 switch ,都應(yīng)該考慮用多態(tài)來替換掉。甚至有些人認(rèn)為除個別情況外,代碼中就不應(yīng)該存在 if...else 。
三、總結(jié)
本文首先一句話概括了我認(rèn)為的好的優(yōu)雅代碼的必要條件:精簡,邏輯清晰,高內(nèi)聚,低耦合,接著具體分析了壞代碼的特點(diǎn),什么樣的代碼不是好的代碼。僅是本人的一些見解,希望對各位以后的編程有些許的幫助。
對于如何保持代碼整潔,離不開設(shè)計(jì)模式和代碼重構(gòu),多閱讀開源社區(qū)的代碼,比如最近微信開源的MMKV就可以讀來學(xué)習(xí),像世界同行大佬學(xué)習(xí)交流如何優(yōu)雅的寫代碼,也可以讀一些經(jīng)典的書籍如《代碼整潔之道》、《重構(gòu)改善既有代碼的設(shè)計(jì)》、《重構(gòu)改善既有代碼的設(shè)計(jì)》等等。






