我無法寫出易讀的代碼

經(jīng)常能聽到一些開發(fā)人員抱怨其他人寫的代碼難以理解,這時(shí),我常常會(huì)想,如果不告訴那些開發(fā)人員,而直接讓他們看我寫的代碼,他們也一定會(huì)有同樣的感覺吧,“這個(gè)人的代碼寫得真爛”。似乎無論你的技術(shù)水平多么高超,都很難寫出易讀的代碼來。

代碼本來就是難以閱讀的

我相信很多程序員一定都讀過《代碼大全》,《Effective Java》,《設(shè)計(jì)模式》等等介紹如何寫出更優(yōu)秀代碼的書籍吧。而程序員們在寫代碼時(shí),也確實(shí)遵循著書中的那些最佳實(shí)踐,努力地去寫出高質(zhì)量的代碼。但當(dāng)他們編寫更復(fù)雜一些的程序時(shí),所寫出的代碼就會(huì)變得越來越難以閱讀,即使加上了很多注釋,這種情況也不會(huì)得到明顯的改善。

這是程序員的問題嗎?不,至少我認(rèn)為不是這樣的,因?yàn)?strong>代碼并不是自然語言,它本來就是難以閱讀的,況且代碼是否易讀不僅與代碼本身有關(guān),還與閱讀代碼的人對系統(tǒng)的理解程度,以及他們自身的技術(shù)水平有關(guān),更何況,我們寫代碼的目的本身也不是為了讓它更容易閱讀。

我很喜歡拿寫作與寫代碼進(jìn)行比較,當(dāng)我們寫完一篇文章后,我們常常會(huì)反復(fù)修改,直到它變得流暢易讀為止,因?yàn)橹挥羞@樣,讀者才能明白你的文章所要表達(dá)的內(nèi)容。而對于編碼而言卻不是這樣,我們寫代碼是為了實(shí)現(xiàn)功能、解決問題,因此我們一般都會(huì)通過測試來進(jìn)行驗(yàn)證,但極少會(huì)為了讓它變得易讀,而去修改它。與代碼的準(zhǔn)確性相比,顯然代碼是否易讀變得次要了很多。

如何讓你的代碼更易閱讀

那么是否有一些簡單可行的方法讓你的代碼易讀或更易于維護(hù)呢?有,但前提是我們可能需要暫時(shí)跳出代碼本身才能找到那些行之有效的方法。

推行模式(Patterns)而非建立規(guī)范

我見過很多項(xiàng)目團(tuán)隊(duì),在開始編碼之前,都會(huì)相應(yīng)地制定一整套代碼規(guī)范(多的達(dá)到幾百條),但隨著項(xiàng)目的深入,我們卻發(fā)現(xiàn),代碼的質(zhì)量還是失控了。雖然表面上,每個(gè)人都在遵守著那些代碼規(guī)范,但其實(shí)他們的思維卻沒有得到很好的統(tǒng)一。想象一下,在一個(gè)閱兵式上,一隊(duì)身著統(tǒng)一制服的士兵,他們每個(gè)人的動(dòng)作都非常標(biāo)準(zhǔn),但他們都在按照自己的節(jié)奏和步點(diǎn)作著動(dòng)作,這場面是不是有些滑稽呢?

我所推薦的方法是推行模式(Patterns),在項(xiàng)目進(jìn)入開發(fā)階段前,就將那些開發(fā)過程中會(huì)遇到的相同類型的問題進(jìn)行分類,并為它們創(chuàng)建模式——標(biāo)準(zhǔn)處理方式,比如:

使用什么結(jié)構(gòu)來表示數(shù)據(jù)本身
采用哪種機(jī)制來進(jìn)行數(shù)據(jù)加工
如何進(jìn)行統(tǒng)一的錯(cuò)誤的處理
會(huì)話的管理及使用策略
哪些地方需要記錄日志
包與方法的命名 Name Convention
.......

在項(xiàng)目的進(jìn)行中,我們也需要不斷地去識(shí)別那些帶有共性的問題,并為它們建立新的模式,然后再推廣到項(xiàng)目中。我發(fā)現(xiàn),比起那些僵硬的規(guī)范,程序員們更樂意去理解這些模式,并把它們視作為項(xiàng)目中的最佳實(shí)踐,在開發(fā)中加以遵守。

深入理解并尊重你所使用的應(yīng)用框架

如果你沒有熟練掌握駕駛技術(shù),或者對所駕駛的車不熟悉的話,你將很難體會(huì)到駕駛所能帶給你的樂趣。而編程和駕駛一樣,你需要同時(shí)掌握所使用的編程語言和所在系統(tǒng)的應(yīng)用框架,才能非常自如地進(jìn)行開發(fā)。

每個(gè)公司或項(xiàng)目在開發(fā)一個(gè)產(chǎn)品時(shí),往往都會(huì)建立或使用一套自己的框架,它們一般都是基于Spring,Struts這樣的流行框架之上的。在大多數(shù)情況下,構(gòu)建應(yīng)用框架的目的并不是為了給開發(fā)者提供一個(gè)比Spring更強(qiáng)大的框架,恰恰相反,它們在大多數(shù)時(shí)候,是為了限制框架的使用,而使整個(gè)系統(tǒng)變得更加標(biāo)準(zhǔn)且易于維護(hù)。你需要理解這一點(diǎn),并在開發(fā)時(shí)盡可能使用你系統(tǒng)的應(yīng)用框架所提供的標(biāo)準(zhǔn)方法。如果框架無法滿足你的某些需求時(shí),嘗試與架構(gòu)師溝通,是否需要對應(yīng)用框架進(jìn)行擴(kuò)展,或找出合理的解決方案。如果你沒有這么做,而是跳過應(yīng)用框架,直接使用那些更底層的框架方法或API,將會(huì)給系統(tǒng)帶來壞味道,而這將引發(fā)連鎖反應(yīng),更多壞味道會(huì)接踵而至,導(dǎo)致整個(gè)項(xiàng)目代碼質(zhì)量的失控。

當(dāng)然,要想深入理解你所使用的應(yīng)用框架也絕不是件容易的事,光靠那些開發(fā)指南和代碼示例是不夠的,你還可以通過閱讀源碼,以及大量的實(shí)踐去深入地理解它們,訓(xùn)練出最有效使用它們的感覺。最終當(dāng)你進(jìn)行開發(fā)時(shí),那些正確且標(biāo)準(zhǔn)的應(yīng)用框架使用方法會(huì)非常自然地出現(xiàn)在你所敲擊的每一行代碼中。

不要使用過多的所謂技巧

當(dāng)我們的技術(shù)水平有所提升后,會(huì)不自覺地想著去使用一些不太常見的技巧。使用這些代碼往往能夠以非常Cool的方式快速解決問題,但如果這樣的代碼過多,便會(huì)給系統(tǒng)帶來難以維護(hù)的問題。

程序員們經(jīng)常使用的另一個(gè)所謂技巧便是“可配置”,他們經(jīng)常會(huì)在與用戶討論需求時(shí),推銷他們可配置的點(diǎn)子,好像只要做到了這一點(diǎn),他們所開發(fā)出來的功能就能勝人一籌似得,而結(jié)果往往是,那些所謂的可配置功能,用戶極少會(huì)去使用,而為了這些可配置,卻大大增加了系統(tǒng)的復(fù)雜性,而系統(tǒng)的性能也因此變得低下。

因此,我總是不鼓勵(lì)程序員們?nèi)戇^多Hack Code或?yàn)榱艘肽切┎槐匾目膳渲霉δ芏拐麄€(gè)系統(tǒng)過于復(fù)雜。

Design Review與Code Reivew都很重要

流程有時(shí)也能幫助我們寫出更好的代碼,Design Review和Code Review就是其中非常重要的兩個(gè)。Design Review能夠幫助我們在較早的階段就發(fā)現(xiàn)那些潛在的設(shè)計(jì)問題,并加以糾正,這往往能發(fā)揮事半功倍的效果。在實(shí)踐中,我總是會(huì)建議采用最簡單的設(shè)計(jì)文檔模板,并讓開發(fā)人員寫下真正體現(xiàn)他們所做程序設(shè)計(jì)的內(nèi)容,這一方面可以避免因過多Paper Work導(dǎo)致的效率降低,同時(shí)設(shè)計(jì)文檔中只包含那些真正重要的東西,也會(huì)使文檔本身變得更易于維護(hù)。

而在程序員開發(fā)完成后,由另一位較資深的程序員來進(jìn)行Code Review也能很好地識(shí)別出代碼中的一些疏漏,而更有益的是,通過這樣的Code Reivew能夠形成一種非常有效的反饋機(jī)制,幫助那些初級程序員快速成長。

讓你的架構(gòu)師忙起來

團(tuán)隊(duì)中有著不同的角色,項(xiàng)目經(jīng)理、產(chǎn)品經(jīng)理、業(yè)務(wù)分析人員、架構(gòu)師、資深開發(fā)工程師和普通開發(fā)工程師。而其中架構(gòu)師作為最技術(shù)的角色顯得尤為關(guān)鍵,他甚至可以成為一個(gè)項(xiàng)目成功與否的關(guān)鍵先生。

架構(gòu)師應(yīng)該承擔(dān)起應(yīng)用架構(gòu)、技術(shù)風(fēng)險(xiǎn)識(shí)別、指導(dǎo)團(tuán)隊(duì)開發(fā)等等很多工作,因?yàn)?strong>在真實(shí)的項(xiàng)目場景中,我們隨時(shí)面臨著架構(gòu)方面的問題,他不應(yīng)僅僅出現(xiàn)在項(xiàng)目的開始階段,而應(yīng)該服務(wù)于整個(gè)項(xiàng)目生命周期中,在需要解決棘手的技術(shù)問題時(shí),挺身而出,快速而準(zhǔn)確地解決問題。但遺憾的是我們經(jīng)??吹郊軜?gòu)師在團(tuán)隊(duì)中只起到了顧問的作用,他們甚至不親手寫一行代碼,只是給出一些系統(tǒng)部署、核心設(shè)計(jì)方面的建議后,就早早地退出了項(xiàng)目。

讓你團(tuán)隊(duì)中的架構(gòu)師忙起來,同樣對你團(tuán)隊(duì)成員的成長有很大的幫助,特別對于那些年輕程序員,通過理解架構(gòu)師給出的技術(shù)解決方案,以及閱讀他們所寫的代碼,都能幫助他們提高編程能力,而更重要的是,他們將慢慢學(xué)會(huì)像那些技術(shù)專家一樣進(jìn)行思考。

小比大好

最后讓我們回到編寫代碼本身上來,在文章的一開頭我就提到,對于那些復(fù)雜的程序邏輯,你很難寫出易讀的代碼,那真的是一點(diǎn)辦法也沒有嗎?我所能給出的唯一建議便是“小比大好”。當(dāng)一段邏輯變得比較長時(shí),就將它拿出,起一個(gè)與這段代碼功能相對應(yīng)的名字,封裝成一個(gè)新的方法。

這聽起來非常顯而易見,但我告訴你大部分程序員并不會(huì)那么做,因?yàn)樗麄兯坪踝裱硪粋€(gè)原則:只有當(dāng)一段邏輯會(huì)被多次調(diào)用(大于等于2次)時(shí),才為它創(chuàng)建一個(gè)新的方法。所以,我們便看到了包含幾百行代碼的方法。這個(gè)原則本身并沒有錯(cuò),但我們可以做適當(dāng)?shù)难a(bǔ)充,除了在考慮復(fù)用性上可以拆分方法之外,我們也可以為了代碼的可讀性和可維護(hù)性去進(jìn)行拆分,這樣將大大改善一個(gè)大的邏輯段的易讀性??赡苣阌謺?huì)問,如果這樣做了不是會(huì)讓代碼變得很散,到處都是方法嗎?我還是想說“小比大好”,就像我們現(xiàn)在修理汽車更多地是更換那些有問題的零件一樣,通過將邏輯拆分成更多小的部件,在維護(hù)時(shí)我們可以更方便地進(jìn)行替換從而降低開發(fā)成本以及因關(guān)聯(lián)性判斷不足帶來的風(fēng)險(xiǎn)。

雖然,我仍然無法寫出易讀的代碼,但通過對上面這些方法的實(shí)踐,我卻能在大多數(shù)項(xiàng)目中寫出易于維護(hù)的代碼,我想,這可能對于整個(gè)項(xiàng)目和團(tuán)隊(duì)來說,才是更加重要的吧!


簡書簽約作者:技匠,以上內(nèi)容歡迎大家分享到朋友圈/微博等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,048評論 25 709
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • DONE 做完了硅光電池的特性大物實(shí)驗(yàn)報(bào)告 聽了高數(shù)課,又得自己看書自己學(xué)了 TODO 進(jìn)行遞推算法ACM練習(xí) 把...
    small_pond閱讀 123評論 0 0
  • 閱讀及筆記時(shí)間:2017年7月,2日,約4小時(shí); 閱讀書本:《從文自傳》;作者:沈從文;2014年1月第1版;江蘇...
    時(shí)空山莊閱讀 979評論 0 1
  • 云向深藍(lán)流去素白得 如你風(fēng)中的一舉,嶙峋的光 加深終點(diǎn)的陰影,句點(diǎn) 風(fēng)中彈奏的三樓的鋼琴 我想我曾經(jīng)被誰從天空摔下...
    十七秒閱讀 198評論 0 1

友情鏈接更多精彩內(nèi)容