入職Apifox研發(fā)組三個月,我領(lǐng)悟了30個高效開發(fā)方法
?? 前言
從去年入職Apifox研發(fā)組至今,已經(jīng)有快「四個月」的時間了,今天來跟大家分享一下我的感想??。
寫這篇文章的契機(jī)是在年后我成功通過「三個月試用期」,也算是給自己一個交代,從自身出發(fā)來進(jìn)行反思與總結(jié)在這「三個月」學(xué)到的東西與一些感想???。
?? 我學(xué)會了什么
在這「三個月內(nèi)」我更多接受到的是工作或者說是寫代碼甚至作為程序員「應(yīng)該掌握的方法」,而這些方法「不在于」你是什么技術(shù)?;蛘哒f什么職位都很有用??,所以今天我就來分享一些我總結(jié)的30個方法,我主要分成??代碼方面和??程序員方面。
?? 代碼方面
學(xué)會表達(dá)
當(dāng)你在寫一個復(fù)雜的表達(dá)式甚至需要用到這些表達(dá)式來做判斷的時候,這時候要養(yǎng)成一個習(xí)慣把表達(dá)式換成一個變量來表示??,別人才能語義化的理解你這個表達(dá)式。
自己寫的代碼不管你寫的再復(fù)雜你自己都可以看懂,但是對于別人不同,如果你把你的這些表達(dá)式賦值給一個變量,「這樣別人只需要知道這個變量是什么意思就行了」。
學(xué)會復(fù)盤
中級與高級的程序員有一個差別是,優(yōu)秀程序員肯定至少會花一些時間來「清理??自己的代碼」。
這么做是因?yàn)椋麄冎勒麧嵑每吹拇a比雜亂無章的代碼更容易修改,「甚至他們知道自己幾乎無法一開始就寫出整潔的代碼????」。
雖然我自己也沒有完全嚴(yán)苛遵守,但是還是希望大家多去復(fù)盤,因?yàn)楫?dāng)你去看了你之前寫的代碼后你會發(fā)現(xiàn)很多樂趣(覺得自己寫的代碼可笑??)。
擁抱變化
永遠(yuǎn)都不要說我寫的功能 「"總是滿足我們的需求"」 ,在做項(xiàng)目開發(fā)特別是公共模塊,你要學(xué)會「擁抱變化」??, 永遠(yuǎn)要考慮變化的情況。
養(yǎng)成一個習(xí)慣,在做一個公共模塊的時候要考慮后面有沒有實(shí)現(xiàn)變化的可能或者能不能封裝成一個js模塊??,而不是直接用第三方庫?。
特別是我們是做客戶端而不是簡簡單單的單頁網(wǎng)頁,而這里的公共模塊指的是 「"使用者只用用到你的提供出來的API就知道怎么用了,并不需要使用者去考慮里面的實(shí)現(xiàn)"」
學(xué)會修BUG
很多人在接到一個BUG需求的時候經(jīng)常只關(guān)注 「"眼前"」 ,即只關(guān)注遇到的問題而沒有考慮其原本的意義。
你要做的其實(shí)不止是修改好這一個「缺陷」而是要去思考??為什么他會出現(xiàn)這個「缺陷」,一定要關(guān)注上下文。
在修改一個舊的模塊引發(fā)的BUG的時候,我們要保證不影響原來的功能邏輯,考慮清楚再commit,否則就會出現(xiàn)經(jīng)常遇到的 「"改了BUG生成另一個BUG??"」 。
多用結(jié)構(gòu)化數(shù)據(jù)
在你所做的一個組件邏輯「很復(fù)雜」的時候,更要考慮清楚它的結(jié)構(gòu),「多用結(jié)構(gòu)化數(shù)據(jù)」,定義一個數(shù)據(jù)結(jié)構(gòu)來存儲中間狀態(tài),而不應(yīng)該永遠(yuǎn)用簡單的狀態(tài)?。
「所有復(fù)雜的組件你的狀態(tài)復(fù)雜是可以接受的,但是有多個狀態(tài)是不可接受的」。
因?yàn)槿绻髅骺梢杂媒Y(jié)構(gòu)化狀態(tài)來存儲,反而用多個狀態(tài)組合實(shí)現(xiàn)的話,你這個組合關(guān)系就很復(fù)雜了。
確定一個你所需要的數(shù)據(jù)結(jié)構(gòu),「所有的操作都以這個數(shù)據(jù)結(jié)構(gòu)為目標(biāo)」,這個數(shù)據(jù)結(jié)構(gòu)可以是一個對象可以是一個數(shù)組任何你期望的值,這樣最后只需要拿到這個結(jié)構(gòu)化數(shù)據(jù)來進(jìn)行簡單處理,所有的問題都迎刃而解了。
不要怕錯
很多人包括我自己在進(jìn)入一個新的公司或者面對一個別人正在開發(fā)的項(xiàng)目難免都會有一個問題:「"不夠自信"」 。
在看到別人的代碼時候難免會看見別人明顯的錯誤,而在當(dāng)下你看來可能對自己編碼不自信而不愿意幫忙改正,又怕改了之后被同事責(zé)怪,但這是不對的?。
不要怕改錯代碼,「如果在當(dāng)時看到一個錯誤或者命名不規(guī)范而你覺得有更好的名字或者重構(gòu)方法可以及時改正」,就算是改錯了那就在CodeReview的時候提出來讓大家提建議。
這樣在下次見到這段代碼時就不要重復(fù)努力搞懂邏輯,因?yàn)楹芸赡芟麓芜€會是你繼續(xù)改動這個模塊。
每次只關(guān)心一個上下文
如果某個模塊經(jīng)常因?yàn)椴煌脑蛟诓豢深A(yù)知的方向上發(fā)生變化,那么這個模塊就變的很散亂了。
當(dāng)你需要在原有基礎(chǔ)上根據(jù)一種條件新增功能的時候,我可能需要更改三個函數(shù),兩個變量,這樣的話就會很煩躁了,在如今這么內(nèi)卷的時代再煩躁起來得有多難受??。
我們要養(yǎng)成一種習(xí)慣每個函數(shù)只干一件事情,「將一個功能按照不同模塊劃分開來」,分成數(shù)個上下文而每次我們修改功能的時候只需要找到對應(yīng)的模塊來修改就很清晰了,我們只需要關(guān)注那一個上下文就可以了。
消滅注釋
盡可能少的添加注釋,特別是團(tuán)隊(duì)開發(fā),有很多人不理解為什么???我舉個最簡單的例子:「如果這個函數(shù)以后功能變了,除了我們需要改里面的代碼還需要幫忙改變函數(shù)命名還要一起把之前的注釋也改了」,假如一個函數(shù)有「5-6行」注釋這么多,那你是不是每個都要改?
當(dāng)然在不添加注釋的前提下我們要保證我們函數(shù)命名變量命名「盡可能語義化」????。
任何你覺得需要注釋的地方,99%是因?yàn)檫@段代碼不合理。
每當(dāng)你需要用注釋來說明什么的時候,我們要做的不是用文字去解釋這段代碼,「而是把我們需要說明注釋的東西寫進(jìn)一個獨(dú)立函數(shù),并以它的用途取個語義化的名字?」。
甚至我們可以用短短幾行的小函數(shù)來代替這件事情,哪怕之后調(diào)用函數(shù)的步驟變多,但是只要每個函數(shù)命名足夠語義化,就能用代碼合理的解釋你想要做的一切。
函數(shù)的長度關(guān)鍵不在于有多長而是在于可讀性,「在于"??如何做 "和"??做些什么"」 。
不畏注釋
我們通過上面的方法可以有效的減少在代碼內(nèi)的注釋但是對于別人已經(jīng)遺留的注釋我們應(yīng)該置之不理嗎?
如果在修改的功能模塊發(fā)現(xiàn)原來存在注釋,不要去抱怨,這對你沒有一點(diǎn)好處,「相反的這可能是個很好的信號去告知我們應(yīng)該去對這段代碼進(jìn)行修改」,而通過這些注釋可以精準(zhǔn)的幫我們定位到他的問題所在。
學(xué)會命名
如果在編寫一個函數(shù)的時候你無法對其進(jìn)行命名,「那么這個函數(shù)多數(shù)是設(shè)計不合理的」,就像我們上面提到的,函數(shù)里面表達(dá)的是 「"如何做"和"做些什么"」 ,而我們對函數(shù)的命名也切記按照這個原則。
當(dāng)你真正對一個函數(shù)準(zhǔn)確命名,那么這里面的結(jié)構(gòu)往往是「可讀性高」的。
做任何業(yè)務(wù)都「不要把實(shí)現(xiàn)寫在函數(shù)名」上,以后如果別人需要改動函數(shù)邏輯,還要幫你把函數(shù)名字給改動了。
合理入?yún)?br>對于攜帶參數(shù)的函數(shù)的命名也是有講究的,我們通?!缚梢允褂猛ㄓ玫拿謥泶韰?shù)命名」而不是使用在當(dāng)下具體的名稱,比如:「apiSelectedKey=>selectedKey」
修改的好不僅能增加函數(shù)的應(yīng)用范圍,還能改變連接一個模塊所需的條件,從而去除不必要的耦合。
學(xué)會提煉函數(shù)
在簡化代碼塊的時候,我們最喜歡的就是提煉函數(shù),「提煉函數(shù)可以讓我們將意圖與實(shí)現(xiàn)分開」。
并以意圖命名函數(shù),但是如果發(fā)現(xiàn)自己并不能合理命名,說明你不應(yīng)該提煉這個函數(shù)?????,你應(yīng)該考慮更多。
學(xué)會返回
上面講了兩個關(guān)于函數(shù)命名的方法,而往往在小函數(shù)內(nèi)我們對于內(nèi)部的變量會 「"詞窮"」 。
大部分的函數(shù)都可以使用result作為返回值,在函數(shù)開頭定義,在函數(shù)結(jié)尾return,這樣下次看這段代碼的人一下就知道要返回的是什么??。
考慮時機(jī)
往往我們剛拿到一個新需求的時候很容易去實(shí)現(xiàn)它的功能,甚至不會去調(diào)研,修改BUG也是如此。
這是很容易的,任何一個程序員都可以做到,但是在什么時機(jī)做這個 「"動作"」 是應(yīng)該考慮清楚的,點(diǎn)擊的時候?依賴變化的時候?函數(shù)返回的時候?
我就吃過這個虧,「在不恰當(dāng)?shù)拇a恰好完成了需求但是引發(fā)了一些不可控的缺陷」,導(dǎo)致我要重復(fù)讀這整個模塊的代碼,不僅拖慢了項(xiàng)目進(jìn)度還讓自己多掉了幾扎頭發(fā)??。
保持可拓展性
在拿到一個新需求的時候永遠(yuǎn)永遠(yuǎn)不要想著做完就ok,因?yàn)槟銦o法保證以后會不會讓你在這個基礎(chǔ)上增加新的功能甚至在你commit后的一個小時,產(chǎn)品的需求如果你沒有優(yōu)秀的產(chǎn)品思維是捉摸不透的??,所以要給自己留 「"一條后路"」 。
而這而最常見的無非就是各種判斷,根據(jù)不同的判斷來讓程序走不同的代碼,這時候我們不能寫死判斷而是多去使用map結(jié)構(gòu)來保持功能可拓展性??。
巧用模塊
如果你發(fā)現(xiàn)兩個模塊之間「需要交流」,或許你可以新建一個模塊??來存放。
在做一個需求的時候,如果很多函數(shù)跟變量都是「從不同的第三方庫引入」,這時候不妨把它歸為一個模塊,「就算是函數(shù)變量名字一摸一樣都可以」。
只要保證是在這個模塊里面導(dǎo)出就可以,這樣后面的人更加方便維護(hù)這個模塊,屏蔽這個實(shí)現(xiàn)。
「使用的人不關(guān)心用,只關(guān)心結(jié)果」,就類似中間層??。
?? 程序員方面
巧用方法
有很多人想入行這個行業(yè),「他要學(xué)的就是方法」,就比如說 「《重構(gòu)》」,「《代碼整潔之道》」 這些書講的都是方法,教的就是方法??。
你一個架構(gòu)師寫的代碼好,去到一個新的項(xiàng)目怎么提現(xiàn)他的作用,還是「因?yàn)樗姆椒ê?,而不是他寫過的代碼有多好」。
「只有你的方法好,你后面新產(chǎn)出的代碼才會好」。
擇善而從
當(dāng)你覺得你在做重復(fù)的工作的時候,「一定是你做的方式不對,而不是這個任務(wù)不對」。
你任何一個任務(wù)都有可學(xué)習(xí)的地方,「我們做的是腦力活動,不存在像搬磚那樣的情況」,一定會有更好的方案,只是你沒有發(fā)現(xiàn)??。
你可以通過研究別人的app看很多的源碼,看別人的相同效果是怎么做的,「擇善而從自己去實(shí)現(xiàn)一個新的方案」。
「當(dāng)你實(shí)現(xiàn)完了之后,你就是這種功能的大神」,以后再去面試別人公司的時候,你就說你在之前的公司,做了xxx功能的方案,吸收了業(yè)界很多類似xxx功能方案的長處,別人就會覺得你很牛逼,但是如果你只是說你之前重復(fù)的做xxx功能的某些事情那別人直接就把你刷掉了??。
學(xué)會參考
「作為程序員就是要不斷看別人的代碼??」,哪種代碼寫得好,哪種寫得不好,哪些是值得去參考的,「自己心里要有一個底」,如果你不確定這個好不好,你就百度、谷歌、看源碼。
API設(shè)計的過程中除非你是經(jīng)驗(yàn)豐富的人,否則就得學(xué)會參考,任何一個程序員入門的方式都是抄襲,看別人怎么實(shí)現(xiàn)看別人代碼怎么寫。
「一個入門程序員、一個中級程序員一上來就給你設(shè)計一套很舒服的API這是不可能的??」,參考開源大佬的項(xiàng)目,參考別人設(shè)計的時候?yàn)槭裁催@么做,不能自己純想。
產(chǎn)品思維
「有產(chǎn)品思維是好的,能理解產(chǎn)品需求,能與產(chǎn)品進(jìn)行有效溝通這是優(yōu)勢」。
這時候你就需要學(xué)會「跳出程序員的維度,擁有多學(xué)科交叉的能力??」,要去「了解」產(chǎn)品「提這個需求的目的」,因?yàn)樵跊]了解的情況下,你按照自己的產(chǎn)品思維去認(rèn)為這個需求的不同會導(dǎo)致想法過度或不及。
在不了解的情況下要多與產(chǎn)品交流,一定不要自己想當(dāng)然,當(dāng)你覺得應(yīng)該怎么去做,「可以帶方案去找產(chǎn)品討論」。
適當(dāng)做減法
你要想把一個需求做到100分可能是很難的,但是對于用戶來說這個需求可能做到60分已經(jīng)不錯了,「剩下的40分就需要跟產(chǎn)品溝通什么時候把它做到100分??」。
這也是所謂的什么時候該干什么樣的事情,現(xiàn)階段你做起來可能會很吃力花費(fèi)很多時間,但或許2個月后的你來改這段代碼輕而易舉。
學(xué)會做需求
「接到一個新需求要列方案、調(diào)研????」,方案有很多種,看起來都很可行,但是實(shí)際上合不合適還是需要調(diào)研??,否則做到一半后就要重新更換方案,不然就只能在產(chǎn)品上做妥協(xié)。
在明確了自己的方案并有一種想法的時候,「多去嘗試,嘗試使用它」。如果后來發(fā)現(xiàn)不太合適,完全可以再重來 完全沒有問題,「只要在里面學(xué)到了東西,時間就不會白費(fèi)」。就算你覺得不穩(wěn)妥,在CodeReview提出來,自然會被指出錯誤。
當(dāng)然我們在做一個需求的時候「不能局限于這個需求」,也就是我上面有提到的保持可拓展性,眼光要放長遠(yuǎn),以后可能還會有人會用到你寫的API。
學(xué)會問問題
養(yǎng)成一個習(xí)慣,當(dāng)你要問人問題的時候,要知道每個人溝通能力不一樣的,當(dāng)你達(dá)到一種水平,覺得你能幾句話能把一個問題說的很清晰,你可以不寫,「如果你覺得你沒有那個水平,你要寫一下你的文字然后發(fā)給別人」,溝通協(xié)調(diào)能力也是在職場中需要鍛煉的??。
很多時候你不能靠問,你必須要帶方案,「如果你靠問別人給了你方案,那永遠(yuǎn)都是別人教你寫代碼」。
如果你自己帶了方案,別人覺得方案不錯,或者別人有更好的會提出來,當(dāng)然別人花30s提出來的方案肯定不是最佳的,這是你負(fù)責(zé)的模塊,你熟悉的邏輯,你想出來的方案肯定會更好,要在此抉擇。
多用快捷鍵
花時間去看快捷鍵,千萬不要在CodeReview或者技術(shù)分享會的時候找文件點(diǎn)來點(diǎn)去,在平時就要「養(yǎng)成追求"快"」 的習(xí)慣
一段時間干好一件事
這個點(diǎn)我以前一直都在提到,任何事情你都無法做到完美兼顧,「你要知道一段時間內(nèi)能把一件事情干好就已經(jīng)很不錯了」。
如果你現(xiàn)在想要換工作,那就安心復(fù)習(xí)準(zhǔn)備面試,如果你要學(xué)某個技術(shù),那就圍繞著它一直學(xué),你可以給自己定個時間,「一個月?兩個月?半年???」 沒有關(guān)系,只要你在這段時間內(nèi)用心去做了,時間會給你答案。
動手前提
在做公共業(yè)務(wù)和普通頁面當(dāng)你需要用到一個第三方庫的時候,中級和高級的有一個差別是 高級要「先大概把文檔過一遍」,這樣當(dāng)你「遇到問題了可以快速定位」,「而不是遇到問題了再去找,再去看源碼」。
這樣不會花費(fèi)很多很多時間,如果當(dāng)你看文檔的時候卡住了,你可以選擇嘗試看別人總結(jié)好解析好的的文章??,說不定就幫你解決了問題,要記住看文章永遠(yuǎn)是比看源碼快的。
快速定位問題
當(dāng)你遇到一個BUG的時候一定要思考,不能莽做,縷清前因后果,思考為什么會引發(fā)這樣的現(xiàn)象。
最合適的解決問題的路徑是:「看上下文->看issue->看文檔->看文章->看源碼」。
? 時間不知不覺 我們后知后覺
一生或許只是幾頁,不斷在修改和謄抄著的詩稿,從青絲到白發(fā),有人還在燈下。——席慕蓉
誰說不是呢?「時間如流水,一去不復(fù)返」,認(rèn)真過好每一天也是我們力所能及的事情了。
「在漫漫程序員歷史長河中,幾個月不過是浪花一朵」,學(xué)會時間管理對我們也極其重要。
我特別喜歡我老大的一句話:「"如果你是我招進(jìn)來的而在你出去后你沒有任何提升,我覺得我自己是失職的"」
在這「三個月」的時間里我「大多數(shù)的時間都花在了熟悉公司業(yè)務(wù)和代碼規(guī)范上面」,在開始我深知我對未嘗試的技術(shù)棧的不熟,對產(chǎn)品的不熟,再到后面逐漸熟練使用,我覺得對我自己成長真的不是一星半點(diǎn)??。
這里的小伙伴真的是把一個產(chǎn)品當(dāng)成自己的寶貝,細(xì)心呵護(hù)用規(guī)范的代碼澆灌成長,我在大學(xué)當(dāng)模特隊(duì)隊(duì)長的時候也一直在跟隊(duì)員強(qiáng)調(diào):我們能夠在一起 「不是因?yàn)槲?,不是因?yàn)槟悖皇且驗(yàn)樗?,而?我們"」 ,只有我們達(dá)成了這種共識,才會越走越長遠(yuǎn)??????。
除了平時自愿留在公司學(xué)習(xí),一周我會花一個晚上的時間回家整理CodeReview提到的點(diǎn),也會抽兩天早點(diǎn)回家看看書寫寫文,畢竟勞逸結(jié)合才是最好嘛。
我從來沒說過我技術(shù)有多好,甚至我覺得我的技術(shù)跟很多人比起來差遠(yuǎn)了,可能屏幕前的你能夠感同身受,「時間不停,我們當(dāng)然也不能停滯不前」。
很多人都說「面試造火箭工作擰螺絲」,但是實(shí)際上工作中確實(shí)會造火箭,就比如我們,做的都是很有意思的事情,一群人都會忘乎所以的去往一個方向去做去成長,「但是在造火箭??的途中難免會擰一下螺絲??」,這時候我們就需要知道用什么螺絲,框架的底層是什么,做了什么就很重要了。
以上我所總結(jié)的方法都是這三個月切切實(shí)實(shí)學(xué)到的,「無論是在書里還是在工作中,基本上每一個方法都對應(yīng)一個小故事」,這些我完完全全可以拆分成30篇文章來寫,但是還是毫無保留的寫出來了,如果大家對小故事感興趣的話以后我也可以分享出來??。
作者:快跑啊小盧
歡迎關(guān)注微信公眾號 :前端快快跑