重構 - 改善既有程式的設計 - Organizing Data
April 18, 2020這篇文章討論《重構 - 改善既有程式的設計》裡的第八章 - Organizing Data
主要會討論程式碼的壞味道中 沒有被提及的重構方法裡面有關於 重新組織資料 的內容
圖片以及程式碼來源自重構 - 改善既有程式的設計
重新組織資料
Replace Data Value with Object
當你有一筆資料項(data item) 需要額外的資料和行為 就把那個資料項變成一個物件
Change Value To Reference
將實質物件改為引用物件
上圖的意思 就是把一個value object轉成reference object
別激動別激動 我一開始看也是看不懂 我來說說我的理解吧
我們繼續使用Replace Data Value with Object的例子 在使用Replace Data Value with Object重構之後
每張Order
上都有一個Customer
物件而不是String
但當Order
多了之後 發現很多Customer都是同一個人(同一個名字) 但同一個人在不同的Order
物件裡面卻是不同的Customer
物件
之後管理起來會麻煩 比如顧客換名字或是換地址 就得改所有的Order
物件
你說這還不簡單 建構子跟setter裡面 傳進來Customer
物件不就得了?
這的確是把實質物件改為引用物件 但你的使用者使用起來還是很麻煩 他在創建一個新Order的時候 手上拿著customerName
你要先找出有著這個名字的Customer
物件 才能把這個物件丟進Order
的constructor
好麻煩 怎麼辦呢
我們使用Replace Constructor with Factory Method 我們就可以控制Customer的創建過程
有了create
這個靜態工廠之後 Order只要有customerName 就很好辦了
Change Reference To Value
[Change Value To Reference]的反向 如果你的reference object很小而且不可變 那就不如把它換成value object
Replace Array with Object
當你有一個陣列 其中的元素代表不同的東西 那就用物件來替換
Change Bidirectional Association to Unidirectional
如果兩個類別A,B 只有類別A需要知道類別B的特性 那就把依賴關係變成單向
Change Unidirectional Association to Bidirectional
Change Bidirectional Association to Unidirectional的反向
當兩個類別彼此需要知道對方特性 但目前只有一個方向的依賴 就把依賴變成雙向
雖然比較複雜 但卻是比較常見的use case 你會想知道每個Order
是由哪個Customer
下訂的 你當然也會想知道每個Customer
有下了哪些Order
Replace Magic Number with Symbolic Constant
為一個有意義的數值命名
把重力常數命名一下
Encapsulate Field
封裝欄位 把public的欄位變成private 並提供存取函式
Encapsulate Collection
檢查是不是對於Collections也都做好了封裝
Replace Type Code with Class
Type Code三兄弟之老大: 類別之中有一個數值型別代碼(numeric type code) 但他不影響類別的行為
Replace Type Code with Subclasses
Type Code三兄弟之老二: 當類別之中的數值型別代碼會影響類別行為的時候 就用這個方法
Replace Type Code with State/Strategy
Type Code三兄弟之老三: 當你想動態的改變類別的行為的時候 就用這個方法
Replace Subclass with Fields
你的各個subclass的差別 只差在回傳常數資料的函式 你就可以把這個函式提煉到superClass 然後移除所有subClass