你從某個對象中取出若干值,將它們作為某一次函數調用時的參數。改為傳遞整個對象。
動機:有時候,你會將來自同一對象的若干項資料作為參數,傳遞給某個函數。這樣做的問題在於:萬一將來被調用函數需要新的資料項目,你就必須尋找並修改對此函數的所有調用。如果你把這些資料所屬的整個對象傳給函數,可以避免這種尷尬的處境,因為被調用函數可以向那個參數對象請求任何它想要的資訊。
除了可以使參數列更穩固外,Preserve Whole Object (保持對象完整)往往還能提高代碼的可讀性。過長的參數列很難使用,因為調用者和被調用者都必須記住這些參數的用途。此外,不使用完整對象也會造成重複代碼,因為被調用函數無法利用完整對象中的函數來計算某些中間值。
不過事情總有2面:如果你傳的是數值,被調用函數就只依賴於這些數值,而不依賴它們所屬的對象。但如果你傳遞的是整個對象,被調用函數所在的對象就需要依賴參數對象。如果這會使你的依賴結構惡化,那麼就不該使用Preserve Whole Object (保持對象完整)。
有的觀點認為:如果被調用函數只需要參數對象的其中一項數值,那麼只傳遞那個數值會更好。這個觀點不能被認同:因為傳遞一項數值和傳遞一個對象,至少在代碼清晰度上是一致的。更重要的考量應該放在對象之間的依賴關係上。
如果被調用函數使用了來自另一個對象的很多資料項目,這可能意味著該函數實際上應該被定義在那些資料所屬的對象中。所以,考慮使用Preserve Whole Object (保持對象完整)同時,你也該考慮Move Method(搬移函數)。
運用本項重構前,你可能還沒有定義一個完整對象,那麼就應該先使用Introduce Parameter Object (引入參數對象)。
還有一種常見情況:調用者將自己的若干數值作為參數,傳遞給被調用函數。這種情況下,如果該對象有合適的存取子,你可以使用this取代這些參數值,並且無需操心對象依賴問題。
做法:1、對你的目標函數新添一個參數項,用以代表原資料所在的完整對象。
2、編譯、測試。
3、判斷哪些參數可被包含在新添得完整對象中。
4、選擇上述參數之一,將被調用函數中原來引用該參數的地方,改為調用新添參數對象的相應存取子。
5、刪除該項參數。
6、編譯、測試。
7、針對所有可從完整對象中獲得的參數,重複上述過程。
8、刪除調用端中那些帶有被刪除參數的代碼。
9、編譯、測試。