September 13 20:30~22:07
前言
上一集<重構既有系統,邁向整潔架構 (2):逆轉重構流程>Teddy提到只要「大膽假設」不管你是開發什麼系統,就是要套用Clean Architecture就對了。如此一來,便可將重構從「由下而上」的設計方法轉變成「由上而下」的設計過程。
接下來這幾集,Teddy將以Task List Kata為例,說明如何將既有系統的架構重構成Clean Architecture。
***
Task List Kata介紹
Task List Kata是一個公開的重構練習,程式碼可參考:https://kata-log.rocks/task-list-kata。如圖1所示,它有8種不同的語言版本,Teddy使用Java版本。
▲圖1:Task List Kata支援的語言
如圖2所示,Teddy將Task List Kata複製到自己的repository,並將package name改成tw.teddysoft.tasks。
▲圖2:Task List Kata專案目錄
Task List Kata原本只有三支程:
- Task:參考圖3,這是一支只有不到30行的程式,很簡單,好像沒什麼需要重構。
- TaskList:參考圖4、圖5,這是一支約150行的程式,看起來很亂,感覺是重構的重點。
- ApplicationTest︰整合測試,當重構進行時可以執行這個測試案例確定沒有感變舊有的程式行為。
▲圖3:Task.java程式碼
▲圖4:TaskList.java程式碼, 1/2
▲圖5:TaskList.java程式碼, 2/2
***
鄉民們怎麼重構
首先,了解需求。Task List Taka的介紹網頁提到 (用ChatGPT翻譯成中文):
***
任務清單
這是一個對基元(primitives)過度依賴的程式範例。
基元是任何具有技術性質且與您的業務領域無關的概念。這包括整數、字符、字串和集合(列表、集合、映射等),還有執行緒、讀取器、寫入器、解析器、異常處理等任何純粹專注於技術問題的事物。相比之下,這個專案中的業務概念,如「任務」、「專案」等,應被視為您領域模型的一部分。領域模型是您所運營的業務的語言,將其應用於代碼庫有助於避免使用不同的語言,從而幫助避免誤解。根據我們的經驗,誤解是造成漏洞的最大原因。
練習
嘗試實現以下功能,同時逐步重構以去除基元。在完全重構代碼以移除基元之前,儘量不要實現任何新行為,也就是說,只有在您即將更改的代碼已被重構後,才進行變更。不要重構無關的代碼。
一組判斷基元是否已移除的標準是,只允許基元出現在構造函數的參數列表、本地變量和私有字段中。基元不應該被傳遞給方法或從方法中返回。唯一的例外是基礎設施代碼——與終端、網絡、資料庫等進行通信的代碼。基礎設施需要將數據序列化為基元,但應視為特殊情況處理。您甚至可以將基礎設施視為一個獨立的領域,具有技術性質,其中基元是該領域的核心概念。
您應該嘗試將測試包圍在您正在重構的行為周圍。一開始,這些測試大多是高級系統測試,但隨著進展,您應該會撰寫更多的單元測試。
***
上述說明已經提示了重構方向:「優先考慮去除primitives」,也就是去除重構中提到Primitive Obsession(基本型別依戀)壞味道。但是一般人看到這個練習,直覺的想法是:「把大的拆成小的」。很多人會先把TaskList的private methods像是show、add、setDone、help、error等「座艙升等」,各自變成一個class,並套用Command設計模式,讓execute可以執行不同的命令。
接著,為了產生這些不同的命令,又套了Simple Factory。然後呢…….嗯,就沒有然後了。此時TaskList程式長度剩下原本的1/3,抽離出來的Command也符合單一責任原則,程式碼也很短,感覺好像沒什麼明顯地方需要重構了。
***
換你想
在正式談Teddy如何重構Task List Kata之前,請鄉民們也想想看,如果是你,你會如何重構?
***
工商服務
想了解本系列文章完整內容,請參考【重構既有系統:邁向整潔架構實作班】。課程介紹與報名網址在此:https://teddysoft.tw/courses/refactor-to-ca/。
***
友藏內心獨白:搞錯順序只會徒然浪費時間。
沒有留言:
張貼留言