第2章 重構(gòu)原則_第1頁
第2章 重構(gòu)原則_第2頁
第2章 重構(gòu)原則_第3頁
第2章 重構(gòu)原則_第4頁
第2章 重構(gòu)原則_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第2章 重構(gòu)原則2.1 概念 調(diào)整軟件內(nèi)部結(jié)構(gòu),在不改變軟件行為前提下,提高其可理解性,降低修改成本。 重構(gòu)使軟件更容易被理解和修改??梢栽谲浖?nèi)部做很多修改,但必須對(duì)軟件可觀察到的外部行為造成很小變化,或不造成變化。 和重構(gòu)形成對(duì)比的是“性能優(yōu)化”。性能優(yōu)化通常不會(huì)改變組件的行為(除了執(zhí)行速度),只會(huì)改變其內(nèi)部結(jié)構(gòu)。 兩者出發(fā)點(diǎn)不同,性能優(yōu)化往往使代碼較難理解,但為了得到所需性能不得不那么做。 2.2 重構(gòu)目的改進(jìn)軟件設(shè)計(jì) 如果沒有重構(gòu),程序的設(shè)計(jì)會(huì)變差。 當(dāng)人們只為短期目的或者在完全理解整體設(shè)計(jì)之前,貿(mào)然修改代碼,程序?qū)⒅饾u失去自己的結(jié)構(gòu),程序員越來越難以通過閱讀源碼而理解原本設(shè)計(jì)。代碼結(jié)

2、構(gòu)的流失是累積性的。越難看出代碼所代表的設(shè)計(jì)意涵,就越難保護(hù)其中設(shè)計(jì),于是該設(shè)計(jì)就腐敗得愈快。 重構(gòu)很像是在整理代碼 ,所做的就是讓所有東西回到應(yīng)該的位置上。經(jīng)常性的重構(gòu)可以幫助代碼維持自己該有的形態(tài) 。 同樣完成一件事,設(shè)計(jì)不良的程序往往需要更多代碼,這常常是因?yàn)榇a在不同的地方使用完全相同的語句做同樣的事。因此改進(jìn)設(shè)計(jì)的一個(gè)重要方向就是消除重復(fù)代碼。 這個(gè)動(dòng)作的重要性著眼于未來。代碼數(shù)量減少并不會(huì)使系統(tǒng)運(yùn)行更快,然而會(huì)使未來可能的程序修改變得容易得多。代碼愈多,就愈難正確修改,因?yàn)橛懈啻a需要理解。如果消除重復(fù)代碼,就可以確定代碼將所有事物和行為都只表述一次,這是優(yōu)秀設(shè)計(jì)的根本。 2.

3、使軟件更易被理解 一、使別人容易理解。 謂程序設(shè)計(jì),便是與計(jì)算機(jī)交談。編寫代碼告訴計(jì)算機(jī)做什么事,它的回應(yīng)則是精確按照你的指示行動(dòng)。除了計(jì)算機(jī)外,源碼還有其他讀者:數(shù)個(gè)月之后可能會(huì)有另一位程序員嘗試讀懂你的代碼并做一些修改。 二、利用重構(gòu)來協(xié)助理解不熟悉的代碼。 看到不熟悉的代碼,需試著理解它的用途。有了重構(gòu)這個(gè)概念,就不會(huì)滿足頭腦中得到的一點(diǎn)體會(huì)。而是真正動(dòng)手修改代碼,讓它更好地反映出我的理解,然后重新執(zhí)行,看它是否仍然正常運(yùn)作,以此檢驗(yàn)我的理解是否正確。隨著代碼漸趨簡(jiǎn)潔,發(fā)現(xiàn)自己可以看到一些以前看不到的設(shè)計(jì)層面的東西,達(dá)到更高的理解層次。3.有助找到缺陷(bug) 如果對(duì)代碼進(jìn)行重構(gòu),就可

4、以深入理解代碼的作為,恰到好處地把新的理解反饋回去。搞清楚程序結(jié)構(gòu)的同時(shí),也清楚了自己所做的一些假設(shè),從這個(gè)角度來說,從而非常容易的找出缺陷。4.提高編程速度 良好設(shè)計(jì)是快速軟件開發(fā)的根本。擁有良好設(shè)計(jì)才可能達(dá)成快速的開發(fā)。如果沒有良好設(shè)計(jì),或許某一段時(shí)間內(nèi)程序進(jìn)展迅速,但惡劣的設(shè)計(jì)很快就讓速度慢下來。程序員會(huì)把時(shí)間花在調(diào)試上面,無法添加新功能。修改時(shí)間愈來愈長,因?yàn)楸仨毣ㄓ鷣碛嗟臅r(shí)間去理解系統(tǒng)、尋找重復(fù)代碼。隨著給最初程序打上一個(gè)又一個(gè)的補(bǔ)丁,新特性需要更多代碼才能實(shí)現(xiàn)。這是個(gè)惡性循環(huán)。2.3 何時(shí)重構(gòu)1. 添加功能時(shí) 最常見的重構(gòu)時(shí)機(jī)就是想給軟件添加新特性的時(shí)候。這些代碼可能是別人寫的,

5、也可能是自己寫的。無論何時(shí)只要想理解代碼所做的事,就會(huì)問自己:是否能對(duì)這段代碼進(jìn)行重構(gòu),使我能更快理解它。之所以這么做,部分原因是為了下次再看這段代碼時(shí)容易理解,但最主要的原因是:如果在前進(jìn)過程中把代碼結(jié)構(gòu)理清,就可以從中理解更多東西。 另外,現(xiàn)有代碼的設(shè)計(jì)無法幫助輕松添加所需要的特性。如果改用某種方式來設(shè)計(jì),添加特性會(huì)簡(jiǎn)單得多。修補(bǔ)錯(cuò)誤時(shí)復(fù)審代碼時(shí) 重構(gòu)可以幫助復(fù)審別人的代碼。開始先閱讀代碼,得到一定程度的理解,并提出一些建議。一旦想到一些點(diǎn)子,就會(huì)考慮是否可以通過重構(gòu)立即輕松地實(shí)現(xiàn)它們。這樣可以把代碼看得更清楚,提出更多恰當(dāng)?shù)慕ㄗh。 重構(gòu)還可以幫助代碼復(fù)審工作得到更具體的結(jié)果。不僅獲得建議

6、,而且其中許多建議能夠立刻實(shí)現(xiàn),從而在實(shí)踐中得到比以往多得多的成就。2.4 重構(gòu)的難題1. 數(shù)據(jù)庫 重構(gòu)經(jīng)常出問題的一個(gè)領(lǐng)域就是數(shù)據(jù)庫,有兩個(gè)原因: 數(shù)據(jù)耦合。絕大多數(shù)商用程序都與它們背后的數(shù)據(jù)庫表格結(jié)構(gòu)緊密耦合在一起。 數(shù)據(jù)遷移。即使非常小心地將系統(tǒng)分層,將數(shù)據(jù)庫表格結(jié)構(gòu)和對(duì)象模型間的依賴降至最低,但數(shù)據(jù)庫表格結(jié)構(gòu)的改變還是不得不遷移所有數(shù)據(jù)。 在非對(duì)象數(shù)據(jù)庫中,解決這個(gè)問題的辦法之一就是:在對(duì)象模型和數(shù)據(jù)庫模型之間插入一個(gè)分隔層,隔離兩個(gè)模型各自的變化。升級(jí)某一模型時(shí)無需同時(shí)升級(jí)另一模型,只需升級(jí)上述的分隔層即可。 這樣的分隔層會(huì)增加系統(tǒng)復(fù)雜度,但會(huì)帶來很大的靈活度。如果同時(shí)擁有多個(gè)數(shù)據(jù)庫

7、,或如果數(shù)據(jù)庫模型較為復(fù)雜使人難以控制,那么即使不進(jìn)行重構(gòu),這分隔層也很重要。 對(duì)開發(fā)者而言,對(duì)象數(shù)據(jù)庫既有幫助也有妨礙。某些面向?qū)ο髷?shù)據(jù)庫提供不同版本的對(duì)象之間的自動(dòng)遷移功能,這減少了數(shù)據(jù)遷移時(shí)的工作量,但還是會(huì)損失一定時(shí)間。如果各數(shù)據(jù)庫之間的數(shù)據(jù)遷移并非自動(dòng)進(jìn)行,就必須自行完成遷移工作,這種情況下必須更加注意數(shù)據(jù)結(jié)構(gòu)變化。數(shù)據(jù)尚未被轉(zhuǎn)移前先運(yùn)用訪問函數(shù)造成數(shù)據(jù)已經(jīng)轉(zhuǎn)移的假象。一旦確定數(shù)據(jù)應(yīng)該在何處時(shí),就可以一次性地將數(shù)據(jù)遷移過去。這時(shí)惟一需要修改的只有訪問函數(shù),從而降低錯(cuò)誤風(fēng)險(xiǎn)。2. 修改接口 如果重構(gòu)手法改變了已發(fā)布接口,必須同時(shí)維護(hù)新舊兩個(gè)接口,直到所有用戶都有時(shí)間對(duì)這個(gè)變化做出反應(yīng)。

8、 盡量讓舊接口調(diào)用新接口。當(dāng)要修改某個(gè)函數(shù)名稱時(shí),留下舊函數(shù),讓它調(diào)用新函數(shù)。千萬不要拷貝函數(shù)實(shí)現(xiàn)碼,那會(huì)陷入重復(fù)代碼中難以自拔。還應(yīng)該使用 Java 提供的“反對(duì)”設(shè)施,將舊接口標(biāo)記為 deprecated。這么一來調(diào)用者就會(huì)注意到它。2.5 重構(gòu)與設(shè)計(jì)兩個(gè)觀點(diǎn): 把設(shè)計(jì)看作軟件開發(fā)的關(guān)鍵環(huán)節(jié),而把編程看作只是機(jī)械式的低級(jí)勞動(dòng)。 重構(gòu)可以成為“預(yù)先設(shè)計(jì)”的替代品,根本不必做任何設(shè)計(jì),只管按照最初想法開始編碼,讓代碼有效運(yùn)作,然后再將它重構(gòu)成型 重構(gòu)改變了預(yù)先設(shè)計(jì)的角色。 如果沒有重構(gòu),就必須保證“預(yù)先設(shè)計(jì)”正確無誤,這個(gè)壓力太大。這意味如果將來需要對(duì)原始設(shè)計(jì)做任何修改,代價(jià)都將非常高昂。因此

9、需要把更多時(shí)間和精力放在預(yù)先設(shè)計(jì)上,以避免日后修改。 如果選擇重構(gòu),問題的重點(diǎn)就轉(zhuǎn)變了。仍需做預(yù)先設(shè)計(jì),但是不必一定找出正確的解決方案。此刻只要得到一個(gè)足夠合理的解決方案就夠了。因?yàn)槲覀冎?,在?shí)現(xiàn)這個(gè)初始解決方案的時(shí)候,對(duì)問題的理解也會(huì)逐漸加深,可能會(huì)察覺最佳解決方案和當(dāng)初設(shè)想的有些不同。只要有重構(gòu),就不成問題,因?yàn)橹貥?gòu)讓日后的修改成本不再高昂。2.6 重構(gòu)與性能 時(shí)間預(yù)算法 通常只用于性能要求極高的實(shí)時(shí)系統(tǒng)。分解設(shè)計(jì)時(shí)要做好預(yù)算,給每個(gè)組件預(yù)先分配一定資源,包括時(shí)間和執(zhí)行軌跡。每個(gè)組件絕對(duì)不能超出自己的預(yù)算,就算擁有可在不同組件之間調(diào)度預(yù)配時(shí)間的機(jī)制也不行。 這種方法高度重視性能,對(duì)于心律調(diào)節(jié)器一類的系統(tǒng)是必須的,因?yàn)樵谶@樣的系統(tǒng)中遲來的數(shù)據(jù)就是錯(cuò)誤的數(shù)據(jù)。但對(duì)其他類系統(tǒng)(例如經(jīng)常開發(fā)的企業(yè)信息系統(tǒng))而言,不必如此追求高性能。 編寫快速軟件方法:首先寫出可調(diào)軟件,然后調(diào)整它以求獲得足夠速度。 持續(xù)關(guān)切法 要求任何程序員在任何時(shí)間做任何事時(shí),都要設(shè)法保持系統(tǒng)的高性能。 這種方式很常見,感覺上很有吸引力,但通常不會(huì)起太大作用。任何修改如果是為了提高性能,通常會(huì)使程序難以維護(hù),因而減緩開發(fā)速度。如果最終得到的軟件的確更快了,那么這點(diǎn)損失尚有所值,可惜通常事與愿違,因?yàn)樾阅芨纳埔坏┍环稚⒌匠绦蚋鹘锹?,每次改善都只不過是從對(duì)程序行為的一個(gè)狹隘

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論