修改代碼的藝術—– 1.1 修改軟體的四個起因

來源:互聯網
上載者:User

修改(既有)代
碼本身並無什麼問題,我們正是以此謀生的。然而,如果修改的方式不當則會招來麻煩,當然,只要方法正確,我們也可以令事情變得簡單得多。在業界,對於修改
代碼的方法學討論得不是很多,其中最接近的恐怕是重構方面的文獻了。因此我覺得可以將討論的範疇稍微擴大一點,即討論如何在最為棘手的情況下處理代碼。為
此,我們首先要深入瞭解修改的深層機理。

1.1  修改軟體的四個起因

為了簡明起見,讓我們來看看修改軟體的四個主要起因:

(1) 添加新特性;

(2) 修正bug;

(3) 改善設計;

(4) 最佳化資源使用。

1.1.1  添加特性和修正bug

添加特性看起來似乎是最直接的一種改動:軟體原先是以某種方式運作的,現在使用者提出需要這個系統能夠做其他事情。

假設我們正在構建一個基於Web的應用,這時經理告
訴我們她(指客戶)想要把公司的logo從頁面的左側移到右側。於是我們與她交談,發現這件事情並不是想象中那麼簡單。她不但要移動logo,還想進行其
他改動。她希望在系統的下一個版本中能夠讓它動起來。那麼,這算是修正bug還是添加新特性呢?答案取決於你看待這個問題的角度。從客戶的角度來看,她很
明顯是在要求我們修正一個問題。因為不久前她預覽了網站,然後召集其部門的人員舉行了一個會議,最後大家決定改動logo的位置,並要求更多一點的功能。
而站在開發人員的立場上,這種改動則可以看成是添加一個全新的特性。開發人員會說:“如果客戶不改變主意的話,我們的工作現在就已經算是完成了。”然而,對於
某些公司,移動logo的位置只是看作bug修正,他們並不管Team Dev為此而不得不從頭開始做一些新工作的事實。

我們可以認為以上這些純屬主觀看法的差異:在你的眼
裡它是一次bug修正,而在我看來則是添加新特性,就這麼簡單。然而實際情況是,許多公司出於合約或品質方面的某些原因和目的,bug修正與特性添加是必
須分開記錄和解決的。從人的層面來看,我們可以在“我們是在添加特性還是在修正bug”這個問題上爭論不休。然而從代碼層面來說,這些終究不過是在修改代
碼以及其他遺留下來的東西罷了。不幸的是,這種關於究竟是bug修正還是特性添加的爭執掩蓋了某些從技術上來說對我們要重要得多的東西:行為改變。事實
上,在添加新行為與改變舊行為之間存在著巨大的差異。

行為對於軟體來說是最重要的一樣東西。軟體的使用者要依賴於軟體的行為。使用者喜歡我們添加行為(前提是新的行為確實是他們所需要的),然而如果我們改變或移除了他們原本所依賴的行為(引入bug),那麼他們就不會再相信我們。

回過頭來,在前面提到的公司logo的案例中,我們是在添加新行為嗎?是的。因為在改動之後,系統將會在頁面的右側顯示logo。那麼我們是否移除掉了某些行為呢?是的,因為頁面的左側將不會再有logo。

讓我們再來看一個更為複雜的案例。假設客戶想要在頁面的右側添加一個logo,同時在頁面的左側原本並沒有任何logo。在這種情況下我們就是在添加新行為,但我們有沒有移除任何已有行為呢?我們即將要放置logo的地方原本是否是由其他圖案或文字佔據的呢?

我們是在改變行為,添加行為,還是兩者皆是?

事實上,我們可以抽出一個對於程式員來說更為有用的差別。即如果我們必須修改代碼(HTML某種程度上也算代碼),那麼我們就是在改變行為。如果我們只是往其中添加代碼並調用它,則通常是在添加行為。對此我們再來看一個例子。下面是一個Java類的方法:

public class CDPlayer

{

    public void addTrackListing(Track
track) {

        ...

    }

    ...

}

該類擁有一個方法addTrackListing,我們通過該方法能夠添加音軌列表。現在,讓我們添加一個用於替換音軌列表的新方法:

public class CDPlayer

{

    public void addTrackListing(Track
track) {

        ...

    }

    public void replaceTrackListing(String
name, Track track) {

        ...

    }

    ...

}

當添加該方法時,我們是在往該應用程式中添加新行為呢,還是改變了現有行為?答案是:兩者都不是。添加一個方法並不會改變代碼的行為,除非我們以某種方式調用了該方法。

現在我們來進行另一處修改,往這個CD播放軟體的用
戶介面上放置一個新的按鈕。該按鈕的功能是讓使用者能夠替換音軌列表。這一舉動不僅添加了replaceTrackListing方法所指定的行為,同時也
細微地改變了該軟體的行為。因為有了這個新按鈕,使用者介面的渲染(render)就與以前不一樣了,使用者介面的顯示大概需要多耗一毫秒(用於渲染新的按
鈕)。所以,想要完全不改變現有行為地添加新行為幾乎是不可能的。

1.1.2  改善設計

改善設計則是另一種軟體修改。當我們想要改變既有軟
件的結構和組織,以令其更易於維護時,通常也會希望能夠在此過程中不改變其行為。倘若在這個過程中丟掉了某個行為,我們通常會將其稱作引入了一個bug。
許多程式員通常並不試圖改善既有設計,其主要原因之一就是這一舉動相對容易導致行為喪失或壞行為的誕生。

在不改變軟體行為的前提下改善其設計的舉動稱為重構
(refactoring)。重構背後的理念是,如果我們編寫測試以確保現有行為不變,並在重構過程中的每一小步都小心驗證其行為的不變性的話,我們就可
以在不改變軟體行為的前提下通過重構使其更具可維護性。多年來人們一直都在做著清理系統中既有代碼的事情,而重構的出現則是近幾年的事。重構與一般的代碼
清理不同,在重構時我們並不只是在做那些低危險性的工作(如重整原始碼的格式)或侵入性的危險工作(如重寫代碼塊),而是進行一系列的結構上的小改動,並
通過測試的支援來使得代碼的修改更容易著手。從改變的角度來說,重構的關鍵在於在進行重構的過程中不應當有任何功能上的改變。(不過行為可以稍有改變,因
為你在代碼結構上的改動可能會導致效能上的改變,其效能可能會變得差一點,也可能會變得好一點。)

1.1.3  最佳化

最佳化與重構類似,但目標不同。對於重構和最佳化,我們
都可以說:“我們在進行修改的過程中將會保持功能不變,但我們可能會改變某些其他東西。”對於重構來說,這裡的“某些其他東西”就是指程式的結構,我們想
讓代碼更容易維護。而對於最佳化來說,“某些其他東西”則是指程式所使用的某些資源,通常指時間或記憶體。

1.1.4  綜合起來

重構與最佳化的相似性看起來似乎有點奇怪。它們彼此間的相似性看上去比添加特性與修正bug之間的相似性還要高。然而,真的是這樣嗎?重構與最佳化之間的共同點就是在改變某些東西的過程中保持軟體的功能不變。

一般而言,當對一個系統進行修改的時候,其三個方面可能會發生改變:結構、功能以及資源使用。

讓我們來看一看,當進行上述四種修改的時候,系統通常在哪些方面發生改變,以及哪些方面基本保持不變(通常其三個方面都會發生改變,但讓我們來看看什麼是典型的情況):

添加特性

修正bug

重   

優   

結構

改變

改變

改變

功能

改變

改變

資源使用

改變

從表面上看,重構和最佳化的確是蠻相似的。它們都保持功能不變。但倘若我們將新功能的出現分離出來考慮又會怎樣呢?當我們添加一個新特性時,通常是在維持現有功能不變的前提下添加新的功能。

添加特性

修正bug

重   

優   

結構

改變

改變

改變

新功能

改變

功能

改變

資源使用

改變

添加特性、重構以及最佳化這三種舉動統統都維持既有功能不變。如果仔細觀察bug修正的話,我們會發現它是會改變(既有)功能的,只不過這種改變比起那些沒被改變的既有功能通常顯得非常微小罷了。

特性添加和bug修正與重構和最佳化是非常相似的。在所有四種情況下,我們都想要改變某些功能、某些行為,但我們想要保持不變的地方則要多得多(見圖1-1)。

圖1-1  既有行為行為保持

圖1-1很好地表現了當對系統進行修改時所發生的情
況,那麼在實際工作中這幅圖對我們來說又意味著什麼呢?從積極的角度來說,這幅圖似乎告訴我們應當將注意力集中在什麼方面。我們要確保所修改的少數幾處已
經正確修改了。從消極的角度來說,我們不僅需要關注這些,還得知道如何保持其他行為不變。然而遺憾的是,保留既有行為不變並非意味著只要不碰那些代碼就
成。我們要知道這些行為並沒有發生改變,而這可能是件棘手的事情。需要保持的行為的數量通常是非常巨大的,不過這倒不是什麼大問題。問題在於我們通常並不
知道在修改的過程中哪些行為存在被連帶改變的風險。如果我們知道,就可以將精力集中在那些行為上而不用管其他的。所以,要想安全地進行修改,關鍵就在於
“理解”。

保留既有行為不變是軟體開發中最具挑戰性的任務之一。即便是在改變主要特性時,通常也有很多行為是必須保留不變的。


修改(既有)代
碼本身並無什麼問題,我們正是以此謀生的。然而,如果修改的方式不當則會招來麻煩,當然,只要方法正確,我們也可以令事情變得簡單得多。在業界,對於修改
代碼的方法學討論得不是很多,其中最接近的恐怕是重構方面的文獻了。因此我覺得可以將討論的範疇稍微擴大一點,即討論如何在最為棘手的情況下處理代碼。為
此,我們首先要深入瞭解修改的深層機理。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.