← 開發日常

Clean Architecture 讀後感

Uncle Bob在2017年寫了Clean Architecture,在2018年博碩也出版了中文翻譯版,自己也趁著公司同事在團購時也一起入手了一本,但是自己卻沒在收到的時候馬上來讀,反而是最近才出來看。書一開始從語言設計的歷史開始講起,講述SOLID和元件,此時還不是很清楚這一切與架構關係,到後來談架構時才把一切串了起來,看完有一種任督二脈被打通的感覺。

SOLID

學寫Web Api的時候,會拆分Controller、Service、Repository、Model...等,會分別把Request/Response的轉換放在Controller中,Service/Model則是專注於處理商業邏輯,而Repository則是從DB取資料...等,在看這本書以前都會覺得拆分這幾個Component是為了單一職責,讓不同的物件專注於處理各自的職責。

除了單一職責之外,其實還有一個很重要原因:依賴反轉 → 高層次的模組不依賴於低層次的模組的實現細節。書中把這架構分成了四類元件,一圈一類元件,外層相依於裡層,最裡層也是最高層次的元件則不相依於任何元件,通常也是最核心的商業邏輯,最外層也最細節的元件則相依於裡層的元件,通常就是處理Request/Response或是操作DB的代碼。

Article image

商業邏輯可能會關心資料會不會被儲存,但是通常不關心資料如何被儲存,比如是存在DB或存在Memory裡。DbRepository需要知道哪些資料要被儲存,所以DbRepository會依賴於Use Cases或Entities,但是Use Cases則是不需要依賴於DbRepository,而是依賴於介面,讓外層的DbRepository去實作這個介面。

同樣的,商業邏輯可能會關心哪些資料是要給User看,但是不關心資料如何顯示給User,有可能是透過GUI顯示給User,也有可能是透過Web Api傳出去。所以ApiController會需要知道裏層,但是裏層的商業邏輯卻不需要知道Response是如何包裝這些資料。

當架構遵循著依賴反轉的原則在設計時,什麼功能的代碼要寫在哪一層就清楚了許多,這麼做的好處是當外層改動的時候不容易影響內層,代碼就比較不容易因為畫面一改,然後牽一髮而動全身。越內層元件改動的時候,則是會很大層度影響外層元件,這也表示最核心的商業邏輯改動了,所有東西包括使用者操作行為和畫面都得跟著改動。

讓測試變好寫了

越內層的元件也扮演著越重要的商業邏輯,也越需要為它寫單元測試,因為我們希望在未來新增需求或重構的時候,單元測試能即時幫我們檢測到這些邏輯是否被改壞,又剛好內層的元件相依較少,也讓單元測試變得好寫了,我們不需要Fake一大堆底層的細節,不需要Fake某個DbRepository或Request/Respone,所以越內層的元件可測試性也越高。