《重構》讀書筆記之資料重構

2021-09-01 11:00:27 字數 3438 閱讀 8917

1. self encapsulate field 自封裝字段

為字段建立setter/getter,並且只以這些函式來訪問字段

做法:為待封裝字段建立取值/設定函式

找出該字段的所有引用點,將他們全部改為呼叫取值/設值函式

將該字段宣告為private

複查,確保找出所有引用點

編譯測試

2. replace data value with object 以物件取代資料值

有乙個資料項,需要與其他資料和行為一起使用才有意義

做法:為待替換數值新建乙個類,在其中宣告乙個final欄位,其型別和源類中的待替換數值型別一樣,然後在新類中加入這個欄位的取值函式,再加上乙個接受此字段為引數的建構函式

編譯將源類中的待替換數值字段的型別改為前面新建的類

修改源類中該字段的取值函式,令它呼叫新類的取值函式

如果源類建構函式中用到這個待替換字段(多半是賦值動作),我們就修改建構函式,令它改用新類的建構函式來對字段進行賦值動作

修改源類中待替換欄位的設定函式,令它為新類建立乙個例項

編譯測試

現在,你有可能需要新類使用change value to refrence

3. change value to reference 將值物件改為引用物件

從乙個類衍生出許多彼此相等的例項,比如同樣表示2010-1-1的日期物件,希望將他們替換為同乙個物件

做法:使用 replace constructor with factory method

編譯測試

決定由什麼物件負責提供訪問新物件的途徑,可能是乙個靜態字典或乙個登錄檔物件

決定這些引用物件應該預先建立好,或是應該動態建立

修改工廠函式,令它返回引用物件

4. change reference to value

有乙個引用物件,很小且不可變,而且不易管理。這裡有必要澄清一下「不可變」的意思。如果以money類表示錢的概念,其中有「幣種」和「金額」兩條資訊,那麼money物件通常是乙個不可變的值物件。這並非意味你的薪資不能改變,而是意味:如果要改變你的薪資,就需要使用另乙個money物件來取代現有的money物件,而不是在現有的money物件上修改。

做法:檢查重構目標是否為不可變物件,或是否可修改為不可變物件

建立equals() 和 hashcode()

編譯測試

考慮是否可以刪除工廠函式,並將建構函式宣告為public

5. replace array with object 以物件取代陣列

有乙個陣列,其中的元素各自代表不同的東西。以物件替換陣列,對於陣列中的每個元素,以乙個欄位來表示

string  row = new string[3];

row[0] = "liverpool";

row[1] = "15";

performance row = new performance();

row.setname("liverpool");

row.setwins("15");

做法:

新建乙個類表示陣列所擁有的資訊,並在其中以乙個 public 字段儲存原先的陣列

修改陣列的所有使用者,讓他們改用新類的例項

編譯測試

逐一為陣列元素新增setter/getter函式。根據元素的用途,為這些訪問函式命名。修改客戶端**,讓他們通過訪問函式取用陣列內的元素,每次修改後,編譯並測試。

當所有對陣列的直接訪問都轉而呼叫訪問函式後,將新類中儲存該陣列的字段宣告為private

編譯對於陣列內的每乙個元素,在新類中建立乙個型別相當的字段。修改該元素的訪問函式,令它改用上述的新建字段。

每修改乙個元素,編譯並測試

陣列的所有元素都有了相應字段之後,刪除該陣列

6. duplicate observed data 複製」被監視資料「

一些領域資料置身於gui控制項中,而領域函式需要訪問這些資料,將該資料複製到乙個領域物件中,建立乙個observer模式,用以同步領域物件和gui物件內的重複資料。

該例比較複雜,請參考書內描述

7. change unidirectional association to bidirectional 將單向關聯改為雙向關聯

兩個類都需要使用對方特性,但其間只有一條單向連線。新增乙個反向指標,並使修改函式能夠同時更新兩條連線

做法:在被應用類中增加乙個字段,用以儲存反向指標

決定由哪個類——引用端還是被引用端——控制關聯關係。如果是」一對多「關係,那麼就由」擁有單一引用「的哪一方承擔」控制者「角色。

在被控端建立乙個輔助函式,其命名應該清楚指出它的有限用途

如果既有的修改函式在控制端,讓它負責更新反向指標

如果既有的修改函式在被控端,就在控制端建立乙個控制函式,並讓既有的修改函式呼叫這個新建的控制函式。

8. change bidirectional association to unidirectional 將雙向關聯改為單向關聯

去除不必要的關聯

做法:找出儲存」你想去除的指標「的字段,檢查它的每乙個使用者,判斷是否可以去除該指標

如果客戶使用了取值函式,先運用 self encapsulate field 將待刪除字段自我封裝起來,然後使用 substitute algorithm 對付取值函式,令它不再使用該欄位,然後編譯測試。

如果客戶並未使用取值函式,那就直接修改待刪除欄位的所有被引用點:改以其他途徑獲得該字段所儲存的物件。每次修改後,編譯並測試

如果已經沒有熱河函式使用待刪除字段,移除所有對該字段的更新邏輯,然後移除該欄位。

編譯測試

9. replace magic number with symbolic constant 以字面常量取代魔法數

建立乙個常量,根據其意義為它命名,並將上述的字面數值替換為這個常量

10. encapsulate field 封裝字段

類中存在乙個public 字段,將它宣告為private,並提供相應的訪問函式。

11. encapsulate collection 封裝集合

讓這個函式該集合的乙個唯讀副本,並在這個類中提供新增/移除集合元素的函式。

做法:加入為集合新增/移除元素的函式

將儲存集合的字段初始化為乙個空集合

編譯找出集合設值函式的所有呼叫者。你可以修改那個設值函式,讓它使用上述新建立的」新增/移除元素「函式;也可以直接修改呼叫端,改讓他們呼叫上述新建立的」新增、移除元素「函式。

編譯測試

找出所有」通過取值函式獲得集合並修改其內容「的函式,逐一修改這些函式,讓他們改用新增、移除函式。每次修改後,編譯並測試

修改完上述所有」通過取值函式獲得集合並修改集合內容「的函式後,修改取值函式自身,使它返回該集合的乙個唯讀副本。使用collection.unmodifiable***x()得到該集合的唯讀副本。

編譯測試

找出取值函式的所有使用者,從中找出應該存在於集合所屬物件內的**,運用extract method和move method將這些**移到宿主物件去

《重構》讀書筆記

再次看重構這本書,用了十幾分鐘,看完了原來斷斷續續用了差不多一周看完的第一章 沒有增加什麼新知識 僅對state stategy模式增加了點熟悉度 可見許久前學習第一章還是比較深入的,呵呵。還記得當時看得還是有點費力的。站的高度不同了,視角變化了,所以看得也快,看得也更精深。首先覺得第一章寫的真不賴...

重構讀書筆記

年前參加了軟體重構的培訓,就像老師所說,幾天的培訓不會有實質的變化,主要的目的是出發更深層次的思考和不斷的實踐,1,duplicated code,重複 是最常見,醜陋的壞味道,有以下一些解決辦法 extract method pull up method template method 這個準則最...

重構 讀書筆記

1.重構的基本原則 新增新功能和重構是兩類工作。重構時,盡量不要新增新功能,除非發現了原來程式的錯誤。其實即使發現原來的錯誤,也應該把錯誤暫時記下來,待重構完成後,再修改原來的錯誤。重構就是不修改程式對外的表現形式,哪怕原來是錯誤的。2.重構時state模式的使用 當乙個物件中的某個屬性需要改變類屬...