重構整理(二) 在物件之間搬移特性

2021-09-24 15:44:02 字數 2538 閱讀 3468

在物件導向的程式設計中,把責任放在哪幾乎是最重要的事情之一。在我寫**的時候,唯有當寫完了,才會發現初期思考的設計在責任分配上還是有問題。相信沒有多少人就能保證不出錯,這時候我們就需要重構,將責任和特性進行搬移。這一部分作者就主要講了於此相關的重構手法。

1.move method(搬移函式)

原文解釋的非常好,清晰易懂:

例子,有乙個賬戶類。

class account 

double overdraftcharge()

else

}

假設每一種賬戶都有自己的「透支金額計費規則」,這時候上面這個方法則應該放到accounttype類裡去。那首先得觀察每乙個特性和字段是否要跟著方法一起移動。在這個例子裡,_daysoverdrawn會隨著不同型別的賬戶而變化,那麼它則應該是賬戶的特性,所以這裡應該保留這個字段。

移到另外乙個類的時候假如有欄位需要保留在舊類,那麼則需要注意,如果是乙個,則可以當作引數傳遞,否則需要在兩者之間建立一種引用關係。

2.move field(搬移字段)

當乙個類的某個欄位被另乙個類更多的用到,則需要把這個欄位移到那個類去。當欄位搬移以後,舊類中數個對其的引用則會報錯,那麼舊類則需要有這個欄位的引用,這裡可以使用c#的屬性機制也可以寫類似get set的方法。

另外,當我們搬移以後乙個個去修改可能會不太方便,這時候可以使用selfencapsulatefield(自我封裝,應該是作者在後文會說到)。什麼意思呢,就是可以先把要轉移的字段進行一層封裝變成屬性或者方法統一引用的指向,轉移之後就只需要更改屬性或者方法中的實際關聯操作了。

3.extract class(提煉類)

有時候我們會因為需求的增加而不斷擴張類。但是某個地方你覺得又不值得為它分離出乙個單獨的類,那麼慢慢地這個類就會變得非常亂。而這種情況下,我們就要根據自己的分析來判斷哪些是需要提煉出去的。

這個就不用舉例了,只要配合上面的move method和move field來將相關特性也一併搬移出去。

另外搬移後的類究竟要設定乙個什麼樣的公開性是值得考慮的,比如c#中我們可以將新類作為舊類的內部類,或者私有的並且只被舊類訪問。具體還是看情況而定。     

4.inline class(將類內聯化)

當乙個類不再承擔足夠的責任,可以選擇將其內聯到使用它最多的使用者類去。

5.hide delegate(隱藏委託關係)

這種方法的定義是 在服務類上建立客戶所需的所有函式,用以隱藏委託關係。單看定義很難理解,甚至可能會想到c#中的委託,現在來看個書中的例子:

class person

public void setdepartment(department arg)

}class department

public person getmanager()

...}

像上面這樣,我們要知道乙個人的部門經理,就得 person.getdepartment).getmanager().客戶這樣呼叫就說明他已經知道了這一層工作原理,得通過department物件來訪問某人的經理。但是假如我們在person類中建立乙個簡單的委託函式: 

public person getmanager()

此時,person類就成了個服務物件,所有的修改都可以只在它之中完成,這樣即使實現細節改變,客戶中依然是通過person.getmanager()來訪問,去除了之前必須訪問department的依賴。

6.remove middle man(移除中間人)

上面是通過新增委託函式來封裝一些實現細節,但是問題在於,假如受託類的特性功能越來越多,那每新增乙個特性,就要增加乙個受託函式,服務類完全變成了乙個中間人,此時就應該讓客戶直接呼叫受託類。很難說什麼程度才算是最合適的,但是我們只要發現問題去修改就好了。

這裡這個方法的實現細節就是把上面方法的操作去掉就好了。

7.introduce foreign method(引入外加函式)

當乙個類可以為你提供需要的服務,而隨後你又需要乙個新服務它卻無法**,這時候你假如客戶端幫助這個類實現了這個業務,那麼其他的地方則無法使用。所以這裡可以通過類似c#擴充套件方法的方式,為這個類補足業務。

但當乙個服務類建立了大量外加函式,或者發現許多類都需要同樣的外加函式,就不應該使用這個方法,而使用下面這個introduce local extension。

8.introduce local extension(引入本地擴充套件)

這種方式其實就是單獨建立乙個新的類作為某個類的擴充套件類。裡面包含的是這個類的擴充套件方法。在c#中,這樣應該很常見了。

重構 在物件之間搬移特性

1 move method 搬移函式 有個函式與所在類之外的另乙個類進行更多的交流 呼叫或被呼叫 在該函式最常引用的類中建立乙個有著類似行為的新函式。將舊函式變為乙個單純的委託函式,或者將舊函式刪除。2 move field 搬移字段 某個欄位被其所屬類之外的另乙個類頻繁呼叫。3 extract c...

重構 在物件之間搬移特性

你的程式中,有個函式與其所駐類之外的另乙個類進行更多交流 呼叫後者,或被後者呼叫 則在該函式最常引用的類中建立乙個有著類似行為的新函式,將舊函式變成乙個單純的委託函式,或是將舊函式完全移除。動機 如果乙個類有太多行為,或如果乙個類與另乙個類有太多合作而形成高度耦合,就使用搬移函式,通過這種手段,可以...

重構之在物件之間搬移特性

1.move method 搬移函式 你的程式中,有個函式與其所駐 class 之外的另乙個 class 2.move field 搬移值域 在 target class 建立乙個 new field 修改source field 的所有使用者,令它們改用 new field。3.extract c...