您的位置:首頁 >  新聞中心 > 行業(yè)動態(tài)
  行業(yè)動態(tài)
 

如何處理前任程序員留下的代碼

來源:原創(chuàng)    時間:2017-10-30    瀏覽:0 次

作為軟件工程師不可防止會遇到的一個場景是:我們在改動或增加一個功用到不是我們創(chuàng)立的、我們不熟悉的、與我們擔(dān)任的體系部分無關(guān)的代碼中時,會遇到費事。盡管這可能會是一個繁瑣而艱巨的使命,可是由于運用其他開發(fā)人員編寫的代碼有很大的靈活性,所以我們能夠從中得到大大的長處,包括增加我們的影響規(guī)模,修正軟件腐朽以及學(xué)習(xí)我們曾經(jīng)不了解的體系部分(更何況,還能夠?qū)W習(xí)其他程序員的技能和技巧)。

考慮到運用其他開發(fā)人員編寫的代碼既有其厭煩之處,又有其優(yōu)勢地點,所以我們有必要當(dāng)心不要犯一些嚴(yán)峻的過錯:
我們的自我意識:我們可能會覺得自己知道得最多,但一般現(xiàn)實并非如此。我們要更改的是我們知之甚少的代碼——我們不知道原作者的目的、導(dǎo)致此代碼的決議計劃以及原作者在寫代碼時可用的東西和結(jié)構(gòu),等等。謙遜的質(zhì)量無價之寶,你值得具有。

原作者的自我意識:我們行將觸摸的代碼是由另一個開發(fā)人員所編寫的,另一種風(fēng)格、束縛、期限和個人日子(耗費他或她作業(yè)之外的時刻)。只需當(dāng)我們開端質(zhì)疑他或她做出的決議或質(zhì)疑代碼為什么這么不潔凈的時分,那人才會自我檢討,不至于自高自大。我們應(yīng)該盡悉數(shù)盡力讓原作者協(xié)助我們作業(yè),而不是阻礙我們。
對不知道的驚駭:許多時分,我們即將觸摸的代碼是我們知之甚少或徹底一竅不通的。令人懼怕的是:我們將對我們所做的任何改動擔(dān)任,可是我們基本上就像是在沒有光線的漆黑屋子里走動一樣。其實我們不需求憂慮,而是應(yīng)該構(gòu)建一種使我們能夠在大小紛歧的改動中感到舒適的結(jié)構(gòu),并答應(yīng)我們保證沒有損壞現(xiàn)有的功用。
由于開發(fā)人員,包括我們自己,是人,所以在處理其他開發(fā)人員編寫的代碼時,處理好許多人的天分問題是很有用的。在這篇文章中,我們將經(jīng)過我們能夠運用的五種技能來保證將對人道的了解成為我們的優(yōu)勢,從現(xiàn)有代碼和原作者羅致盡可能多的協(xié)助,并使得其他開發(fā)人員編寫的代碼終究變得比正本更優(yōu)異。盡管這兒列出的5個辦法并不全面,可是運用下面的技能將保證在完畢改動其他開發(fā)人員編寫的代碼時,我們有決心堅持現(xiàn)有功用的作業(yè)狀況,一同保證我們的新功用與現(xiàn)有的代碼庫協(xié)調(diào)一致。
work-with-someone-else-code

1.保證測驗的存在
要想保證在其他開發(fā)人員編寫的代碼中所存在的現(xiàn)有功用實踐能夠依照預(yù)期的辦法作業(yè),而且我們對其進(jìn)行的任何更改都不會影響到功用的完結(jié),僅有真實令人決心十足的辦法是用測驗來支撐代碼。當(dāng)我們遇到另一位開發(fā)人員編寫的代碼時,代碼有兩種所在的狀況:(1)沒有滿足的測驗水平,或(2)有滿足的測驗水平。遇到前一種狀況,我們得擔(dān)任創(chuàng)立測驗,而在后一種狀況下,我們能夠運用現(xiàn)有的測驗來保證我們做出的任何更改都不會損壞代碼,并盡可能多地從測驗去了解代碼的目的。
創(chuàng)立新測驗
這是一個哀痛的比如:我們在改動其他開發(fā)人員的代碼時,要對更改成果擔(dān)任,可是我們沒有辦法保證我們在進(jìn)行更改時不損壞任何東西。訴苦是沒有用的。不管我們發(fā)現(xiàn)代碼處在什么樣的條件下,我們總之是要觸摸代碼,因而如果代碼壞掉了,就是我們的責(zé)任。所以我們在改動代碼時,一定要掌控自己的行為。斷定不會損壞代碼的僅有辦法是自己寫測驗。
盡管這是庸俗的,但它答應(yīng)我們經(jīng)過編寫測驗來學(xué)習(xí),這是它的首要長處。假定代碼現(xiàn)在能夠正常作業(yè),而我們需求編寫測驗,以便預(yù)期的輸入會導(dǎo)致預(yù)期的輸出。在我們完結(jié)這個測驗的進(jìn)程中,我們逐步了解到代碼的目的和功用。例如,給出以下代碼

我們對代碼的目的以及為什么在代碼中運用Magic number知道得并不多,可是我們能夠創(chuàng)立一組測驗,已知輸入發(fā)生已知輸出。例如,經(jīng)過做一些簡略的數(shù)學(xué)和處理構(gòu)成成功的閾值薪水問題,我們發(fā)現(xiàn)如果一個人的年紀(jì)在30歲以下,且每年大約賺68,330美元,那么他被認(rèn)為是成功的(依照本規(guī)范的規(guī)范)。盡管我們不知道那些magic number是什么,可是我們知道它們的確削減了初始的薪水值。因而,68,330美元的閾值是扣除前的基本工資。經(jīng)過運用這些信息,我們能夠創(chuàng)立一些簡略的測驗,例如:

經(jīng)過這三個測驗,我們現(xiàn)在對現(xiàn)有代碼的作業(yè)辦法有了大致的了解:如果一個人不到30歲,且每年賺$ 68,300,那么他被認(rèn)為是成功人士。盡管我們能夠創(chuàng)立更多的測驗來保證臨界狀況(例如空白年紀(jì)或工資)功用正常,可是一些簡略的測驗不只使我們了解了原始功用,還給出了一套自動化測驗,可用于保證在對現(xiàn)有代碼進(jìn)行更改時,我們不會損壞現(xiàn)有功用。
運用現(xiàn)有測驗
如果有滿足的代碼測驗組件,那么我們能夠從測驗中學(xué)到許多東西。正如我們創(chuàng)立測驗一樣,經(jīng)過閱覽測驗,我們能夠了解代碼如安在功用層面上作業(yè)。此外,我們還能夠知道原作者是怎么讓代碼運轉(zhuǎn)的。即便測驗是由原作者以外的人(在我們觸摸之前)編撰的,也依然能夠為我們供給關(guān)于其他人對代碼的觀點。
盡管現(xiàn)有的測驗?zāi)軌蚬┙o協(xié)助,但我們依然需求對此持保存情緒。測驗是否與代碼的開發(fā)更改一同與時俱進(jìn)是很難說的。如果是的話,那么這是一個很好的了解根底;如果不是,那么我們要當(dāng)心不要被誤導(dǎo)。例如,如果初始的工資閾值是每年75,000美元,而后來更改為我們的68,330美元,那么下面這個過期的測驗可能會使我們誤入歧途:

這個測驗仍是會經(jīng)過的,但沒有了預(yù)期的效果。經(jīng)過的原因不是由于它正好是閾值,而是由于它超出了閾值。如果此測驗組件包括這樣一個測驗用例:當(dāng)薪水低于閾值1美元時,過濾器就回來false,這樣第二個測驗將會失利,標(biāo)明閾值是過錯的。如果套件沒有這樣的測驗,那么陳腐的數(shù)據(jù)會很簡略誤導(dǎo)我們弄錯代碼的真實目的。當(dāng)有疑問時,請信任代碼:正如我們之前所表述的那樣,求解閾值標(biāo)明測驗沒有對準(zhǔn)實踐閾值。
別的,要檢查代碼和測驗用例的存儲庫日志(即Git日志):如果代碼的終究更新日期比測驗的終究更新日期更近(對代碼進(jìn)行了嚴(yán)重更改,例如更改閾值),則測驗可能現(xiàn)已過期,應(yīng)慎重檢查。留意,我們不應(yīng)該徹底忽視測驗,由于它們或許依然能為我們供給關(guān)于原作者(或最近編撰測驗的開發(fā)人員)目的的一些文檔,但它們可能包括過期或不正確的數(shù)據(jù)。
2.與編寫代碼的人溝通
在觸及多個人的任何作業(yè)中,溝通至關(guān)重要。不管是企業(yè),越野游覽仍是軟件項目,缺少溝通是危害使命最有用的手法之一。即便我們在創(chuàng)立新代碼時進(jìn)行溝通,可是當(dāng)我們觸摸現(xiàn)有的代碼時,危險會增加。由于此刻我們對現(xiàn)有的代碼并不太了解,因而我們所了解的內(nèi)容可能是被誤導(dǎo)的,或只代表了其間的一小部分。為了真實了解現(xiàn)有的代碼,我們需求和編寫它的人溝通。
當(dāng)開端提出問題時,我們需求斷定問題是詳細(xì)的,而且旨在完結(jié)我們了解代碼的方針。例如:
這個代碼片段最適合放到體系的哪里?
你有什么規(guī)劃或圖表嗎?
我應(yīng)該留意什么圈套?
這個組件或類是做什么的?
有沒有什么你想放到代碼里,但其時沒有做的?為什么?
一直要堅持謙善的情緒,活躍尋求原作者真實的答案。簡直每個開發(fā)人員都碰到過這樣的場景,他或她看著他人的代碼,自問自答:“為什么他/她要這樣做?為什么他們不這樣做?”然后花幾個小時來得出正本只需原作者答復(fù)就能得到的定論。大多數(shù)開發(fā)人員都是有才調(diào)的程序員,所以即便如果我們遇到一個看似糟糕的決議,也有可能有一個很好的理由(可能沒有,但研討他人的代碼時最好假定他們這樣做是有原因的;如果真的沒有,我們能夠經(jīng)過重構(gòu)來改動)。
溝通在軟件開發(fā)中起非有必要副效果。1967年開端由Melvin Conway創(chuàng)立的康威規(guī)律規(guī)矩:
規(guī)劃體系的任何安排…都將不可防止地發(fā)生一種規(guī)劃,該規(guī)劃結(jié)構(gòu)反映了安排的通訊結(jié)構(gòu)。
這意味著,一個巨大、嚴(yán)密溝通的團(tuán)隊可能會生成一體化,嚴(yán)密耦合的代碼,但一些較小的團(tuán)隊可能會生成更獨立、松懈耦合的代碼(有關(guān)此相關(guān)性的更多信息,請參閱《Demystifying Conway’s Law》)。關(guān)于我們來說,這意味著我們的通訊結(jié)構(gòu)不只影響特定的代碼段,也影響整個代碼庫。因而,與原作者親近溝通肯定是一個好辦法,但我們應(yīng)該自檢不要太過于依賴于原作者。這不只可能會惹惱原作者,還可能在我們的代碼中發(fā)生無意識的耦合。
盡管這有助于我們深入研討代碼,但這是在假定能夠觸摸原作者的狀況下。在許多時分,原作者可能現(xiàn)已脫離了公司,或恰巧不在公司(例如正在度假)。在此種狀況下我們該做什么?問詢可能對代碼有所了解的人。這個人紛歧定要曾真實作業(yè)于代碼,他能夠是在原作者編寫代碼時就在周圍,也能夠是知道原作者。哪怕僅是從原開發(fā)者周圍的人中得到只言片語,也可能會啟迪其他不知道的代碼片段。
3.刪去一切正告
心思學(xué)中有一個眾所周知的概念,稱為“破窗理論”,Andrew Hunt和Dave Thomas在《 The Pragmatic Programmer 》(第4-6頁)中詳細(xì)描繪了這個概念。這個理論開端是由James Q.Wilson和George L. Kelling提出的,描繪如下:
假定有一個建筑物有幾扇破了的窗戶。如果窗戶沒有修好,那么損壞者會趨向于打破更多的窗戶。終究,他們乃至可能會破門而入,如果建筑物是沒人住的,那么他們可能會非法占有或許在里面焚燒。也能夠考慮人行道的狀況。如果道路上面有廢物堆積,那么不久之后,就會有更多的廢物累積。終究,人們乃至?xí)_端往那里扔外賣廢物,乃至打破轎車。
這個理論指出,如果好像現(xiàn)已沒人關(guān)懷這個物品或事物,那么我們就會忽視對物品或事物的照料,這是人的天分。例如,如果一棟建筑物看上去現(xiàn)已凌亂不堪,那么它更有可能被任意損壞。在軟件方面,這個理論意味著如果開發(fā)人員發(fā)現(xiàn)代碼現(xiàn)已是一團(tuán)糟,那么人的賦性會讓他弄壞代碼。從實質(zhì)上說,我們心里想的是(即便心思活動沒有這么豐厚),“已然終究一個人不在乎這代碼,我為什么要在乎?”或“都是亂糟糟的代碼,誰知道是誰寫的。”
可是,這不應(yīng)該成為我們的托言。只需我們觸摸曾經(jīng)歸于其他人的代碼,那么我們就要對這些代碼擔(dān)任,而且如果它不能有用作業(yè)的話,我們得背負(fù)結(jié)果。為了打敗這種人的天分行為,我們需求采納一些小辦法以防止我們的代碼更少地被弄臟(及時替換破掉的窗戶)。
一個簡略辦法是刪去來自我們正在運用的整個包或模塊中的一切正告。至于未運用或增加注釋的代碼,刪去它。如果我們稍后需求這部分代碼,那么在存儲庫中,我們總是能夠從從前的提交中檢索它。如果存在無法直接處理的正告(例如原始類型正告),那么運用@SuppressWarnings注解注釋該調(diào)用或辦法。這樣能夠保證我們對代碼進(jìn)行過細(xì)心的考慮:它們不是由于疏忽而宣布的正告,而是我們明確地留意到了正告(如原始類型)。
一旦我們刪去或明確地制止一切正告,那么我們就有必要保證代碼堅持革除正告。這有兩個首要效果:
迫使我們細(xì)心考慮我們創(chuàng)立的任何代碼。
削減代碼糜爛的改動,現(xiàn)在的正告會導(dǎo)致今后的過錯。
這對其他人,以及我們自己都有心思暗示效果——我們其實關(guān)懷我們正在處理的代碼。它不再是條單行線——我們強逼著自己更改代碼,提交,然后永不回頭。相反,我們知道到我們需求對這代碼擔(dān)任。這對之后的軟件開發(fā)也是有協(xié)助的——它向?qū)淼拈_發(fā)人員展現(xiàn),這不是一間窗戶都破了的庫房:而是一個保護(hù)杰出的代碼庫。
4.重構(gòu)
在曩昔幾十年中,重構(gòu)現(xiàn)已成為了一個十分重要的術(shù)語,而且最近被當(dāng)作是對當(dāng)時作業(yè)代碼做任何改動的代名詞。盡管重構(gòu)的確觸及對當(dāng)時正在作業(yè)的代碼的更改,但并非整個全局。Martin Fowler在他關(guān)于這個論題的重要著作——《Refactoring》一書中將重構(gòu)界說為:
對軟件的內(nèi)部結(jié)構(gòu)進(jìn)行更改,使其更簡略了解而且修正起來更廉價,而不改動其可調(diào)查的行為。
這個界說的關(guān)鍵在于它觸及的更改不會改動體系可調(diào)查的行為。這意味著當(dāng)我們重構(gòu)代碼時,我們有必要要有辦法來保證代碼的外部可見行為不會改動。在我們的比如中,這意味著是在我們承繼或自己開發(fā)的測驗套件中。為了保證我們沒有改動體系的外部行為,每逢我們進(jìn)行改動時,都有必要從頭編譯和履行我們的悉數(shù)測驗。
此外,并不是我們所做的每一個改動都被認(rèn)為是重構(gòu)。例如,重命名辦法以更好地反映其預(yù)期用處是重構(gòu),但增加新功用不是。為了看到重構(gòu)的長處,我們將重構(gòu)SuccessfulFilter。履行的第一個重構(gòu)是提取辦法,以更好地封裝個人凈工資的邏輯:

在我們進(jìn)行這種改動之后,我們從頭編譯并運轉(zhuǎn)我們的測驗套件,測驗套件將持續(xù)經(jīng)過?,F(xiàn)在更簡略看出,成功是經(jīng)過一個人的年紀(jì)和凈薪酬界說的,可是getNetSalary辦法好像并不像Person類一樣歸于SuccessfulFilter(指示標(biāo)志就是該辦法的僅有參數(shù)是Person,該辦法的僅有調(diào)用是Person類的辦法,因而對Person類有很強的親和力)。 為了更好地定位這個辦法,我們履行一個Move辦法將其移動到Person類:

為了進(jìn)一步整理此代碼,我們對每個magic number履行符號常量替換magic number行為。為了知道這些值的意義,我們可能得和原作者溝通,或許向具有滿足范疇常識的人討教,以引領(lǐng)正確的方向。我們還將履行更多的提取辦法重構(gòu),以保證現(xiàn)有的辦法盡可能簡略。


從頭編譯和測驗,發(fā)現(xiàn)體系依然依照預(yù)期的辦法作業(yè):我們沒有改動外部行為,可是我們改進(jìn)了代碼的可靠性和內(nèi)部結(jié)構(gòu)。有關(guān)更雜亂的重構(gòu)和重構(gòu)進(jìn)程,請參閱Martin Fowler的Refactoring Guru網(wǎng)站。
5.當(dāng)你脫離的時分,代碼比你發(fā)現(xiàn)它的時分更好
終究這個技能在概念上十分簡略,但在實踐中很困難:讓代碼比你發(fā)現(xiàn)它的時分更好。當(dāng)我們整理代碼,特別是他人的代碼時,我們大多會增加功用,測驗它,然后前行,不關(guān)懷我們會不會奉獻(xiàn)軟件腐朽,也不在乎我們增加到類的新辦法會不會導(dǎo)致額定的紊亂。因而,本文的悉數(shù)內(nèi)容可總結(jié)為以下規(guī)矩:
每逢我們修正代碼時,請保證當(dāng)你脫離的時分,代碼比你發(fā)現(xiàn)它的時分更好。
前面提到過,我們需求對類形成的損壞和對改動的代碼擔(dān)任,如果它不能作業(yè),那么修正是我們的責(zé)任。為了打敗隨同軟件出產(chǎn)而呈現(xiàn)的熵,我們有必要強制自己做到脫離時的代碼比我們發(fā)現(xiàn)它的時分更佳。為了不躲避這個問題,我們有必要歸還技能債款,保證下一個觸摸代碼的人不需求再付出代價。說不定,將來可能是我們自己感謝自己這個時分的堅持呢。作為軟件工程師不可防止會遇到的一個場景是:我們在改動或增加一個功用到不是我們創(chuàng)立的、我們不熟悉的、與我們擔(dān)任的體系部分無關(guān)的代碼中時,會遇到費事。盡管這可能會是一個繁瑣而艱巨的使命,可是由于運用其他開發(fā)人員編寫的代碼有很大的靈活性,所以我們能夠從中得到大大的長處,包括增加我們的影響規(guī)模,修正軟件腐朽以及學(xué)習(xí)我們曾經(jīng)不了解的體系部分(更何況,還能夠?qū)W習(xí)其他程序員的技能和技巧)。
考慮到運用其他開發(fā)人員編寫的代碼既有其厭煩之處,又有其優(yōu)勢地點,所以我們有必要當(dāng)心不要犯一些嚴(yán)峻的過錯:
我們的自我意識:我們可能會覺得自己知道得最多,但一般現(xiàn)實并非如此。我們要更改的是我們知之甚少的代碼——我們不知道原作者的目的、導(dǎo)致此代碼的決議計劃以及原作者在寫代碼時可用的東西和結(jié)構(gòu),等等。謙遜的質(zhì)量無價之寶,你值得具有。
原作者的自我意識:我們行將觸摸的代碼是由另一個開發(fā)人員所編寫的,另一種風(fēng)格、束縛、期限和個人日子(耗費他或她作業(yè)之外的時刻)。只需當(dāng)我們開端質(zhì)疑他或她做出的決議或質(zhì)疑代碼為什么這么不潔凈的時分,那人才會自我檢討,不至于自高自大。我們應(yīng)該盡悉數(shù)盡力讓原作者協(xié)助我們作業(yè),而不是阻礙我們。
對不知道的驚駭:許多時分,我們即將觸摸的代碼是我們知之甚少或徹底一竅不通的。令人懼怕的是:我們將對我們所做的任何改動擔(dān)任,可是我們基本上就像是在沒有光線的漆黑屋子里走動一樣。其實我們不需求憂慮,而是應(yīng)該構(gòu)建一種使我們能夠在大小紛歧的改動中感到舒適的結(jié)構(gòu),并答應(yīng)我們保證沒有損壞現(xiàn)有的功用。
由于開發(fā)人員,包括我們自己,是人,所以在處理其他開發(fā)人員編寫的代碼時,處理好許多人的天分問題是很有用的。在這篇文章中,我們將經(jīng)過我們能夠運用的五種技能來保證將對人道的了解成為我們的優(yōu)勢,從現(xiàn)有代碼和原作者羅致盡可能多的協(xié)助,并使得其他開發(fā)人員編寫的代碼終究變得比正本更優(yōu)異。盡管這兒列出的5個辦法并不全面,可是運用下面的技能將保證在完畢改動其他開發(fā)人員編寫的代碼時,我們有決心堅持現(xiàn)有功用的作業(yè)狀況,一同保證我們的新功用與現(xiàn)有的代碼庫協(xié)調(diào)一致。
work-with-someone-else-code
1.保證測驗的存在
要想保證在其他開發(fā)人員編寫的代碼中所存在的現(xiàn)有功用實踐能夠依照預(yù)期的辦法作業(yè),而且我們對其進(jìn)行的任何更改都不會影響到功用的完結(jié),僅有真實令人決心十足的辦法是用測驗來支撐代碼。當(dāng)我們遇到另一位開發(fā)人員編寫的代碼時,代碼有兩種所在的狀況:(1)沒有滿足的測驗水平,或(2)有滿足的測驗水平。遇到前一種狀況,我們得擔(dān)任創(chuàng)立測驗,而在后一種狀況下,我們能夠運用現(xiàn)有的測驗來保證我們做出的任何更改都不會損壞代碼,并盡可能多地從測驗去了解代碼的目的。
創(chuàng)立新測驗
這是一個哀痛的比如:我們在改動其他開發(fā)人員的代碼時,要對更改成果擔(dān)任,可是我們沒有辦法保證我們在進(jìn)行更改時不損壞任何東西。訴苦是沒有用的。不管我們發(fā)現(xiàn)代碼處在什么樣的條件下,我們總之是要觸摸代碼,因而如果代碼壞掉了,就是我們的責(zé)任。所以我們在改動代碼時,一定要掌控自己的行為。斷定不會損壞代碼的僅有辦法是自己寫測驗。
盡管這是庸俗的,但它答應(yīng)我們經(jīng)過編寫測驗來學(xué)習(xí),這是它的首要長處。假定代碼現(xiàn)在能夠正常作業(yè),而我們需求編寫測驗,以便預(yù)期的輸入會導(dǎo)致預(yù)期的輸出。在我們完結(jié)這個測驗的進(jìn)程中,我們逐步了解到代碼的目的和功用。例如,給出以下代碼

我們對代碼的目的以及為什么在代碼中運用Magic number知道得并不多,可是我們能夠創(chuàng)立一組測驗,已知輸入發(fā)生已知輸出。例如,經(jīng)過做一些簡略的數(shù)學(xué)和處理構(gòu)成成功的閾值薪水問題,我們發(fā)現(xiàn)如果一個人的年紀(jì)在30歲以下,且每年大約賺68,330美元,那么他被認(rèn)為是成功的(依照本規(guī)范的規(guī)范)。盡管我們不知道那些magic number是什么,可是我們知道它們的確削減了初始的薪水值。因而,68,330美元的閾值是扣除前的基本工資。經(jīng)過運用這些信息,我們能夠創(chuàng)立一些簡略的測驗,例如:

經(jīng)過這三個測驗,我們現(xiàn)在對現(xiàn)有代碼的作業(yè)辦法有了大致的了解:如果一個人不到30歲,且每年賺$ 68,300,那么他被認(rèn)為是成功人士。盡管我們能夠創(chuàng)立更多的測驗來保證臨界狀況(例如空白年紀(jì)或工資)功用正常,可是一些簡略的測驗不只使我們了解了原始功用,還給出了一套自動化測驗,可用于保證在對現(xiàn)有代碼進(jìn)行更改時,我們不會損壞現(xiàn)有功用。
運用現(xiàn)有測驗
如果有滿足的代碼測驗組件,那么我們能夠從測驗中學(xué)到許多東西。正如我們創(chuàng)立測驗一樣,經(jīng)過閱覽測驗,我們能夠了解代碼如安在功用層面上作業(yè)。此外,我們還能夠知道原作者是怎么讓代碼運轉(zhuǎn)的。即便測驗是由原作者以外的人(在我們觸摸之前)編撰的,也依然能夠為我們供給關(guān)于其他人對代碼的觀點。
盡管現(xiàn)有的測驗?zāi)軌蚬┙o協(xié)助,但我們依然需求對此持保存情緒。測驗是否與代碼的開發(fā)更改一同與時俱進(jìn)是很難說的。如果是的話,那么這是一個很好的了解根底;如果不是,那么我們要當(dāng)心不要被誤導(dǎo)。例如,如果初始的工資閾值是每年75,000美元,而后來更改為我們的68,330美元,那么下面這個過期的測驗可能會使我們誤入歧途:

這個測驗仍是會經(jīng)過的,但沒有了預(yù)期的效果。經(jīng)過的原因不是由于它正好是閾值,而是由于它超出了閾值。如果此測驗組件包括這樣一個測驗用例:當(dāng)薪水低于閾值1美元時,過濾器就回來false,這樣第二個測驗將會失利,標(biāo)明閾值是過錯的。如果套件沒有這樣的測驗,那么陳腐的數(shù)據(jù)會很簡略誤導(dǎo)我們弄錯代碼的真實目的。當(dāng)有疑問時,請信任代碼:正如我們之前所表述的那樣,求解閾值標(biāo)明測驗沒有對準(zhǔn)實踐閾值。
別的,要檢查代碼和測驗用例的存儲庫日志(即Git日志):如果代碼的終究更新日期比測驗的終究更新日期更近(對代碼進(jìn)行了嚴(yán)重更改,例如更改閾值),則測驗可能現(xiàn)已過期,應(yīng)慎重檢查。留意,我們不應(yīng)該徹底忽視測驗,由于它們或許依然能為我們供給關(guān)于原作者(或最近編撰測驗的開發(fā)人員)目的的一些文檔,但它們可能包括過期或不正確的數(shù)據(jù)。
2.與編寫代碼的人溝通
在觸及多個人的任何作業(yè)中,溝通至關(guān)重要。不管是企業(yè),越野游覽仍是軟件項目,缺少溝通是危害使命最有用的手法之一。即便我們在創(chuàng)立新代碼時進(jìn)行溝通,可是當(dāng)我們觸摸現(xiàn)有的代碼時,危險會增加。由于此刻我們對現(xiàn)有的代碼并不太了解,因而我們所了解的內(nèi)容可能是被誤導(dǎo)的,或只代表了其間的一小部分。為了真實了解現(xiàn)有的代碼,我們需求和編寫它的人溝通。
當(dāng)開端提出問題時,我們需求斷定問題是詳細(xì)的,而且旨在完結(jié)我們了解代碼的方針。例如:
這個代碼片段最適合放到體系的哪里?
你有什么規(guī)劃或圖表嗎?
我應(yīng)該留意什么圈套?
這個組件或類是做什么的?
有沒有什么你想放到代碼里,但其時沒有做的?為什么?
一直要堅持謙善的情緒,活躍尋求原作者真實的答案。簡直每個開發(fā)人員都碰到過這樣的場景,他或她看著他人的代碼,自問自答:“為什么他/她要這樣做?為什么他們不這樣做?”然后花幾個小時來得出正本只需原作者答復(fù)就能得到的定論。大多數(shù)開發(fā)人員都是有才調(diào)的程序員,所以即便如果我們遇到一個看似糟糕的決議,也有可能有一個很好的理由(可能沒有,但研討他人的代碼時最好假定他們這樣做是有原因的;如果真的沒有,我們能夠經(jīng)過重構(gòu)來改動)。
溝通在軟件開發(fā)中起非有必要副效果。1967年開端由Melvin Conway創(chuàng)立的康威規(guī)律規(guī)矩:
規(guī)劃體系的任何安排…都將不可防止地發(fā)生一種規(guī)劃,該規(guī)劃結(jié)構(gòu)反映了安排的通訊結(jié)構(gòu)。
這意味著,一個巨大、嚴(yán)密溝通的團(tuán)隊可能會生成一體化,嚴(yán)密耦合的代碼,但一些較小的團(tuán)隊可能會生成更獨立、松懈耦合的代碼(有關(guān)此相關(guān)性的更多信息,請參閱《Demystifying Conway’s Law》)。關(guān)于我們來說,這意味著我們的通訊結(jié)構(gòu)不只影響特定的代碼段,也影響整個代碼庫。因而,與原作者親近溝通肯定是一個好辦法,但我們應(yīng)該自檢不要太過于依賴于原作者。這不只可能會惹惱原作者,還可能在我們的代碼中發(fā)生無意識的耦合。
盡管這有助于我們深入研討代碼,但這是在假定能夠觸摸原作者的狀況下。在許多時分,原作者可能現(xiàn)已脫離了公司,或恰巧不在公司(例如正在度假)。在此種狀況下我們該做什么?問詢可能對代碼有所了解的人。這個人紛歧定要曾真實作業(yè)于代碼,他能夠是在原作者編寫代碼時就在周圍,也能夠是知道原作者。哪怕僅是從原開發(fā)者周圍的人中得到只言片語,也可能會啟迪其他不知道的代碼片段。
3.刪去一切正告
心思學(xué)中有一個眾所周知的概念,稱為“破窗理論”,Andrew Hunt和Dave Thomas在《 The Pragmatic Programmer 》(第4-6頁)中詳細(xì)描繪了這個概念。這個理論開端是由James Q.Wilson和George L. Kelling提出的,描繪如下:
假定有一個建筑物有幾扇破了的窗戶。如果窗戶沒有修好,那么損壞者會趨向于打破更多的窗戶。終究,他們乃至可能會破門而入,如果建筑物是沒人住的,那么他們可能會非法占有或許在里面焚燒。也能夠考慮人行道的狀況。如果道路上面有廢物堆積,那么不久之后,就會有更多的廢物累積。終究,人們乃至?xí)_端往那里扔外賣廢物,乃至打破轎車。
這個理論指出,如果好像現(xiàn)已沒人關(guān)懷這個物品或事物,那么我們就會忽視對物品或事物的照料,這是人的天分。例如,如果一棟建筑物看上去現(xiàn)已凌亂不堪,那么它更有可能被任意損壞。在軟件方面,這個理論意味著如果開發(fā)人員發(fā)現(xiàn)代碼現(xiàn)已是一團(tuán)糟,那么人的賦性會讓他弄壞代碼。從實質(zhì)上說,我們心里想的是(即便心思活動沒有這么豐厚),“已然終究一個人不在乎這代碼,我為什么要在乎?”或“都是亂糟糟的代碼,誰知道是誰寫的。”
可是,這不應(yīng)該成為我們的托言。只需我們觸摸曾經(jīng)歸于其他人的代碼,那么我們就要對這些代碼擔(dān)任,而且如果它不能有用作業(yè)的話,我們得背負(fù)結(jié)果。為了打敗這種人的天分行為,我們需求采納一些小辦法以防止我們的代碼更少地被弄臟(及時替換破掉的窗戶)。
一個簡略辦法是刪去來自我們正在運用的整個包或模塊中的一切正告。至于未運用或增加注釋的代碼,刪去它。如果我們稍后需求這部分代碼,那么在存儲庫中,我們總是能夠從從前的提交中檢索它。如果存在無法直接處理的正告(例如原始類型正告),那么運用@SuppressWarnings注解注釋該調(diào)用或辦法。這樣能夠保證我們對代碼進(jìn)行過細(xì)心的考慮:它們不是由于疏忽而宣布的正告,而是我們明確地留意到了正告(如原始類型)。
一旦我們刪去或明確地制止一切正告,那么我們就有必要保證代碼堅持革除正告。這有兩個首要效果:
迫使我們細(xì)心考慮我們創(chuàng)立的任何代碼。
削減代碼糜爛的改動,現(xiàn)在的正告會導(dǎo)致今后的過錯。
這對其他人,以及我們自己都有心思暗示效果——我們其實關(guān)懷我們正在處理的代碼。它不再是條單行線——我們強逼著自己更改代碼,提交,然后永不回頭。相反,我們知道到我們需求對這代碼擔(dān)任。這對之后的軟件開發(fā)也是有協(xié)助的——它向?qū)淼拈_發(fā)人員展現(xiàn),這不是一間窗戶都破了的庫房:而是一個保護(hù)杰出的代碼庫。
4.重構(gòu)
在曩昔幾十年中,重構(gòu)現(xiàn)已成為了一個十分重要的術(shù)語,而且最近被當(dāng)作是對當(dāng)時作業(yè)代碼做任何改動的代名詞。盡管重構(gòu)的確觸及對當(dāng)時正在作業(yè)的代碼的更改,但并非整個全局。Martin Fowler在他關(guān)于這個論題的重要著作——《Refactoring》一書中將重構(gòu)界說為:
對軟件的內(nèi)部結(jié)構(gòu)進(jìn)行更改,使其更簡略了解而且修正起來更廉價,而不改動其可調(diào)查的行為。
這個界說的關(guān)鍵在于它觸及的更改不會改動體系可調(diào)查的行為。這意味著當(dāng)我們重構(gòu)代碼時,我們有必要要有辦法來保證代碼的外部可見行為不會改動。在我們的比如中,這意味著是在我們承繼或自己開發(fā)的測驗套件中。為了保證我們沒有改動體系的外部行為,每逢我們進(jìn)行改動時,都有必要從頭編譯和履行我們的悉數(shù)測驗。
此外,并不是我們所做的每一個改動都被認(rèn)為是重構(gòu)。例如,重命名辦法以更好地反映其預(yù)期用處是重構(gòu),但增加新功用不是。為了看到重構(gòu)的長處,我們將重構(gòu)SuccessfulFilter。履行的第一個重構(gòu)是提取辦法,以更好地封裝個人凈工資的邏輯:

在我們進(jìn)行這種改動之后,我們從頭編譯并運轉(zhuǎn)我們的測驗套件,測驗套件將持續(xù)經(jīng)過?,F(xiàn)在更簡略看出,成功是經(jīng)過一個人的年紀(jì)和凈薪酬界說的,可是getNetSalary辦法好像并不像Person類一樣歸于SuccessfulFilter(指示標(biāo)志就是該辦法的僅有參數(shù)是Person,該辦法的僅有調(diào)用是Person類的辦法,因而對Person類有很強的親和力)。 為了更好地定位這個辦法,我們履行一個Move辦法將其移動到Person類:

為了進(jìn)一步整理此代碼,我們對每個magic number履行符號常量替換magic number行為。為了知道這些值的意義,我們可能得和原作者溝通,或許向具有滿足范疇常識的人討教,以引領(lǐng)正確的方向。我們還將履行更多的提取辦法重構(gòu),以保證現(xiàn)有的辦法盡可能簡略。


從頭編譯和測驗,發(fā)現(xiàn)體系依然依照預(yù)期的辦法作業(yè):我們沒有改動外部行為,可是我們改進(jìn)了代碼的可靠性和內(nèi)部結(jié)構(gòu)。有關(guān)更雜亂的重構(gòu)和重構(gòu)進(jìn)程,請參閱Martin Fowler的Refactoring Guru網(wǎng)站。
5.當(dāng)你脫離的時分,代碼比你發(fā)現(xiàn)它的時分更好
終究這個技能在概念上十分簡略,但在實踐中很困難:讓代碼比你發(fā)現(xiàn)它的時分更好。當(dāng)我們整理代碼,特別是他人的代碼時,我們大多會增加功用,測驗它,然后前行,不關(guān)懷我們會不會奉獻(xiàn)軟件腐朽,也不在乎我們增加到類的新辦法會不會導(dǎo)致額定的紊亂。因而,本文的悉數(shù)內(nèi)容可總結(jié)為以下規(guī)矩:
每逢我們修正代碼時,請保證當(dāng)你脫離的時分,代碼比你發(fā)現(xiàn)它的時分更好。
前面提到過,我們需求對類形成的損壞和對改動的代碼擔(dān)任,如果它不能作業(yè),那么修正是我們的責(zé)任。為了打敗隨同軟件出產(chǎn)而呈現(xiàn)的熵,我們有必要強制自己做到脫離時的代碼比我們發(fā)現(xiàn)它的時分更佳。為了不躲避這個問題,我們有必要歸還技能債款,保證下一個觸摸代碼的人不需求再付出代價。說不定,將來可能是我們自己感謝自己這個時分的堅持呢。


免费视频观无码一区,国内精品一区二区无码,99精品无码视频在线播放,ā片国产在线播放