什么是軟件再工程
任何一個(gè)有多年工作經(jīng)驗的軟件開(kāi)發(fā)者都曾經(jīng)面臨過(guò)這樣一個(gè)困難的局面:如何改進(jìn)應用程序。這種困難之處包括:瀏覽代碼很困難,確定從哪里開(kāi)始追蹤缺陷很困難,對缺陷進(jìn)行修復也很困難??傊?,關(guān)于應用程序的所有一切都很難。改進(jìn)和修復缺陷耗時(shí)長(cháng)、風(fēng)險高而且代價(jià)大。
解決舊版應用程序問(wèn)題的一種可能的選擇是:離線(xiàn)一年或更久的時(shí)間,從頭開(kāi)始重寫(xiě)。通常情況下,這些應用程序對業(yè)務(wù)運營(yíng)是非常關(guān)鍵的,所以,功能開(kāi)發(fā)不能停滯如此長(cháng)的一段時(shí)間。因此,對舊版應用程序的修復工作需要不間斷地進(jìn)行,以期在下一個(gè)發(fā)布周期之前修復所有缺陷并推出補丁。
此外,還有一種選擇來(lái)幫助解決這些舊版系統的問(wèn)題,那就是“軟件再工程”。
什么是舊軟件
一個(gè)應用程序構建完成后,就會(huì )立即步入老化的過(guò)程。軟件工程是一門(mén)年輕的學(xué)科,構建應用程序的方法每天都在推陳出新。隨著(zhù)業(yè)界不斷引入新的開(kāi)發(fā)工具,如果不更新現有的應用程序從而使用這些工具,那么它們會(huì )變得越來(lái)越難以維護。
軟件老化的原因
軟件老化有很多原因。最明顯的原因莫過(guò)于當今世界科學(xué)技術(shù)的飛速發(fā)展。幾年前才開(kāi)發(fā)的軟件技術(shù)很快就會(huì )變得陳舊,并且難以維護。
快速的工作變動(dòng)正在成為一種潮流,這同樣加劇了代碼質(zhì)量的下降。隨著(zhù)原先的開(kāi)發(fā)人員轉投新的公司,關(guān)于代碼結構設計的最初的一些理念就會(huì )丟失,導致留下的開(kāi)發(fā)人員拼盡全力收拾殘局。
然而,通過(guò)使用軟件再工程持續不斷地改進(jìn)系統,這種對原代碼設計者的依賴(lài)程度就會(huì )削弱。新的開(kāi)發(fā)人員也能很容易適應和了解系統的架構,這主要是因為系統的架構將是與時(shí)俱進(jìn)的,同時(shí)在網(wǎng)絡(luò )上也可以找到很多有用的信息。
警示標志
特定標志可以警示一個(gè)系統是否真的到了需要再工程的時(shí)候。
開(kāi)發(fā)者對功能請求存在抵觸情緒
如果開(kāi)發(fā)人員抵制來(lái)自于管理人員或用戶(hù)的功能請求,不愿意改進(jìn)應用程序,那么很有可能是因為該系統真的已經(jīng)到了舉步維艱的地步。隨著(zhù)時(shí)間的推移,該軟件應用會(huì )變得非常脆弱,從而導致任何功能的開(kāi)發(fā)都變得極其困難且令人沮喪。
發(fā)布后存在著(zhù)大量缺陷修復工作
如果開(kāi)發(fā)團隊在軟件新版本發(fā)布后馬上就面臨缺陷警告,則表明軟件在開(kāi)發(fā)過(guò)程中并沒(méi)有使用現代的質(zhì)量保證工具。為了顯著(zhù)減少缺陷率,部分軟件再工程流程需要引入這些自動(dòng)化的質(zhì)量保證工具。
軟件質(zhì)量問(wèn)題長(cháng)期存在
舊軟件中缺陷及其修復工作的多少顯示了舊軟件的老化程度。軟件的老化和脆弱程度越高,做非破壞性的修復就越難。如果你發(fā)現,每當剛修復一個(gè)缺陷,馬上就有兩個(gè)或者更多的缺陷涌現出來(lái)的時(shí)候,那么說(shuō)明這個(gè)應用程序需要進(jìn)行再工程。
由于不支持諸如單元測試和系統模擬等新的質(zhì)量保證方法,舊版應用程序特別容易出現質(zhì)量問(wèn)題。如果不使用這些工具,那么在系統修復時(shí)所產(chǎn)生的那些缺陷,看上去會(huì )與剛剛所做的修復完全無(wú)關(guān)。
軟件再工程的目標和優(yōu)點(diǎn)
軟件再工程的目標是通過(guò)引入現代的架構和軟件開(kāi)發(fā)技術(shù)來(lái)逐步改善現有系統,同時(shí)在保證在線(xiàn)的情況下,持續不斷地為系統增加新的功能。這意味著(zhù)對目前已有的系統來(lái)說(shuō),我們無(wú)須費盡心思重寫(xiě)代碼。通過(guò)軟件再工程,我們可以有條不紊地改進(jìn)現有系統,使之逐漸達到符合最新的軟件開(kāi)發(fā)標準的水平。在整個(gè)軟件再工程項目期間,系統隨時(shí)都可以進(jìn)行產(chǎn)品發(fā)布。換句話(huà)說(shuō),這就好比我們可以在飛機飛行的同時(shí)對飛機進(jìn)行維修。
引入現代架構
軟件系統的架構決定了需要建立的必要細節的數量。有的時(shí)候,我們試圖使用最新的方法為一個(gè)舊系統建立一種數據輸入的形式,這就像是為一架雙翼飛機加上一個(gè)噴氣式發(fā)動(dòng)機一樣,這樣做飛機就算飛離地面也飛行不了多久。
大多數管理者聽(tīng)到“需要更新架構”的第一反應就是應用程序必須重寫(xiě)。這并不一定正確。事實(shí)上,只要保證新的組件在接入的過(guò)程中,始終保持一個(gè)合理的步驟和順序,那么架構的更新就可以逐步實(shí)現。
引入新架構無(wú)須勞師動(dòng)眾。不管開(kāi)發(fā)團隊有多少人,或者現有系統有多少行代碼,新架構的引入完全可以由一個(gè)小團隊甚至一個(gè)獨立的設計師來(lái)完成。引入新架構的每一步都是獨立的,并且不影響應用程序的其余部分。引入新架構和質(zhì)量管理無(wú)須大量的預算或者專(zhuān)家團隊。
在線(xiàn)增加新功能
本書(shū)中關(guān)于如何在線(xiàn)增加新功能的所有步驟都是特別設計的,這樣既保證了這些步驟不會(huì )對其他開(kāi)發(fā)造成干擾,同時(shí)保證了這些步驟之間可以并發(fā)進(jìn)行。這些新功能的結構也是特別設計的,為的是保證引入的新功能不會(huì )帶來(lái)任何不利影響,并在完成時(shí)通過(guò)幾行代碼就可啟用新功能。這確保:在前端,產(chǎn)品經(jīng)理能夠持續不斷地接受產(chǎn)品新的功能請求,發(fā)布更新的版本;在后臺,每個(gè)新的版本都會(huì )在前一版本的基礎上有所改進(jìn)。
對于任何一個(gè)新增的功能,如果它需要一個(gè)獨立程序開(kāi)發(fā)員花費一整天的時(shí)間來(lái)完成,那么為該應用增加新功能的過(guò)程將會(huì )被重新分解成多個(gè)小的步驟。這樣做的目的在于:一方面,保證該應用的部分功能能夠持續更新;另一方面,保證該應用的其他部分功能仍然能夠使用舊的結構。
隨著(zhù)該應用每一個(gè)部分的逐步更新,應用程序將會(huì )變得更可測,缺陷率也會(huì )大幅度地降低。
靈活使用敏捷方法
很多開(kāi)發(fā)公司都采用敏捷開(kāi)發(fā)策略。對于不熟悉這種方法的公司來(lái)說(shuō),敏捷開(kāi)發(fā)可以簡(jiǎn)單地解釋成快速周期開(kāi)發(fā)。這種周期(又稱(chēng)為“沖刺”)通常以幾天或者幾周來(lái)度量。每個(gè)快速周期開(kāi)發(fā)結束時(shí),應用程序處于一個(gè)潛在可發(fā)布狀態(tài)。
保持應用程序處于一個(gè)潛在可發(fā)布狀態(tài),就是軟件再工程。每一次所做的更新都必須是完整和獨立的,這樣才能夠保證在提交代碼的時(shí)候,一方面系統仍然可以正常運行;另一方面系統能夠處在一個(gè)穩步提升質(zhì)量的過(guò)程中。這就是本書(shū)在設計這些步驟時(shí)所遵循的設計方法。每個(gè)步驟都可以在一個(gè)沖刺階段中完成,而這往往是一天。極少數軟件再工程的工作需要比較長(cháng)的時(shí)間。這樣的工作就需要特殊設計,以保證當它們還沒(méi)完成,或者完成一半的時(shí)候,整個(gè)系統受到的影響也是微乎其微的:系統可以照常運行,只不過(guò)部分功能已經(jīng)進(jìn)行過(guò)更新,部分功能還處于舊版本的狀態(tài)下。
降低風(fēng)險
一個(gè)軟件系統使用多年之后,用戶(hù)就會(huì )形成對該軟件系統固定的業(yè)務(wù)流程操作模式。重寫(xiě)整個(gè)系統會(huì )破壞這些未文檔化的業(yè)務(wù)流程,逼迫用戶(hù)在工作流中使用新系統。
軟件再工程維持了工作中的這些未文檔化的流程。通過(guò)在現有系統上慢慢引入新的架構,這些流程就可以不受干擾。如果引入新架構確實(shí)以某種形式擾亂了正常的業(yè)務(wù)流程,那么一定會(huì )有一個(gè)及時(shí)的反饋,通常情況下,應用軟件的產(chǎn)品化必須是快速而敏捷的。
降低成本
從頭重寫(xiě)系統要求對所有業(yè)務(wù)邏輯的開(kāi)發(fā)也要推倒重來(lái)。對于一個(gè)舊版系統來(lái)說(shuō),重寫(xiě)軟件擯棄了之前投入的大量時(shí)間和知識,而事實(shí)上這些時(shí)間和知識在軟件重寫(xiě)過(guò)程中不可避免地需要被重新創(chuàng )建。
再工程盡可能地復用現有的業(yè)務(wù)邏輯代碼,從而可以顯著(zhù)節省大量的時(shí)間和金錢(qián)。在再工程項目中,有顯著(zhù)數量的任務(wù)可以跳過(guò)而無(wú)須改動(dòng)。而這些任務(wù)的總體數量是非??捎^(guān)的。由于現有系統已包含絕大多數的需求,所以只需新增極少數的需求文檔。這可以為需求分析人員節省下幾周甚至幾個(gè)月的調研和歸檔用戶(hù)需求的時(shí)間。有了實(shí)現這些需求的業(yè)務(wù)邏輯,會(huì )節省更多的時(shí)間。
1990年,W.M.Ulrich為《American Programmer》雜志的十月刊撰寫(xiě)了一篇文章。在文章中,他描述了一個(gè)商業(yè)系統,該系統完全重寫(xiě)的成本約為5億美金。事實(shí)上,該系統成功地進(jìn)行了再工程,其總成本僅為1.2億美金。相比全新的開(kāi)發(fā),再工程是非常經(jīng)濟的。
本書(shū)的讀者對象
本書(shū)適合從事維護和運行系統工作的讀者。對于技術(shù)經(jīng)理和產(chǎn)品經(jīng)理來(lái)說(shuō),本書(shū)描述了提高系統可靠性的必要過(guò)程,其使得系統運行更快,更易維護以及擁有更少的缺陷。對于架構師和開(kāi)發(fā)人員來(lái)說(shuō),本書(shū)包含了新架構的選擇方法以及完成關(guān)鍵部分的必要代碼的詳細描述。對于通過(guò)添加現代架構和自動(dòng)化測試方法增量地改進(jìn)應用程序的結構和質(zhì)量,本書(shū)給出了詳細的建議。按照本書(shū)中概括的步驟,可以提高應用程序的質(zhì)量并使得添加新功能變得更加容易和快速。
再工程一個(gè)現有系統比從頭開(kāi)始構建一個(gè)等效的系統更加容易、便宜且風(fēng)險低。如果你遵循本書(shū)中總結的建議,就可以提高開(kāi)發(fā)的速度和最終的質(zhì)量,同時(shí)還可以保持系統正常運行。
我希望你發(fā)現本書(shū)是一種很好的資源,并且可以節約時(shí)間。
致謝
沒(méi)有許多朋友的幫助,我不可能完成這本書(shū)。首先,我想要感謝我的技術(shù)編輯Joey Ebright和Peter Himschoot,他們在確保我的代碼整潔、正確和切中要點(diǎn)方面做得非常出色。他們的架構洞察力和許多中肯的建議使得這本書(shū)更加完美。我還想要感謝我的編輯Christopher Cleveland和Jeff Riley,他們對本書(shū)的結構和流程提供了有價(jià)值的建議。最后,我想要感謝Joan Murray,她給了我自信去接受這個(gè)挑戰。我希望有機會(huì )在另一本書(shū)中再次和所有人一起合作。