作為一名擁有15年開發(fā)經(jīng)驗(yàn)的工程師,最早讓我開始“懂事兒”的,是簡(jiǎn)潔明了的一句話:
出色的代碼,是表達(dá)能力更強(qiáng)的(expressive),而不是令人印象深刻的(impressive)。
我記得當(dāng)時(shí)自己對(duì)此感到很疑惑,表達(dá)能力更強(qiáng)的和令人印象深刻的,他們?cè)诒举|(zhì)上有什么區(qū)別呢?
實(shí)際上,表達(dá)能力更強(qiáng)意味著清晰、明確、具體。因此,一段表達(dá)能力較好的代碼需要能解決一個(gè)特定的問題。在為了寫這樣一段代碼所付出的時(shí)間與努力的背后,是非常清晰、明確、具體的目標(biāo),而這段代碼也必須能夠真正地實(shí)現(xiàn)這個(gè)目標(biāo)。
而令人印象深刻的,則表示要在寫代碼的過程中留下明顯的個(gè)人標(biāo)志或印記。一段自身結(jié)構(gòu)復(fù)雜,夾雜著多種深?yuàn)W算法的代碼,也許可以為你吸引來他人的關(guān)注、贊嘆與掌聲,在充分滿足你的虛榮心的同時(shí),也有可能轉(zhuǎn)化為那個(gè)在未來接替你繼續(xù)維護(hù)代碼的工程師的滿腔怒火。如果他正好是一個(gè)脾氣暴躁且知道你住在什么地方的人,那么接下來會(huì)發(fā)生的事情恐怕就不會(huì)那么讓你感到高興了。
這就是程序員應(yīng)該選擇明智而不是聰明的原因。一個(gè)精明的開發(fā)工程師需要具備那種能夠預(yù)見自己的哪些行為在什么情況下會(huì)帶來什么后果的能力,并能對(duì)「自己寫的是什么樣的代碼」、「自己為什么要這么寫」,以及「這些代碼在未來可能會(huì)有怎樣的演變」這三個(gè)問題有著清楚的認(rèn)知。簡(jiǎn)單來說,精明的工程師不會(huì)去做“亡羊補(bǔ)牢”式地救火開發(fā)工作,他們?cè)趯懘a時(shí)堅(jiān)信應(yīng)當(dāng)一勞永逸地解決問題。
而“聰明”的工程師則正好相反,他們做起開發(fā)工作來速度很快,也知道如何運(yùn)用各種歪門邪道的方法來讓代碼看起來可以“正常工作”。聰明的工程師擁有一種能快速通過“捷徑”來解決任何手邊問題的能力。但隨著時(shí)間的推移,那些不斷由“創(chuàng)可貼”和“膠帶”累積搭建起來脆弱代碼建筑,總有一天會(huì)崩塌,然后讓所有為之付出過心血的人都感到蒙羞。就像美國(guó)著名軟件工程師、Construx Software 公司創(chuàng)始人 Steve McConnell 在其 1993 年的著作《代碼大全》中所寫到的:
編程,可不能像為美國(guó)中央情報(bào)局工作那樣,偷偷摸摸、投機(jī)取巧并沒有什么好處。
精明的開發(fā)工程師絕不會(huì)做見風(fēng)使舵的事,他們寫出的代碼平淡但卻簡(jiǎn)潔易懂,不會(huì)太出彩,但也不會(huì)出差錯(cuò)。
除此之外,精明的工程師還有一些其他值得學(xué)習(xí)的做事習(xí)慣。
ThoughtWorks 首席科學(xué)家 Martin Fowler 認(rèn)為,
任何人包括傻瓜都能寫出計(jì)算機(jī)能看懂的代碼,但只有優(yōu)秀的程序員才能寫出其他人也能看懂的代碼。
程序員有的時(shí)候會(huì)莫名覺得自己需要去證明些什么事情,或者是需要向其他人展示自己的能力以說明自己能夠勝任現(xiàn)在的工作崗位。這種想法會(huì)導(dǎo)致他們?cè)趪L試解決每個(gè)問題的過程中,優(yōu)先選擇那些更復(fù)雜、更困難的方法,而忽略就在眼前擺著且是最直接、最簡(jiǎn)單的解決方案。這是每個(gè)開發(fā)工程師都很容易犯的,同時(shí)也是最糟糕的錯(cuò)誤。
精明的程序員會(huì)直截了當(dāng)?shù)貙懘a,這些代碼在后續(xù)的工作中易于維護(hù)、優(yōu)化或重構(gòu),不會(huì)出現(xiàn)任何奇葩或難以預(yù)料的問題,其他同事看了這些代碼也能準(zhǔn)確地知曉其意圖以及解決問題的思路。而那些新穎的、不尋常的算法或是開發(fā)思路,再配上程序員那副熬了一整夜的疲憊卻又自豪的表情,有時(shí)在上級(jí)或同事看來確實(shí)很棒。但在其引發(fā)一場(chǎng)可悲的失敗時(shí),很可能也會(huì)更加“耀眼”。
不論什么時(shí)候,只要你在寫代碼時(shí),如果你的自負(fù)心理開始影響、誘惑你,那你最好問自己這樣一個(gè)問題:「假如你離開了這項(xiàng)工作兩個(gè)月時(shí)間,等你再回來繼續(xù)工作時(shí),還能看得懂這些代碼嗎?」如果你的回答是肯定的,那么你就可以完全按照自己的想法和意愿去寫這段代碼,只是請(qǐng)對(duì)你的繼任者手下留情 ── 為了不需要過多地解釋這段代碼,請(qǐng)?jiān)诤线m的位置加上注釋,合理地為各種變量命名,并盡可能地將其進(jìn)行模塊化處理。
高質(zhì)量的代碼,就像一個(gè)玩笑。如果必須要通過額外的解釋才能讓別人看懂,那這就不是一段好代碼。
已故荷蘭系統(tǒng)科學(xué)專家、著名軟件開發(fā)工程師、計(jì)算機(jī)科學(xué)先驅(qū) Edsger W. Dijkstra 曾提出,
關(guān)注「為什么」而不是關(guān)注「是什么」,能讓你成為更出色的開發(fā)工程師。
優(yōu)化代碼的方法有很多種,比如可以調(diào)用更多內(nèi)存,或是加快運(yùn)行速度,或是采用不同的算法和邏輯思路。而不管用哪種方法,只要客觀條件允許,精明的開發(fā)工程師都會(huì)明智地做出決定。但在開始進(jìn)行任何優(yōu)化工作之前,他們會(huì)嚴(yán)格遵守「『不要』準(zhǔn)則」:
我為什么要這么做?這些代碼寫得足夠好嗎?在了解、明確程序?qū)⒈蝗绾问褂靡约捌溥\(yùn)行環(huán)境的情況下,如果加快運(yùn)行速度的話會(huì)帶來任何好處嗎?這些問題你都應(yīng)該提前問問自己。
如果一個(gè)非常重要的程序運(yùn)行得很慢,同時(shí)開發(fā)團(tuán)隊(duì)又期望在維持魯棒性、準(zhǔn)確性、清晰度的同時(shí)能讓它變快一些的時(shí)候,優(yōu)化工作才能在付出與成本上顯現(xiàn)出意義。然而,一個(gè)運(yùn)行很快但卻得到了與預(yù)期相反結(jié)果的程序,仍然沒有任何意義。高效率的代碼優(yōu)化工作通常能帶來更多的益處,但如果你沒有按照正確的方式去進(jìn)行優(yōu)化的話,結(jié)果可能非但無益還附帶了更多缺陷。
無論你做了什么優(yōu)化上的工作,都應(yīng)當(dāng)是效果顯著的、可衡量的。不要總是依賴直覺,直覺永遠(yuǎn)都是糟糕的指南針。
復(fù)用而不是寫新的代碼
前谷歌公司高級(jí)副總裁 Vic Gundotra 曾提出過一個(gè)直擊問題要害的觀點(diǎn):
寫代碼之前,我必須要先去搞清楚他們真正想要什么。
精明的程序員更喜歡先看代碼,接著到處尋找可行的、已有的解決方案。而另外一些工程師則喜歡在「以正確的方法進(jìn)行重建」。在大多數(shù)情況下,這些人都是在重復(fù)造輪這件事上浪費(fèi)時(shí)間。
不要害怕花時(shí)間在尋找上,在互聯(lián)網(wǎng)上或是你的代碼數(shù)據(jù)庫(kù)中搜索那些已經(jīng)被實(shí)踐過的的解決方案,將有助于你去學(xué)習(xí)、掌握解決類似問題的通用方法,以及與之相關(guān)的各種利弊。這就是為什么精明的工程師在寫代碼之前會(huì)花更長(zhǎng)時(shí)間先去看代碼。因?yàn)橹貙懸欢稳碌拇a,總是要耗費(fèi)更多的時(shí)間、成本和精力的。除非萬不得已,否則不要這么做。
因此當(dāng)你需要完成一項(xiàng)任務(wù)時(shí),最好先去查一查是否有人已經(jīng)做過解決類似問題的事了,這不是在抄近道耍小聰明,這是在節(jié)省不必要耗費(fèi)的力氣。
挑戰(zhàn)自我
古希臘哲學(xué)家亞里士多德曾說過,
如果你正在做的事情并沒有什么挑戰(zhàn),那么做這件事就不會(huì)讓你變得更好。
精明的程序員總是會(huì)挑戰(zhàn)自我,更準(zhǔn)確地說,是抓住每個(gè)機(jī)會(huì)來挑戰(zhàn)他們自己寫的代碼。他們總是能謙虛地意識(shí)到,沒有最完美的代碼,只有更出色的代碼。
精明的程序員也不會(huì)安逸于呆在自己的舒適區(qū),然后重復(fù)不斷的按照同樣的模式實(shí)施部署工作。他們會(huì)有意識(shí)地避免自己的代碼參數(shù)設(shè)置受到教條主義思想的干擾,并總是會(huì)尋找合適的方法與手段把事情做得更好,即便這意味著需要去花時(shí)間學(xué)習(xí)新的東西,他們?nèi)匀粫?huì)全力以赴。
精明的程序員是不會(huì)被浮夸的想法與花哨的功能所吸引的。他們能很務(wù)實(shí)地認(rèn)識(shí)到,完美的解決方案并不存在,每一個(gè)杰出的功能或神奇的技巧都伴隨著不同的弊端。
敢于向其他人求助
古希臘劇作家、悲劇詩(shī)人索??死账乖嘈?,
如果我們每個(gè)人都能真正地做到互相幫助,那么就沒有人再需要好運(yùn)氣了。
身為程序員,總是會(huì)自認(rèn)為是比較理智、機(jī)靈的那種人。事實(shí)上,有不少的開發(fā)工程師確實(shí)是天賦異稟。但有的時(shí)候,程序員們也會(huì)過度自信地認(rèn)為自己是無所不知的,可以憑借自己的大腦解決任何問題。畢竟,沒有人愿意在工作會(huì)議上承認(rèn)「這個(gè)我不會(huì)」,或者是對(duì)即將要部署的新功能一竅不通。
所以,他們會(huì)不停地告訴自己:「我會(huì)自己想辦法解決的。我過去總是依靠自己的力量,現(xiàn)在依然可以繼續(xù)這樣。」
然而,精明的程序員卻不會(huì)這樣想。他們知道何時(shí)該去求助,何時(shí)該保持獨(dú)立思考。他們清楚地知道任何拖延都可能讓整件事情向不可控制的方向發(fā)展并最終演變?yōu)?,團(tuán)隊(duì)中的每個(gè)人都將在無止境的焦慮與令人近乎絕望的壓力下看著項(xiàng)目截止日期不斷臨近。而這就是精明的程序員能夠在必要時(shí)勇敢地暴露出自己的不足并向他人及時(shí)求助的原因。
向他人求助并不是對(duì)自身能力的一種質(zhì)疑,實(shí)際上這反而鞏固了他人對(duì)你的信任與信心,因?yàn)樗麄兛吹搅四隳軌虿幌б磺写鷥r(jià)地履行自己的職責(zé)并按時(shí)交付符合預(yù)期的工作成果。你在他人心中的印象,也將變?yōu)橐晃挥羞M(jìn)取心的、自信的,且每天都希望讓自己變得更好的開發(fā)工程師。
正如印度最佳女主持人獎(jiǎng)獲得者、演員、模特 Kubbra Sait 所說的,
提出問題,是開始變得更好的第一步。
聯(lián)系客服