程序員修煉之路:你該知道的 7 個(gè)必經(jīng)階段
當(dāng)我做完設(shè)計(jì)相關(guān)的培訓(xùn)分享過后,有同學(xué)來問我:如何才能快速提升自己的設(shè)計(jì)能力?我覺得這個(gè)問題非常有代表性,代表了一大波程序猿在艱辛的修煉路上的心聲?,F(xiàn)將我對(duì)這個(gè)問題的思考、心得體會(huì)分享出來,供大家參考,也歡迎提出不同的意見與看法,共同探討。
一 編碼歷練
代碼行經(jīng)驗(yàn)是個(gè)非常重要的東西,當(dāng)你還沒有 1 萬行代碼經(jīng)驗(yàn)的時(shí)候,你來問如何提升設(shè)計(jì)能力的問題,我只能告訴你不要太糾結(jié),理論看看就好,老老實(shí)實(shí)寫代碼吧。
據(jù)說,一個(gè)程序員平均每天碼代碼的速度是 200~300 行,你可能會(huì)說,我一天怎么也要寫上 1000 行吧,別忘了,當(dāng)你碼完代碼后,你還需要測試、調(diào)試、優(yōu)化、BUG Fix,這些時(shí)間你沒法一直碼代碼的。
編碼規(guī)范就不多說了,如果你的代碼還是雜亂無章的狀態(tài),就先別談什么設(shè)計(jì)與架構(gòu)了,我會(huì)覺得有點(diǎn)扯淡。
另外,作為代碼潔癖患者,推薦大家不要把代碼寫完后,批量格式化處理,或者手工再去整理代碼,而是每敲一個(gè)字符上去,它都是符合規(guī)范的。習(xí)慣真的很重要,有時(shí)在招聘面試的時(shí)候,我真想添加一個(gè)環(huán)節(jié),現(xiàn)場編寫程序完成一個(gè)簡單但容易出錯(cuò)的任務(wù)。
二 理論學(xué)習(xí)
簡單說就是看書,看博客,你所能得到的資源,質(zhì)量高的就行。例如:《重構(gòu) - 改善既有代碼的設(shè)計(jì)》、《敏捷軟件開發(fā):原則、模式與實(shí)踐》、《UML 和模式應(yīng)用》、"面向?qū)ο笤O(shè)計(jì)原則"(五大原則)、《設(shè)計(jì)模式》等。
《設(shè)計(jì)模式》這本書是很古老的一本書了,只有短短 200 頁,但是,這是最難看懂的一本書,一個(gè)月都可能看不完(看小說的話,200 頁 3 個(gè)小時(shí)也許就看完了吧),而且就算看完了,也不會(huì)全看懂,很可能看懂不超過 30%。看不懂沒關(guān)系,看了就行,不用太糾結(jié),這不能說明什么問題。
另外,我想說一下,多線程技術(shù)是程序員必須掌握的,而且需要理解透徹,現(xiàn)在的高級(jí)技術(shù)例如 GCD,會(huì)掩蓋你對(duì)多線程理解不足的問題,因?yàn)槭褂脤?shí)在太簡單了。別說你沒寫過多線程依然完成了復(fù)雜的項(xiàng)目,更別說你隨手寫出的多線程代碼好像也沒出什么問題啊,把你的代碼給我,我寫個(gè) Demo 讓它出錯(cuò)乃至崩潰,如果我做不到,恭喜你。
三 實(shí)踐
現(xiàn)在,你已經(jīng)具備了一定的編碼經(jīng)驗(yàn),而且已經(jīng)學(xué)習(xí)了足夠的理論知識(shí),接下來就是真正練手的時(shí)候了。好好反復(fù)思考你學(xué)習(xí)的這些理論知識(shí),要如何運(yùn)用到項(xiàng)目中去,身體力行的去實(shí)踐,一定要把那些理論搞清楚,用于指導(dǎo)你的實(shí)踐,收起從前的自信,首先否定自己以前的做法,保證每次做出的東西相比以前是有進(jìn)步有改進(jìn)的。
四 重溫理論
你已經(jīng)能看到自己的進(jìn)步了,發(fā)現(xiàn)比以前做的更好了,但是總感覺還不夠,好像有瓶頸似的,恭喜你,我已經(jīng)能看到你未來的潛力了。
重新拿起書本,重溫一遍之前看的似懂非懂的東西,你會(huì)發(fā)現(xiàn)之前沒弄懂的東西,現(xiàn)在豁然開朗了,不再是那種難于理解的晦澀感了。就算是以前你覺得已經(jīng)弄懂的,也再看一遍,通常會(huì)有新的收獲。
五 再實(shí)踐
這個(gè)階段,你已經(jīng)掌握了較多的東西了,不但實(shí)踐經(jīng)驗(yàn)豐富,各種理論也能手到擒來了,但是你發(fā)現(xiàn)你的設(shè)計(jì)依然不夠?qū)I(yè)。而且你回過頭去看你以前寫的代碼,你會(huì)驚訝:天啊,這是誰寫的代碼,怎么能這樣干!然后。。。我就不多說了,你已經(jīng)進(jìn)入了自省的階段,掌握了適合自己的學(xué)習(xí)方法,再要學(xué)習(xí)什么新東西,都不再是個(gè)事。
六 總結(jié)
先別太得意(不信?那你去做一堂講座看看),你需要總結(jié)了,總結(jié)自己的學(xué)習(xí)方法,總結(jié)項(xiàng)目經(jīng)驗(yàn),總結(jié)設(shè)計(jì)理論知識(shí)。
如果你能有自己獨(dú)到的理解,而不是停留在只會(huì)使用成熟的設(shè)計(jì)模式什么的,能根據(jù)自己的經(jīng)驗(yàn)教訓(xùn)總結(jié)一些設(shè)計(jì)原則出來,那自然是極好的。
七 分享
分享是最好的學(xué)習(xí)催化劑,當(dāng)你要準(zhǔn)備一場培訓(xùn)分享的時(shí)候,你會(huì)發(fā)現(xiàn)你先前以為已經(jīng)理解的東西其實(shí)并沒有真正理解透徹,因?yàn)槟銦o法把它講清楚,實(shí)際上就是研究不夠,這時(shí)會(huì)迫使你去重新深入學(xué)習(xí),融匯貫通,然后你才敢走上講臺(tái)。否則當(dāng)別人提問的時(shí)候,你根本回答不上來?! ∫陨?,便是我認(rèn)為的程序員修煉道路的必經(jīng)階段?!∪缓?,我再說說其他對(duì)提升非常重要的幾點(diǎn):
養(yǎng)成先設(shè)計(jì),再編碼的習(xí)慣
幾乎所有的程序員,一開始都不太愿意寫文檔,也不太愿意去精心設(shè)計(jì),拿到需求總是忍不住那雙躁動(dòng)的手,總覺得敲在鍵盤上,一行一行的代碼飆出來,才有成就感,才是正確的工作姿勢。
沒討論清楚不要編碼,不然你一定會(huì)返工。
設(shè)計(jì)重于編碼,接口重于實(shí)現(xiàn)
制定接口的過程,本身就是設(shè)計(jì)過程,接口一定要反復(fù)推敲,盡量做減法而不是加法,在能滿足需求的情況下越簡單越好。
另外,不要一個(gè)人冥思苦想,先簡單做一個(gè)雛形出來,然后拿去找使用方溝通,直到對(duì)方滿意為止。
不要完全根據(jù)使用需求去設(shè)計(jì)接口,參考 MVVM,ViewModel 就是根據(jù) View 的需要而對(duì) Model 進(jìn)行的再封裝,不能將這些接口直接設(shè)計(jì)到 Model 中。
不盲從設(shè)計(jì)模式
設(shè)計(jì)模式只是一種解決問題的套路方法,你也可以有自己的方法,當(dāng)然設(shè)計(jì)模式如果用好了,會(huì)讓你的設(shè)計(jì)顯得專業(yè)與優(yōu)雅,畢竟前輩們的心血結(jié)晶。但是濫用的話,也會(huì)導(dǎo)致更嚴(yán)重的問題,甚至可能成為災(zāi)難。個(gè)人覺得面向?qū)ο笤O(shè)計(jì)原則更加重要,有些原則是必須遵守的(如單向依賴、SRP 等),而設(shè)計(jì)模式本身都是遵守這些原則的,有些模式就是為了遵循某原則而設(shè)計(jì)出來的。
抽象不是萬能的,在適當(dāng)?shù)牡胤绞褂?,需要仔?xì)推敲。當(dāng)有更好的方案不用抽象就能解決問題時(shí),盡量避免抽象,筆者見過太多的抽象過火過度設(shè)計(jì)的案例了,增加了太多維護(hù)成本,還不如按照最自然的方式去寫。
空杯心態(tài),向身邊的同學(xué)學(xué)習(xí),站在巨人的肩上,站在別人的肩上
有人提意見,先收下它(無論接受與否)。
很多程序猿,也都有一個(gè)毛病,就是覺得自己技術(shù)牛的不行,不愿意接受別人的意見,尤其是否定意見(文人相輕)。
而無論是理論的學(xué)習(xí),還是編碼實(shí)踐,向身邊的同學(xué)學(xué)習(xí)將是對(duì)自己影響很大的(三人行,必有我?guī)?,比刻意參加相關(guān)培訓(xùn)要有用的多。
我自己就經(jīng)常在跟團(tuán)隊(duì)同學(xué)的討論中獲益,當(dāng)百思不得解的時(shí)候,把問題拋出來討論一下,通常都能得到一個(gè)優(yōu)秀方案。
另外,跟團(tuán)隊(duì)其他人討論還有一個(gè)好處,就是當(dāng)你的設(shè)計(jì)有妥協(xié),有些不專業(yè)的時(shí)候,別人看到代碼也不會(huì)產(chǎn)生質(zhì)疑,因?yàn)樗麉⑴c了討論的,你不用花那么多時(shí)間去做解釋。
設(shè)計(jì)期間就一定要找他人討論,我一直比較反對(duì)一個(gè)人把設(shè)計(jì)做完了,把文檔寫完了,然后才找大家開個(gè)評(píng)審會(huì)那種模式,雖然也有效果,但是效果真的達(dá)不到極致,大家沒有參與到設(shè)計(jì)中來,通過一場會(huì)議的時(shí)間理解不一定有那么深,最關(guān)鍵的是,如果設(shè)計(jì)有些問題的時(shí)候,但也不是致命問題,難道還讓打回重新設(shè)計(jì)么?
等前期討論足夠后,大家都知道你的思路與方案,而且最后也有設(shè)計(jì)文檔,當(dāng)其他人來閱讀你的代碼的時(shí)候,根本無需你再指引,今后的工作交接都不是很需要了,何樂而不為呢?
最后,我想在此呼吁一下,當(dāng)你去修改維護(hù)別人的代碼時(shí),最好找模塊負(fù)責(zé)人做深入的討論溝通,讓他明白你的需求以及你的方案,請(qǐng)他幫忙評(píng)估方案是否可行,是否會(huì)踩坑、埋坑等。這樣我們的項(xiàng)目才不會(huì)出現(xiàn)壞味道蔓延,而如果你恰好是某模塊負(fù)責(zé)人,請(qǐng)行使你的權(quán)力,拒絕有問題的不符合要求的代碼提交入庫。
大家共勉。