日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

软件配置管理(五)常用重构技巧

發(fā)布時間:2023/12/4 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 软件配置管理(五)常用重构技巧 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、重新組織函數(shù)
    • 1.提煉函數(shù)
    • 2.內(nèi)聯(lián)函數(shù)
    • 3.內(nèi)聯(lián)臨時變量
    • 4.以查詢?nèi)〈R時變量
    • 5.引入解釋性變量
    • 6.分解臨時變量
    • 7.移除對參數(shù)的賦值
    • 8.以函數(shù)對象取代函數(shù)
    • 9.替換算法
  • 二、在對象之間搬移特性
    • 1.搬移函數(shù)
    • 2.搬移字段
    • 3.提煉類
    • 4.將類內(nèi)聯(lián)化
    • 5.隱藏“委托關(guān)系”
    • 6.移除中間人
    • 7.引入外加函數(shù)
    • 8.引入本地擴展
  • 三、重新組織數(shù)據(jù)
    • 1.自封裝字段
    • 2.以對象取代數(shù)據(jù)值
    • 3.將值對象改為引用對象
    • 4.將引用對象改為值對象
    • 5.以對象取代數(shù)組
    • 6.復(fù)制“被監(jiān)視的數(shù)據(jù)”
    • 7.將單向關(guān)聯(lián)改為雙向關(guān)聯(lián)
    • 8.將雙向關(guān)聯(lián)改為單向關(guān)聯(lián)
    • 9.以字面常量取代魔法數(shù)
    • 10.封裝字段
    • 11.封裝集合
    • 12.以數(shù)據(jù)類取代記錄
    • 13.以類取代類型🐎
    • 14.以子類取代類型🐎
    • 15.以State(狀態(tài)模式)/Strategy(策略模式)取代類型🐎
    • 16.以字段取代子類
  • 四、簡化條件表達式
    • 1.分解條件表達式
    • 2.合并條件表達式
    • 3.合并重復(fù)的條件片段
    • 4.移除控制標記
    • 5.以衛(wèi)語句取代嵌套條件表達式
    • 6.以多態(tài)取代條件表達式
    • 7.引入Null對象
    • 8.引入斷言
  • 五、 簡化函數(shù)調(diào)用
    • 1.函數(shù)改名
    • 2.添加參數(shù)
    • 3.移除參數(shù)
    • 4.將查詢函數(shù)和修改函數(shù)分離
    • 5.令函數(shù)攜帶參數(shù)
    • 6.以明確函數(shù)取代參數(shù)
    • 7.保持對象完整
    • 8.以函數(shù)取代參數(shù)
    • 9.引入?yún)?shù)對象
    • 10.移除設(shè)值函數(shù)
    • 11.隱藏函數(shù)
    • 12.以工廠函數(shù)取代構(gòu)造函數(shù)。
    • 13.封裝向下轉(zhuǎn)型
    • 14.以異常取代錯誤碼
    • 15.以測試取代異常
  • 六、處理概括關(guān)系
    • 1.字段上移
    • 2.函數(shù)上移
    • 3.構(gòu)造函數(shù)本體上移
    • 4.函數(shù)下移
    • 5.字段下移
    • 6.提煉子類
    • 7.提煉超類
    • 8.提煉接口
    • 9.折疊繼承體系
    • 10.塑造模板函數(shù)。
    • 11.以委托取代繼承
    • 12.以繼承取代委托
  • 七、大型重構(gòu)
    • 1.梳理并分解繼承體系
    • 2.將過程化設(shè)計轉(zhuǎn)化為對象設(shè)計
    • 3.將領(lǐng)域和表述/顯示分離
    • 4.提煉繼承體系

一、重新組織函數(shù)

1.提煉函數(shù)

將一段代碼組織并獨立出來,放進一個獨立函數(shù)中,并讓函數(shù)名稱解釋用途。

2.內(nèi)聯(lián)函數(shù)

若一個函數(shù)的函數(shù)體足以解釋函數(shù)作用,其解釋性與函數(shù)名稱相差無幾。那么可以移除函數(shù),將函數(shù)體插入函數(shù)調(diào)用點。

3.內(nèi)聯(lián)臨時變量

若一個臨時變量只被一個簡單的表達式賦值一次,且這個變量妨礙了其他的重構(gòu)手段。那么可以將所有對該變量的引用替換為表達式本身。

4.以查詢?nèi)〈R時變量

若在一個函數(shù)中,一個表達式的運算結(jié)果被賦值給了一個臨時變量,而大量的臨時變量會導(dǎo)致理解性變差,而且臨時變量無法被其他函數(shù)使用。此時可以把表達式獨立為一個函數(shù)(稱為查詢式),并將所有臨時變量的引用替換為對函數(shù)的調(diào)用。

5.引入解釋性變量

在復(fù)雜的表達式中,可以將表達式的中間結(jié)果賦給一個臨時變量,用變量名解釋表達式的用途。

6.分解臨時變量

在一段程序中,某個臨時變量被多次賦值,但每次賦值的原因都不同(既不是循環(huán)變量,也不是用來收集計算結(jié)果的變量)。此時可以針對每次賦值都創(chuàng)造一個獨立的臨時變量,增強解釋性。

7.移除對參數(shù)的賦值

不要對函數(shù)的參數(shù)進行賦值,用臨時變量取代被重新賦值的參數(shù)。

8.以函數(shù)對象取代函數(shù)

只要將相對獨立的代碼從大函數(shù)提煉出來,就可以大大提高代碼的可讀性。但局部變量(臨時變量)的存在會增加函數(shù)分解的難度。如果一個函數(shù)中的局部變量泛濫成災(zāi),那么想分解這個函數(shù)是非常困難的。“以查詢替換臨時變量”手法可以幫助減輕負擔,但有時候還是會發(fā)現(xiàn)根本無法拆解一個需要拆解的函數(shù)。這種情況就應(yīng)該考慮使用函數(shù)對象來解決。

在一個大型函數(shù)中,臨時變量的使用導(dǎo)致無法提煉函數(shù),此時可以將這個函數(shù)放進一個單獨的對象中,將臨時變量作為對象的成員變量,這樣就可以將新對象中的大型函數(shù)分解。

示例代碼

9.替換算法

在一個函數(shù)體內(nèi),將某個算法替換為另一個算法。

二、在對象之間搬移特性

1.搬移函數(shù)

在一個類中的某個函數(shù)相較于所在類,其與另一個類有著更加多的聯(lián)系(依戀情結(jié))。可以在其所依戀的類中建立一個有類似行為的新函數(shù),將舊函數(shù)變成一個委托函數(shù),或直接移除。

2.搬移字段

在一個類中的某個字段相較于所在類,其與另一個類有著更加多的聯(lián)系。可以在其目標類中新建一個字段,并將對舊字段的引用轉(zhuǎn)移到新字段中。

3.提煉類

若一個類不符合單一職責原則,那么可以新建一個類,并將相關(guān)的字段和函數(shù)轉(zhuǎn)移。

4.將類內(nèi)聯(lián)化

若一個類的職責過小,那么可以將這個類中的所有字段和函數(shù)轉(zhuǎn)移到另一個類中,并移除原類。

5.隱藏“委托關(guān)系”

“封裝”意味每個對象都應(yīng)該盡可能少了解系統(tǒng)的其他部分。

如果某個客戶先通過委托類的字段得到另一個對象,然后調(diào)用后者的函數(shù),那么客戶必須知曉這一層委托關(guān)系。萬一委托關(guān)系發(fā)生變化,客戶也得相應(yīng)變化。
可以在服務(wù)對象上放置一個簡單的委托函數(shù),將委托關(guān)系隱藏起來,從而去除這種依賴。這么一來,即便將來發(fā)生委托關(guān)系上的關(guān)系,變化也將被限制在服務(wù)對象中,不會涉及客戶。
示例代碼

6.移除中間人

在“隱藏委托關(guān)系”中,談到了“封裝受托對象的好處”。但是這層封裝是需要付出代價的:每當客戶要使用受托類的新特性時,你就必須在服務(wù)器端添加一個簡單委托函數(shù)。但是,隨著受托類的特性越來越多,這一過程就會讓你變得痛苦。

這時,服務(wù)類做了過多的簡單委托動作,完全變成了一個“中間人”,應(yīng)該讓客戶直接調(diào)用受托類。

該手法和“隱藏委托關(guān)系”正好相反,正是由于相反,才能夠在實際的應(yīng)用中進行靈活的變通。可能一些委托關(guān)系需要保留,而另一些卻需要移除,讓客戶直接使用受托對象。這些都是可以隨之變通的。

7.引入外加函數(shù)

你正在使用一個類,它真的很好,為你提供了需要的所有服務(wù)。
而后,你又需要一項新服務(wù),這個類卻無法供應(yīng)。于是你開始咒罵“為什么不能做這件事?”如果可以修改源碼,你便可以自行添加一個新函數(shù);

若無法修改此類的源代碼(不完美的庫類),此時可以在客戶端建立一個函數(shù),并在第一個參數(shù)傳入服務(wù)類的實例 示例代碼

適配器模式也可完成這個任務(wù),但會增加一個額外的類。

8.引入本地擴展

我們都無法預(yù)知一個類的未來,它們常常無法為你預(yù)先準備一些有用的函數(shù)。如果可以修改源碼,那就太好了,那樣就可以直接加入自己需要的函數(shù)。但是你經(jīng)常無法修改源碼。如果只是需要一兩個函數(shù),可以引入外加函數(shù)進行處理。但如果需要多個函數(shù),外加函數(shù)就很難控制它們了。

所以,需要將這些額外函數(shù)組織起來,放到一個恰當?shù)牡胤饺ァR_到這樣的目的,需要用到子類化(適配器模式)和包裝(裝飾器模式)這兩種技術(shù)。這種情況下,把子類或包裝類統(tǒng)稱為本地擴展。

三、重新組織數(shù)據(jù)

1.自封裝字段

不要直接訪問類中的成員變量(字段),這會增大耦合。為這些字段創(chuàng)造getter和setter方法,且自能用這些方法訪問字段。

2.以對象取代數(shù)據(jù)值

開發(fā)初期,我們以簡單的數(shù)據(jù)項表示簡單的情況。但是隨著開發(fā)的進行,你可能會發(fā)現(xiàn),這些簡單數(shù)據(jù)項不再那么簡單了。比如說,一開始你可能會用一個字符串來表示“電話號碼”概念,但是隨后就會發(fā)現(xiàn),電話號碼需要“格式化”、“抽取區(qū)號”之類的特殊行為。如果這樣的數(shù)據(jù)有一兩個,還可以把相關(guān)函數(shù)放進數(shù)據(jù)項所屬的對象里;但是Duplicate Code(重復(fù)代碼)壞味道和Feature Envy(依戀情結(jié))壞味道很快就會從代碼中散發(fā)出來。

當這些壞味道開始出現(xiàn),就應(yīng)該將數(shù)據(jù)值變成對象。

3.將值對象改為引用對象

系統(tǒng)中的對象可以分為引用對象和值對象.
引用對象每個對象代表真實世界的一個實物,你可以直接以“==”檢查兩個對象是否相等。
值對象像是“錢”、“日期”這樣的東西,它們完全由其所含的數(shù)據(jù)值來定義,你并不在意副本的存在。值對象有一個非常重要的特性,它們應(yīng)該是不可變的

有時候,你會從一個簡單的值對象開始,在其中保存少量的不可修改的數(shù)據(jù)。而后,你可能會希望給這個對象加入一些可修改數(shù)據(jù),并確保對任何一個對象的修改都能影響到所有引用此一對象的地方,這時候,你就希望將這個對象變?yōu)橐粋€引用對象。

4.將引用對象改為值對象

若一個引用對象很小,且確定其是不可變的,那么可以將其變?yōu)橹祵ο?#xff0c;方便管理。

5.以對象取代數(shù)組

若一個數(shù)組中的各個元素代表不同的東西,那么將這個數(shù)組替換為對象,使用成員變量標識數(shù)組的不同元素。

6.復(fù)制“被監(jiān)視的數(shù)據(jù)”

一個分層良好的系統(tǒng),應(yīng)該將處理用戶界面(GUI)和處理業(yè)務(wù)邏輯(Business Logic)的代碼分開。

若一些領(lǐng)域數(shù)據(jù)存在GUI里,而業(yè)務(wù)邏輯函數(shù)需要訪問這些數(shù)據(jù)。此時可以將這些數(shù)據(jù)復(fù)制到一個領(lǐng)域?qū)ο笾?#xff0c;并用觀察者模式同步領(lǐng)域?qū)ο蠛虶UI對象的重復(fù)數(shù)據(jù)。

7.將單向關(guān)聯(lián)改為雙向關(guān)聯(lián)

若兩個類都需要使用對方的屬性,但其中只有一條單向連接。此時可以添加一個方向指針,并使修改雙方關(guān)系的函數(shù)同時更新這兩條連接。

8.將雙向關(guān)聯(lián)改為單向關(guān)聯(lián)

在擁有雙向關(guān)聯(lián)的兩個類間,當其中一個類不再需要另一個類的特性使,可以去除不必要的關(guān)聯(lián)。

9.以字面常量取代魔法數(shù)

若一個字面常量帶有特殊含義,此時可以創(chuàng)造一個常量,賦值為字面常量,并使用有意義的變量名。

10.封裝字段

將public字段聲明為private并提供訪問函數(shù)。

11.封裝集合

在函數(shù)返回集合時,讓函數(shù)返回這個集合的只讀副本,并提供修改集合元素的函數(shù)。
示例代碼

12.以數(shù)據(jù)類取代記錄

記錄型結(jié)構(gòu)是許多編程環(huán)境的共同性質(zhì)。有一些理由使它們被帶進面向?qū)ο蟪绦蛑?#xff1a;你可能面對的是一個遺留程序,也可能需要通過一個傳統(tǒng)API來與記錄結(jié)構(gòu)交流,或是處理從數(shù)據(jù)庫讀出的記錄。這些時候你就有必要創(chuàng)建一個接口類,用以處理這些外來數(shù)據(jù)。最簡單的做法就是先建立一個看起來類似外部記錄的類,以便日后將某些字段和函數(shù)搬移到這個類中。

新建一個類(“啞”數(shù)據(jù)對象),表示這個記錄。對應(yīng)記錄中的每一項數(shù)據(jù),在新建的類中建立對應(yīng)的一個private字段。并提供相應(yīng)的取值/設(shè)值函數(shù)。

13.以類取代類型🐎

若一個類有一個不影響類行為的類型碼,可以以一個新的類替換這個數(shù)值類型碼。

在使用Replace Type Code with Class (以類取代類型碼)之前,你應(yīng)該先考慮類型碼的其他替換方式。
只有當類型碼是純粹數(shù)據(jù)時(也就是類型碼不會在switch語句中引起行為變化時),你才能以類來取代它。
更重要的是:任何switch語句都應(yīng)該運用Replace Conditional with Polymorphism (以多態(tài)取代條件表達式)去掉。
為了進行那樣的重構(gòu),你首先必須運用 Replace Type Code with Subclass (以子類取代類型碼)或Replace Type Code with State/Strategy (以狀態(tài)策略取代類型碼),把類型碼處理掉。

14.以子類取代類型🐎

若一個類有一個會影響類行為的類型碼,可以以一個子類取代這個類型碼。
示例代碼

15.以State(狀態(tài)模式)/Strategy(策略模式)取代類型🐎

若一個類有一個會影響行為的類型碼,但無法通過繼承消除它(類型碼的值在對象生命期中發(fā)生變化或其他原因使得宿主類不能被繼承),此時可以用狀態(tài)對象或具體策略對象取代類型碼。

16.以字段取代子類

若一個類的各個子類間唯一的差別只在“返回常量數(shù)據(jù)”的函數(shù)身上,此時可以修改這些函數(shù),是它們返回超類的某個(新增)字段,然后銷毀子類。

建立子類的目的是為了增加新特性或變化父類行為,如果其帶來的影響只是返回的數(shù)據(jù)值不同,就沒有存在的必要

四、簡化條件表達式

1.分解條件表達式

若一個條件表達式過于復(fù)雜,可以將if-then-else三個段落分別提煉獨立的函數(shù)。

2.合并條件表達式

若在并列的條件表達式中,它們的then語句有相同操作,可以用邏輯與和邏輯或語句將各條件中的if語句聯(lián)立,并將then語句合并。

合并后的條件代碼會告訴你“實際上只有一次條件檢查,只不過有多個并列條件需要檢查而已”,從而使這一次檢查的用意更清晰。
其次,這項重構(gòu)往往可以為你使用“提取方法”做好準備。

3.合并重復(fù)的條件片段

若在條件表達式的每個分支上有相同的代碼,此時可以將這段重復(fù)代碼搬移到條件表達式之外。

4.移除控制標記

若在一系列布爾表達式中,某個變量帶有控制標記的作用,可以用break、continue和return語句取代控制標記。

5.以衛(wèi)語句取代嵌套條件表達式

條件表達式通常有2種表現(xiàn)形式。第一:所有分支都屬于正常行為。第二:條件表達式提供的答案中只有一種是正常行為,其他都是不常見的情況。
這2類條件表達式有不同的用途。如果2條分支都是正常行為,就應(yīng)該使用形如if……else……的條件表達式;

如果某個條件極其罕見,就應(yīng)該單獨檢查該條件,并在該條件為真時立刻從函數(shù)中返回。這樣的單獨檢查常常被稱為“衛(wèi)語句”。

給某個分支以特別的重視。它告訴閱讀者:這種情況很罕見,如果它真的發(fā)生了,請做一些必要的整理工作,然后退出。

6.以多態(tài)取代條件表達式

若一個條件表達式根據(jù)對象類型的不同而選擇不同的行為,此時應(yīng)將條件表達式的每個分支拆分為一個子類內(nèi)的override函數(shù)中,然后將原始函數(shù)聲明為抽象函數(shù)。

7.引入Null對象

將null值替換為null對象,這樣就不用在每一個引用處判斷對象是否為空。
示例代碼

8.引入斷言

為一段需要對程序狀態(tài)做出某種假設(shè)的代碼添加斷言,以明確表現(xiàn)這種假設(shè)。

五、 簡化函數(shù)調(diào)用

1.函數(shù)改名

修改那些不能明確揭示函數(shù)用途的函數(shù)名稱。

2.添加參數(shù)

但某個函數(shù)需要從調(diào)用端獲得更多信息時,為這個函數(shù)添加一個對象參數(shù),讓該對象帶進函數(shù)所需信息。

除了添加參數(shù)外,你常常還有其他選擇。只要可能,其他選擇都比添加參數(shù)要好,因為它們不會增加參數(shù)列的長度。過長的參數(shù)列是不好的味道,因為程序員很難記住那么多參數(shù)而且長參數(shù)列往往伴隨著壞味道:數(shù)據(jù)泥團(Data Clumps)。

3.移除參數(shù)

移除函數(shù)體不再用到的參數(shù)。

4.將查詢函數(shù)和修改函數(shù)分離

將既返回對象狀態(tài)值,又能修改對象狀態(tài)的函數(shù)分離為兩個函數(shù),一個負責查詢,一個負責修改。

5.令函數(shù)攜帶參數(shù)

若兩個任務(wù)類似的函數(shù),只因少數(shù)幾個值使行為略為不同,這種情況下,可以建立單一的函數(shù),并通過參數(shù)來處理那些變化,用以簡化問題,去除重復(fù)代碼,并提高靈活性。

6.以明確函數(shù)取代參數(shù)

若一個函數(shù)完全取決于參數(shù)值而采取不同的行為,可以針對參數(shù)的每一個可能值建立一個單獨的函數(shù)。

7.保持對象完整

若函數(shù)參數(shù)是某個對象中的若干字段,此時可以改為傳遞整個對象。

8.以函數(shù)取代參數(shù)

如果函數(shù)可以通過其他途徑獲得參數(shù)值,那么它就不應(yīng)該通過參數(shù)取得該值。

如果對象調(diào)用了某個函數(shù),并將這個函數(shù)的返回值作為參數(shù)傳遞給另一個參數(shù),但后者其實可以直接調(diào)用前者,這時應(yīng)讓后者在函數(shù)體中直接調(diào)用前者,并獲取前者返回值,而不需要使用參數(shù)傳遞。

9.引入?yún)?shù)對象

若某些參數(shù)總是同時出現(xiàn),則可以以一個對象取代這些參數(shù)。

10.移除設(shè)值函數(shù)

若類中某個字段只在對象被創(chuàng)建時被設(shè)值,之后不再改變,則應(yīng)去掉該字段的setter函數(shù)

11.隱藏函數(shù)

如果一個函數(shù)從來沒有被其他類用到,那么應(yīng)將這個函數(shù)修改為privete。

12.以工廠函數(shù)取代構(gòu)造函數(shù)。

如果創(chuàng)建對象時不僅僅要做簡單的構(gòu)建動作,那么應(yīng)將構(gòu)造函數(shù)替換為工廠函數(shù)。

13.封裝向下轉(zhuǎn)型

向下轉(zhuǎn)型也許是無法避免的,但你仍然應(yīng)該盡可能少做。如果你的某個函數(shù)返回一個值,并且你知道所返回的對象類型比函數(shù)簽名所昭告的更特化,你便是在函數(shù)用戶身上強加了非必要的工作。這種情況下你不應(yīng)該要求用戶承擔向下轉(zhuǎn)型的責任,應(yīng)該盡量為他們提供準確的類型。
以上所說的情況,常會在返回迭代器或集合的函數(shù)身上發(fā)生。此時你就應(yīng)該觀察人們拿這個迭代器干什么用,然后針對性地提供專用函數(shù)。

將向下轉(zhuǎn)型的動作轉(zhuǎn)移到函數(shù)體中,而不是讓用戶完成這個動作。

14.以異常取代錯誤碼

對于一個成員方法而言,它要么執(zhí)行成功,要么執(zhí)行失敗。成員方法執(zhí)行成功的情況很容易理解,但如果執(zhí)行失敗了卻沒有那么簡單,因為我們需要將執(zhí)行失敗的原因通知調(diào)用者。拋出異常和返回錯誤代碼都是用來通知調(diào)用者的手段
當我們想要告示調(diào)用者更多細節(jié)的時候,就需要與調(diào)用者約定更多的錯誤代碼。于是。錯誤代碼飛速膨脹,直到看起來似乎無法維護,因為我們需要查找并確認錯誤代碼。
使用了CLR異常機制后,代碼更加清晰,易于理解。
而在某些情況下,錯誤代碼將無用武之地,如構(gòu)造函數(shù)、操作符重載及屬性。語法的特性決定了其不具備任何返回值,于是異常處理被當做取代錯誤代碼的首要選擇。

將函數(shù)返回錯誤碼改為使用異常。
示例代碼

15.以測試取代異常

異常只應(yīng)該被用于異常的,罕見的行為,也就是那些產(chǎn)生意料之外錯誤的行為,而不應(yīng)該成為條件檢查的替代品

如果調(diào)用者有能力在異常被拋出之前檢查拋出條件,那么應(yīng)該讓調(diào)用者在調(diào)用函數(shù)前檢查條件。
示例代碼

六、處理概括關(guān)系

1.字段上移

當兩個子類擁有相同字段時,將該字段移至超類。

2.函數(shù)上移

當函數(shù)在各個子類產(chǎn)生完全相同的結(jié)果時,將該函數(shù)移至超類。

3.構(gòu)造函數(shù)本體上移

當各個子類中的構(gòu)造函數(shù)幾乎完全移至時,在超類新建一個構(gòu)造函數(shù),并在子類構(gòu)造函數(shù)中調(diào)用它。

4.函數(shù)下移

當超類的某個函數(shù)只與部分子類有關(guān)時,將這個函數(shù)移到相關(guān)子類中。

5.字段下移

當超類中的某個字段只被部分子類用到時,將這個字段移到需要它的子類中。

6.提煉子類

當類中某些特性只被部分實例用到時,新建一個子類,將那部分特性移到子類中。

Extract Class(提煉類)是Extract Subclass之外的另一種選擇,兩者之間的抉擇其實就是委托和繼承之間的抉擇。Extract Subclass通常更容易進行,但它也有限制:一旦對象創(chuàng)建完成,你無法再改變與類型相關(guān)的行為。此外,子類只能用以表現(xiàn)一組變化。如果你希望一個類以幾種不同的方式變化,就必須使用委托。

7.提煉超類

當兩個類有相似特性時,為這兩個類建立一個超類,將相同特性移至超類中。

8.提煉接口

如果若干用戶使用類中相同的特殊方法,或兩個類的方法有部分相同,可以將相同方法提煉到一個接口中,并讓這些類實現(xiàn)接口。
實例代碼

9.折疊繼承體系

如果超類和子類沒有太大區(qū)別,那么將他們合為一體。

10.塑造模板函數(shù)。

如果一些子類中相應(yīng)的某些函數(shù)以相同順序執(zhí)行類似的操作,但操作細節(jié)在不同子類間有所不同。這時可以將子類中對應(yīng)函數(shù)修改為相同的函數(shù)名,并在超類中創(chuàng)建對應(yīng)的被重寫的函數(shù),最后在超類中創(chuàng)建一個新的函數(shù),按順序執(zhí)行這些函數(shù)完成操作。
實例代碼

11.以委托取代繼承

如果某個子類只是用了超類的一部分接口,或者沒有使用超類的數(shù)據(jù),那么應(yīng)去除繼承關(guān)系,轉(zhuǎn)而在子類中新建一個持有超類的字段,并調(diào)整子類函數(shù),改為委托超類。
代碼示例

12.以繼承取代委托

如果在兩個類中使用委托關(guān)系會導(dǎo)致編寫許多極簡單的委托函數(shù),這時應(yīng)考慮讓委托類繼承受托類。

七、大型重構(gòu)

1.梳理并分解繼承體系

如果某個繼承體系同時承擔兩項責任,這時應(yīng)建立兩個繼承體系,并通過委托關(guān)系使其中一個調(diào)用另一個。

2.將過程化設(shè)計轉(zhuǎn)化為對象設(shè)計

針對以傳統(tǒng)過程化分隔編寫的代碼,將它的數(shù)據(jù)記錄變成對象,將大塊行為分成小塊并移入相關(guān)對象中。

3.將領(lǐng)域和表述/顯示分離

如果某些GUI類包含了領(lǐng)域邏輯,那么應(yīng)將領(lǐng)域邏輯分離出來,建立單獨的領(lǐng)域類。

4.提煉繼承體系

如果某個類做了太多的、以大量條件表達式完成的工作,那么應(yīng)建立繼承體系,以一個子類表示其中的一種特殊情況。

總結(jié)

以上是生活随笔為你收集整理的软件配置管理(五)常用重构技巧的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。