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

作為軟件工程師不可避免會(huì)遇到的一個(gè)場景是:我們?cè)诟淖兓蛱砑右粋€(gè)功能到不是我們創(chuàng)建的、我們不熟悉的、與我們負(fù)責(zé)的系統(tǒng)部分無關(guān)的代碼中時(shí),會(huì)遇到麻煩蕴侣。雖然這可能會(huì)是一個(gè)繁瑣而艱巨的任務(wù),但是由于使用其他開發(fā)人員編寫的代碼有很大的靈活性臭觉,所以我們可以從中得到大大的好處昆雀,包括增加我們的影響范圍辱志,修復(fù)軟件腐爛以及學(xué)習(xí)我們以前不了解的系統(tǒng)部分(更何況,還可以學(xué)習(xí)其他程序員的技術(shù)和技巧)狞膘。

考慮到使用其他開發(fā)人員編寫的代碼既有其厭煩之處揩懒,又有其優(yōu)勢(shì)所在,所以我們必須小心不要犯一些嚴(yán)重的錯(cuò)誤:

我們的自我意識(shí):我們可能會(huì)覺得自己知道得最多挽封,但通常事實(shí)并非如此已球。我們要更改的是我們知之甚少的代碼——我們不知道原作者的意圖、導(dǎo)致此代碼的決策以及原作者在寫代碼時(shí)可用的工具和框架场仲,等等和悦。謙遜的品質(zhì)價(jià)值千金,你值得擁有渠缕。

原作者的自我意識(shí):我們即將接觸的代碼是由另一個(gè)開發(fā)人員所編寫的,另一種風(fēng)格褒繁、約束亦鳞、期限和個(gè)人生活(消耗他或她工作之外的時(shí)間)。只有當(dāng)我們開始質(zhì)疑他或她做出的決定或質(zhì)疑代碼為什么這么不干凈的時(shí)候棒坏,那人才會(huì)自我反省燕差,不至于夜郎自大。我們應(yīng)該盡一切努力讓原作者幫助我們工作坝冕,而不是妨礙我們徒探。

對(duì)未知的恐懼:很多時(shí)候,我們將要接觸的代碼是我們知之甚少或完全一無所知的喂窟。令人害怕的是:我們將對(duì)我們所做的任何改變負(fù)責(zé)测暗,但是我們基本上就像是在沒有光線的黑暗屋子里走動(dòng)一樣。其實(shí)我們不需要擔(dān)心磨澡,而是應(yīng)該構(gòu)建一種使我們能夠在大小不一的改變中感到舒適的結(jié)構(gòu)碗啄,并允許我們確保沒有破壞現(xiàn)有的功能。

由于開發(fā)人員稳摄,包括我們自己稚字,是人,所以在處理其他開發(fā)人員編寫的代碼時(shí)厦酬,處理好很多人的天性問題是很有用的胆描。在這篇文章中,我們將通過我們可以使用的五種技術(shù)來確保將對(duì)人性的理解成為我們的優(yōu)勢(shì)仗阅,從現(xiàn)有代碼和原作者汲取盡可能多的幫助昌讲,并使得其他開發(fā)人員編寫的代碼最后變得比原來更優(yōu)秀。雖然這里列出的5個(gè)方法并不全面霹菊,但是使用下面的技術(shù)將確保在結(jié)束改動(dòng)其他開發(fā)人員編寫的代碼時(shí)剧蚣,我們有信心保持現(xiàn)有功能的工作狀態(tài)支竹,同時(shí)確保我們的新功能與現(xiàn)有的代碼庫協(xié)調(diào)一致。

1.確保測(cè)試的存在

要想確保在其他開發(fā)人員編寫的代碼中所存在的現(xiàn)有功能實(shí)際能夠按照預(yù)期的方式工作鸠按,并且我們對(duì)其進(jìn)行的任何更改都不會(huì)影響到功能的實(shí)現(xiàn)礼搁,唯一真正令人信心十足的方式是用測(cè)試來支持代碼。當(dāng)我們遇到另一位開發(fā)人員編寫的代碼時(shí)目尖,代碼有兩種所處的狀態(tài):(1)沒有足夠的測(cè)試水平馒吴,或(2)有足夠的測(cè)試水平。遇到前一種情況瑟曲,我們得負(fù)責(zé)創(chuàng)建測(cè)試饮戳,而在后一種情況下,我們可以使用現(xiàn)有的測(cè)試來確保我們做出的任何更改都不會(huì)破壞代碼洞拨,并盡可能多地從測(cè)試去了解代碼的意圖扯罐。

創(chuàng)建新測(cè)試

這是一個(gè)悲傷的例子:我們?cè)诟淖兤渌_發(fā)人員的代碼時(shí),要對(duì)更改結(jié)果負(fù)責(zé)烦衣,但是我們沒有辦法保證我們?cè)谶M(jìn)行更改時(shí)不破壞任何東西歹河。抱怨是沒有用的。無論我們發(fā)現(xiàn)代碼處在什么樣的條件下花吟,我們總歸是要接觸代碼秸歧,因此如果代碼壞掉了,就是我們的責(zé)任衅澈。所以我們?cè)诟淖兇a時(shí)键菱,一定要掌控自己的行為。確定不會(huì)破壞代碼的唯一方法是自己寫測(cè)試今布。

雖然這是乏味的经备,但它允許我們通過編寫測(cè)試來學(xué)習(xí),這是它的主要優(yōu)點(diǎn)险耀。假設(shè)代碼現(xiàn)在可以正常工作弄喘,而我們需要編寫測(cè)試,以便預(yù)期的輸入會(huì)導(dǎo)致預(yù)期的輸出甩牺。在我們完成這個(gè)測(cè)試的過程中蘑志,我們逐漸了解到代碼的意圖和功能。例如贬派,給出以下代碼

publicclass Person {privateintage;privatedoublesalary;public Person(int age, double salary) {this.age = age;this.salary = salary;}public void setAge(int age) {this.age = age;}public int getAge() {returnage;}public void setSalary(double salary) {this.salary = salary;}public double getSalary() {returnsalary;}}publicclass SuccessfulFilter implements Predicate<Person> {@Overridepublic boolean test(Person person) {returnperson.getAge() <30&&((((person.getSalary()-(250*12))-1500) *0.94) >60000);}}

我們對(duì)代碼的意圖以及為什么在代碼中使用Magic number知道得并不多急但,但是我們可以創(chuàng)建一組測(cè)試,已知輸入產(chǎn)生已知輸出搞乏。例如波桩,通過做一些簡單的數(shù)學(xué)和解決構(gòu)成成功的閾值薪水問題,我們發(fā)現(xiàn)如果一個(gè)人的年齡在30歲以下请敦,且每年大概賺68,330美元镐躲,那么他被認(rèn)為是成功的(按照本規(guī)范的標(biāo)準(zhǔn))储玫。雖然我們不知道那些magic number是什么,但是我們知道它們確實(shí)減少了初始的薪水值萤皂。因此撒穷,68,330美元的閾值是扣除前的基本工資。通過使用這些信息裆熙,我們可以創(chuàng)建一些簡單的測(cè)試端礼,例如:

publicclass SuccessfulFilterTest {privatestaticfinaldoubleTHRESHOLD_NET_SALARY =68330.0;@Testpublic void under30AndNettingThresholdEnsureSuccessful() {Person person =newPerson(29, THRESHOLD_NET_SALARY);Assert.assertTrue(newSuccessfulFilter().test(person));}@Testpublic void exactly30AndNettingThresholdEnsureUnsuccessful() {Person person =newPerson(30, THRESHOLD_NET_SALARY);Assert.assertFalse(newSuccessfulFilter().test(person));}@Testpublic void under30AndNettingLessThanThresholdEnsureSuccessful() {Person person =newPerson(29, THRESHOLD_NET_SALARY -1);Assert.assertFalse(newSuccessfulFilter().test(person));}}

通過這三個(gè)測(cè)試,我們現(xiàn)在對(duì)現(xiàn)有代碼的工作方式有了大致的了解:如果一個(gè)人不到30歲入录,且每年賺$ 68,300蛤奥,那么他被認(rèn)為是成功人士。雖然我們可以創(chuàng)建更多的測(cè)試來確保臨界情況(例如空白年齡或工資)功能正常僚稿,但是一些簡短的測(cè)試不僅使我們了解了原始功能凡桥,還給出了一套自動(dòng)化測(cè)試,可用于確保在對(duì)現(xiàn)有代碼進(jìn)行更改時(shí)蚀同,我們不會(huì)破壞現(xiàn)有功能唬血。

使用現(xiàn)有測(cè)試

如果有足夠的代碼測(cè)試組件,那么我們可以從測(cè)試中學(xué)到很多東西唤崭。正如我們創(chuàng)建測(cè)試一樣,通過閱讀測(cè)試脖律,我們可以了解代碼如何在功能層面上工作谢肾。此外,我們還可以知道原作者是如何讓代碼運(yùn)行的小泉。即使測(cè)試是由原作者以外的人(在我們接觸之前)撰寫的,也依然能夠?yàn)槲覀兲峁╆P(guān)于其他人對(duì)代碼的看法。

雖然現(xiàn)有的測(cè)試可以提供幫助为流,但我們?nèi)匀恍枰獙?duì)此持保留態(tài)度烫映。測(cè)試是否與代碼的開發(fā)更改一起與時(shí)俱進(jìn)是很難說的。如果是的話兢交,那么這是一個(gè)很好的理解基礎(chǔ)薪捍;如果不是,那么我們要小心不要被誤導(dǎo)配喳。例如酪穿,如果初始的工資閾值是每年75,000美元,而后來更改為我們的68,330美元晴裹,那么下面這個(gè)過時(shí)的測(cè)試可能會(huì)使我們誤入歧途:

@Testpublicvoid under30AndNettingThresholdEnsureSuccessful() {Person person =newPerson(29,75000.0);Assert.assertTrue(newSuccessfulFilter().test(person));}

這個(gè)測(cè)試還是會(huì)通過的被济,但沒有了預(yù)期的作用。通過的原因不是因?yàn)樗檬情撝到牛且驗(yàn)樗隽碎撝抵涣住H绻藴y(cè)試組件包含這樣一個(gè)測(cè)試用例:當(dāng)薪水低于閾值1美元時(shí)经磅,過濾器就返回false,這樣第二個(gè)測(cè)試將會(huì)失敗钮追,表明閾值是錯(cuò)誤的预厌。如果套件沒有這樣的測(cè)試,那么陳舊的數(shù)據(jù)會(huì)很容易誤導(dǎo)我們弄錯(cuò)代碼的真正意圖畏陕。當(dāng)有疑問時(shí)配乓,請(qǐng)相信代碼:正如我們之前所表述的那樣,求解閾值表明測(cè)試沒有對(duì)準(zhǔn)實(shí)際閾值惠毁。

另外犹芹,要查看代碼和測(cè)試用例的存儲(chǔ)庫日志(即Git日志):如果代碼的最后更新日期比測(cè)試的最后更新日期更近(對(duì)代碼進(jìn)行了重大更改,例如更改閾值)鞠绰,則測(cè)試可能已經(jīng)過時(shí)腰埂,應(yīng)謹(jǐn)慎查看。注意蜈膨,我們不應(yīng)該完全忽視測(cè)試屿笼,因?yàn)樗鼈円苍S仍然能為我們提供關(guān)于原作者(或最近撰寫測(cè)試的開發(fā)人員)意圖的一些文檔,但它們可能包含過時(shí)或不正確的數(shù)據(jù)翁巍。

2.與編寫代碼的人交流

在涉及多個(gè)人的任何工作中驴一,溝通至關(guān)重要。無論是企業(yè)灶壶,越野旅行還是軟件項(xiàng)目肝断,缺乏溝通是損害任務(wù)最有效的手段之一。即使我們?cè)趧?chuàng)建新代碼時(shí)進(jìn)行溝通驰凛,但是當(dāng)我們接觸現(xiàn)有的代碼時(shí)胸懈,風(fēng)險(xiǎn)會(huì)增加。因?yàn)榇藭r(shí)我們對(duì)現(xiàn)有的代碼并不太了解恰响,因此我們所了解的內(nèi)容可能是被誤導(dǎo)的趣钱,或只代表了其中的一小部分。為了真正了解現(xiàn)有的代碼胚宦,我們需要和編寫它的人交流首有。

當(dāng)開始提出問題時(shí),我們需要確定問題是具體的间唉,并且旨在實(shí)現(xiàn)我們理解代碼的目標(biāo)绞灼。例如:

這個(gè)代碼片段最適合放到系統(tǒng)的哪里?

你有什么設(shè)計(jì)或圖表嗎呈野?

我應(yīng)該注意什么陷阱低矮?

這個(gè)組件或類是做什么的?

有沒有什么你想放到代碼里被冒,但當(dāng)時(shí)沒有做的军掂?為什么轮蜕?

始終要保持謙虛的態(tài)度,積極尋求原作者真正的答案蝗锥。幾乎每個(gè)開發(fā)人員都碰到過這樣的場景跃洛,他或她看著別人的代碼,自問自答:“為什么他/她要這樣做终议?為什么他們不這樣做汇竭?”然后花幾個(gè)小時(shí)來得出本來只要原作者回答就能得到的結(jié)論。大多數(shù)開發(fā)人員都是有才華的程序員穴张,所以即使如果我們遇到一個(gè)看似糟糕的決定细燎,也有可能有一個(gè)很好的理由(可能沒有,但研究別人的代碼時(shí)最好假設(shè)他們這樣做是有原因的皂甘;如果真的沒有玻驻,我們可以通過重構(gòu)來改變)。

溝通在軟件開發(fā)中起次要副作用偿枕。1967年最初由Melvin Conway創(chuàng)立的康威定律規(guī)定:

設(shè)計(jì)系統(tǒng)的任何組織…都將不可避免地產(chǎn)生一種設(shè)計(jì)璧瞬,該設(shè)計(jì)結(jié)構(gòu)反映了組織的通信結(jié)構(gòu)。

這意味著渐夸,一個(gè)龐大嗤锉、緊密溝通的團(tuán)隊(duì)可能會(huì)生成一體化,緊密耦合的代碼墓塌,但一些較小的團(tuán)隊(duì)可能會(huì)生成更獨(dú)立档冬、松散耦合的代碼(有關(guān)此相關(guān)性的更多信息,請(qǐng)參閱《Demystifying Conway’s Law》)桃纯。對(duì)于我們來說,這意味著我們的通信結(jié)構(gòu)不僅影響特定的代碼段披坏,也影響整個(gè)代碼庫态坦。因此,與原作者密切溝通絕對(duì)是一個(gè)好辦法棒拂,但我們應(yīng)該自檢不要太過于依賴于原作者伞梯。這不僅可能會(huì)惹惱原作者,還可能在我們的代碼中產(chǎn)生無意識(shí)的耦合帚屉。

雖然這有助于我們深入研究代碼谜诫,但這是在假設(shè)可以接觸原作者的情況下。在很多時(shí)候攻旦,原作者可能已經(jīng)離開了公司喻旷,或恰巧不在公司(例如正在休假)。在此種情況下我們?cè)撟鍪裁蠢挝荩吭儐柨赡軐?duì)代碼有所了解的人且预。這個(gè)人不一定要曾真正工作于代碼槽袄,他可以是在原作者編寫代碼時(shí)就在周圍,也可以是認(rèn)識(shí)原作者锋谐。哪怕僅是從原開發(fā)者周圍的人中得到只言片語遍尺,也可能會(huì)啟迪其他未知的代碼片段。

3.刪除所有警告

心理學(xué)中有一個(gè)眾所周知的概念涮拗,稱為“破窗理論”乾戏,Andrew Hunt和Dave Thomas在《 The Pragmatic Programmer 》(第4-6頁)中詳細(xì)描述了這個(gè)概念。這個(gè)理論最初是由James Q.Wilson和George L. Kelling提出的三热,描述如下:

假設(shè)有一個(gè)建筑物有幾扇破了的窗戶鼓择。如果窗戶沒有修好,那么破壞者會(huì)趨向于打破更多的窗戶康铭。最終惯退,他們甚至可能會(huì)破門而入,如果建筑物是沒人住的从藤,那么他們可能會(huì)非法占有或者在里面點(diǎn)火催跪。也可以考慮人行道的情況。如果道路上面有垃圾堆積夷野,那么不久之后懊蒸,就會(huì)有更多的垃圾累積。最終悯搔,人們甚至?xí)_始往那里扔外賣垃圾骑丸,甚至打破汽車。

這個(gè)理論指出妒貌,如果似乎已經(jīng)沒人關(guān)心這個(gè)物品或事物通危,那么我們就會(huì)忽視對(duì)物品或事物的照顧,這是人的天性灌曙。例如菊碟,如果一棟建筑物看上去已經(jīng)凌亂不堪,那么它更有可能被肆意破壞在刺。在軟件方面逆害,這個(gè)理論意味著如果開發(fā)人員發(fā)現(xiàn)代碼已經(jīng)是一團(tuán)糟,那么人的本性會(huì)讓他弄壞代碼蚣驼。從本質(zhì)上說魄幕,我們心里想的是(即使心理活動(dòng)沒有這么豐富),“既然最后一個(gè)人不在乎這代碼颖杏,我為什么要在乎纯陨?”或“都是亂糟糟的代碼,誰知道是誰寫的《铀浚”

但是靡馁,這不應(yīng)該成為我們的借口。只要我們接觸以前屬于其他人的代碼机久,那么我們就要對(duì)這些代碼負(fù)責(zé)臭墨,并且如果它不能有效工作的話,我們得擔(dān)負(fù)后果膘盖。為了戰(zhàn)勝這種人的天性行為胧弛,我們需要采取一些小措施以避免我們的代碼更少地被弄臟(及時(shí)更換破掉的窗戶)。

一個(gè)簡單方法是刪除來自我們正在使用的整個(gè)包或模塊中的所有警告侠畔。至于未使用或添加注釋的代碼结缚,刪除它。如果我們稍后需要這部分代碼软棺,那么在存儲(chǔ)庫中红竭,我們總是可以從先前的提交中檢索它。如果存在無法直接解決的警告(例如原始類型警告)喘落,那么使用@SuppressWarnings注解注釋該調(diào)用或方法茵宪。這樣可以確保我們對(duì)代碼進(jìn)行過仔細(xì)的考慮:它們不是因?yàn)槭韬龆l(fā)出的警告,而是我們明確地注意到了警告(如原始類型)瘦棋。

一旦我們刪除或明確地禁止所有警告稀火,那么我們就必須確保代碼保持免除警告。這有兩個(gè)主要作用:

迫使我們仔細(xì)考慮我們創(chuàng)建的任何代碼赌朋。

減少代碼腐敗的變化凰狞,現(xiàn)在的警告會(huì)導(dǎo)致以后的錯(cuò)誤。

這對(duì)其他人沛慢,以及我們自己都有心理暗示作用——我們其實(shí)關(guān)心我們正在處理的代碼赡若。它不再是條單行線——我們強(qiáng)逼著自己更改代碼,提交团甲,然后永不回頭斩熊。相反,我們認(rèn)識(shí)到我們需要對(duì)這代碼負(fù)責(zé)伐庭。這對(duì)之后的軟件開發(fā)也是有幫助的——它向?qū)淼拈_發(fā)人員展示,這不是一間窗戶都破了的倉庫:而是一個(gè)維護(hù)良好的代碼庫分冈。

4.重構(gòu)

在過去幾十年中圾另,重構(gòu)已經(jīng)成為了一個(gè)非常重要的術(shù)語,并且最近被當(dāng)作是對(duì)當(dāng)前工作代碼做任何改變的代名詞雕沉。雖然重構(gòu)確實(shí)涉及對(duì)當(dāng)前正在工作的代碼的更改集乔,但并非整個(gè)大局。Martin Fowler在他關(guān)于這個(gè)話題的重要著作——《Refactoring》一書中將重構(gòu)定義為:

對(duì)軟件的內(nèi)部結(jié)構(gòu)進(jìn)行更改,使其更容易理解并且修改起來更便宜扰路,而不改變其可觀察的行為尤溜。

這個(gè)定義的關(guān)鍵在于它涉及的更改不會(huì)改變系統(tǒng)可觀察的行為。這意味著當(dāng)我們重構(gòu)代碼時(shí)汗唱,我們必須要有方法來確保代碼的外部可見行為不會(huì)改變宫莱。在我們的例子中,這意味著是在我們繼承或自己開發(fā)的測(cè)試套件中哩罪。為了確保我們沒有改變系統(tǒng)的外部行為授霸,每當(dāng)我們進(jìn)行改變時(shí),都必須重新編譯和執(zhí)行我們的全部測(cè)試际插。

此外碘耳,并不是我們所做的每一個(gè)改變都被認(rèn)為是重構(gòu)。例如框弛,重命名方法以更好地反映其預(yù)期用途是重構(gòu)辛辨,但添加新功能不是。為了看到重構(gòu)的好處瑟枫,我們將重構(gòu)SuccessfulFilter斗搞。執(zhí)行的第一個(gè)重構(gòu)是提取方法,以更好地封裝個(gè)人凈工資的邏輯:

publicclass SuccessfulFilter implements Predicate<Person> {@Overridepublic boolean test(Person person) {returnperson.getAge() <30&& getNetSalary(person) >60000;}private double getNetSalary(Person person) {return(((person.getSalary()-(250*12))-1500) *0.94);}}

在我們進(jìn)行這種改變之后力奋,我們重新編譯并運(yùn)行我們的測(cè)試套件榜旦,測(cè)試套件將繼續(xù)通過。現(xiàn)在更容易看出景殷,成功是通過一個(gè)人的年齡和凈薪酬定義的溅呢,但是getNetSalary方法似乎并不像Person類一樣屬于SuccessfulFilter(指示標(biāo)志就是該方法的唯一參數(shù)是Person,該方法的唯一調(diào)用是Person類的方法猿挚,因此對(duì)Person類有很強(qiáng)的親和力)咐旧。 為了更好地定位這個(gè)方法,我們執(zhí)行一個(gè)Move方法將其移動(dòng)到Person類:

publicclass Person {privateintage;privatedoublesalary;public Person(int age, double salary) {this.age = age;this.salary = salary;}public void setAge(int age) {this.age = age;}public int getAge() {returnage;}public void setSalary(double salary) {this.salary = salary;}public double getSalary() {returnsalary;}public double getNetSalary() {return((getSalary() - (250*12)) -1500) *0.94;}}publicclass SuccessfulFilter implements Predicate<Person> {@Overridepublic boolean test(Person person) {returnperson.getAge() <30&&person.getNetSalary() >60000;}}

為了進(jìn)一步清理此代碼绩蜻,我們對(duì)每個(gè)magic number執(zhí)行符號(hào)常量替換magic number行為铣墨。為了知道這些值的含義,我們可能得和原作者交流办绝,或者向具有足夠領(lǐng)域知識(shí)的人請(qǐng)教伊约,以引領(lǐng)正確的方向。我們還將執(zhí)行更多的提取方法重構(gòu)孕蝉,以確甭怕桑現(xiàn)有的方法盡可能簡單。

publicclass Person {privatestaticfinalintMONTHLY_BONUS =250;privatestaticfinalintYEARLY_BONUS = MONTHLY_BONUS *12;privatestaticfinalintYEARLY_BENEFITS_DEDUCTIONS =1500;privatestaticfinaldoubleYEARLY_401K_CONTRIBUTION_PERCENT =0.06;privatestaticfinaldoubleYEARLY_401K_CONTRIBUTION_MUTLIPLIER =1- YEARLY_401K_CONTRIBUTION_PERCENT;privateintage;privatedoublesalary;public Person(int age, double salary) {this.age = age;this.salary = salary;}public void setAge(int age) {this.age = age;}public int getAge() {returnage;}public void setSalary(double salary) {this.salary = salary;}public double getSalary() {returnsalary;}public double getNetSalary() {returngetPostDeductionSalary();}private double getPostDeductionSalary() {returngetPostBenefitsSalary() * YEARLY_401K_CONTRIBUTION_MUTLIPLIER;}private double getPostBenefitsSalary() {returngetSalary() - YEARLY_BONUS - YEARLY_BENEFITS_DEDUCTIONS;}}publicclass SuccessfulFilter implements Predicate<Person> {privatestaticfinalintTHRESHOLD_AGE =30;privatestaticfinaldoubleTHRESHOLD_SALARY =60000.0;@Overridepublic boolean test(Person person) {returnperson.getAge() THRESHOLD_SALARY;}}

重新編譯和測(cè)試降淮,發(fā)現(xiàn)系統(tǒng)仍然按照預(yù)期的方式工作:我們沒有改變外部行為超埋,但是我們改進(jìn)了代碼的可靠性和內(nèi)部結(jié)構(gòu)。

5.當(dāng)你離開的時(shí)候,代碼比你發(fā)現(xiàn)它的時(shí)候更好

最后這個(gè)技術(shù)在概念上非常簡單霍殴,但在實(shí)踐中很困難:讓代碼比你發(fā)現(xiàn)它的時(shí)候更好媒惕。當(dāng)我們梳理代碼,特別是別人的代碼時(shí)来庭,我們大多會(huì)添加功能妒蔚,測(cè)試它,然后前行巾腕,不關(guān)心我們會(huì)不會(huì)貢獻(xiàn)軟件腐爛面睛,也不在乎我們添加到類的新方法會(huì)不會(huì)導(dǎo)致額外的混亂。因此尊搬,本文的全部內(nèi)容可總結(jié)為以下規(guī)則:

每當(dāng)我們修改代碼時(shí)叁鉴,請(qǐng)確保當(dāng)你離開的時(shí)候,代碼比你發(fā)現(xiàn)它的時(shí)候更好佛寿。

前面提到過幌墓,我們需要對(duì)類造成的損壞和對(duì)改變的代碼負(fù)責(zé),如果它不能工作冀泻,那么修復(fù)是我們的職責(zé)常侣。為了戰(zhàn)勝伴隨軟件生產(chǎn)而出現(xiàn)的熵,我們必須強(qiáng)制自己做到離開時(shí)的代碼比我們發(fā)現(xiàn)它的時(shí)候更佳弹渔。為了不逃避這個(gè)問題胳施,我們必須償還技術(shù)債務(wù),確保下一個(gè)接觸代碼的人不需要再付出代價(jià)肢专。說不定舞肆,將來可能是我們自己感謝自己這個(gè)時(shí)候的堅(jiān)持呢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末博杖,一起剝皮案震驚了整個(gè)濱河市椿胯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剃根,老刑警劉巖哩盲,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異狈醉,居然都是意外死亡廉油,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門苗傅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抒线,“玉大人,你說我怎么就攤上這事金吗。” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵摇庙,是天一觀的道長旱物。 經(jīng)常有香客問我,道長卫袒,這世上最難降的妖魔是什么宵呛? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮夕凝,結(jié)果婚禮上宝穗,老公的妹妹穿的比我還像新娘。我一直安慰自己码秉,他們只是感情好逮矛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著转砖,像睡著了一般须鼎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上府蔗,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天晋控,我揣著相機(jī)與錄音,去河邊找鬼姓赤。 笑死赡译,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的不铆。 我是一名探鬼主播蝌焚,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼狂男!你這毒婦竟也來了综看?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤岖食,失蹤者是張志新(化名)和其女友劉穎红碑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泡垃,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡析珊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔑穴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忠寻。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖存和,靈堂內(nèi)的尸體忽然破棺而出奕剃,到底是詐尸還是另有隱情衷旅,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布纵朋,位于F島的核電站柿顶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏操软。R本人自食惡果不足惜嘁锯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望聂薪。 院中可真熱鬧家乘,春花似錦、人聲如沸藏澳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽笆载。三九已至扑馁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凉驻,已是汗流浹背腻要。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涝登,地道東北人雄家。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像胀滚,于是被迫代替她去往敵國和親趟济。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容