如果我們在程式中發現一組相關的資料總是同時出現,而且當我們拿掉其中一個資料時,會讓剩下的部分失去意義或不完整時,這就是資料團塊(Data Clumps,或稱數據泥團)的徵兆。譬如說,當我們要描述一個「點」在三維空間中的位置時,三維坐標的數值必須同時存在、缺一不可,否則這個「點」的資料就失去了意義。
這些資料團塊隨著功能新增擴充,可能會逐漸蔓延擴散到專案各處。其中也包括綁定在資料團塊之內的驗證邏輯或業務規則。例如說有一個時間區間資料,除了必須包括開始與結束兩個時間資料外,結束時間必須晚於開始時間。類似這樣的驗證邏輯也可能隨著資料團塊在專案中不斷出現,造成程式碼重複問題。
如果比較這個氣味與上一篇文章介紹的「過長參數列(Long Parameter List)」,我們可以觀察到,雖然不能說百分之百,但「過長參數列」很可能同時也符合「資料團塊」的氣味,只要這些方法中的參數總是必須同時存在才有意義。但資料團塊聚焦的不只是參數,範圍還包括物件或類別中各種變數或資料同時出現的現象。
Bloaters 氣味都有著相似的問題,具體有以下的缺點:
當我們進行到臃腫怪(Bloaters)分類中的最後一個氣味,能夠對應的重構技巧無可避免都是些熟悉的老朋友。根據對照表上列出三種重構手法,在未來我可能會按照自己的心得補上其他:
在物件導向的世界中,創造新的類別來解決問題可以說是我們的一種預設思維。每當我們發現了繁雜、大量、重複的資料與附屬的行為散落在專案各處,我們總是會思考,是否能創造出一個新的類別來做整理。
這也是為何「抽出類別(Extract Class)」這個重構技巧在臃腫怪(Bloaters)氣味的對應中反覆出現,我們可以由對照表上觀察到「Large Class」、「Primitive Obsession」中找到對應關係,甚至上一篇氣味中關於如何重構「Long Parameter List」的討論裡,雖然對照表沒有提及,但我認為抽出類別也一樣可以用來重構參數列表過長所造成的問題。
老朋友二號(?)導入參數物件首次介紹於「Long Method」重構方法一文,如果我們在參數列表發現到資料團塊,自然是可以透過這個熟悉的重構技巧。這個重構技巧同時也可以對應「Long Parameter List」與「Primitive Obsession」,與抽出類別一樣是應對臃腫怪(Bloaster)的熱門候選,只不過聚焦在參數的冗長問題。
這個技巧同時可參見於「Long Method」與「Long Parameter List」。當過長的參數列表中每一個參數都來自相同物件,此時我們自然無須新創一個物件,而是取用這個物件本身來替代長長的參數列表。
只有當這些參數共同的物件不存在時,我們才需要考慮使用「Introduce Parameter Object」或是「Extract Class」來創造新的類別或物件。
鐵人賽很快進入第十天,或可說三分之一。但按照目前文章拆分的情況看,或許總文章數會上看到四時左右,畢竟此時才終於完結第一個氣味大類,介紹了五種氣味與對應重構的技巧。
寫作過程中,首先獲得最多利益的當人是我本人。為了寫成文章免不了需要去研讀、比較,然後產生困惑,再進一步找答案。下筆之後有了新的想法,反過來去推翻前幾日的看法是家常便飯。我並不是這個領域的專家,只是一個求道者。
對於到達終點以後的視野,我相當期待。再次感謝所有讀者,如果有任何反饋意見也相當歡迎留言,希望能提供更高品質的文字輸出留在網路上,對於社群提供一些貢獻。
If deleting one of the data values would make the others meaningless, it is a sign of data clumps. When we find identical groups of variables appearing in different parts of the code, they should be turned into their own classes to avoid data clumps.
https://refactoring.guru/smells/data-clumps