August 20 20:50~22:45
背景說明
《Clean Architecture》書中有一張圖解釋Clean Architecture在網頁程式的實作,如圖1所示。
▲圖1:典型的Clean Architecture實作
Use Case Interactor定義了Input Boundary、Output Boundary以及Input Data和Output Data,這些類別與介面都位於Use Case階層。
其中Output Boundary介面由Presenter實作。Presenter位於Interface Adapters,負責產生View所需要的資料,稱為View Model。
以上分層與類別/介面的關係看起來很簡單,在撰寫程式碼時,一個Use Case對應到一組Input與Output,Input由Use Case實作,Output由Presenter實作。理論上,一個Use Case會對應到一個Presenter。
***
太多Presenter
如果完全依照圖1的方式去開發,有多少個Use Case就會有多少個Presenter與View Model。圖2是ezKanban系統關於操作Board(看板)所設計出來的多個Presenter與View Model其中,其中包含:
- addermember:加入組員
- changetitle:修改標題
- create:新增看板
- delete:刪除看板
- enter:進入看板
- get:取得看板id與名稱
- getcontent:取得整個看板的資料,包含裡面的Workflow
- leave:離開看板
▲圖2:ezKanban系統為了操作Board所設計的多個Presenter與View Model
圖3為CreateBoardViewModel、RenameBoardViewModel以及DeleteBoardViewModel的內容,長得一模一樣,都只包含boardId這個資料。
▲圖3:三個View Model內容都很像
圖4的BoardContentViewModel長得和其他人不一樣,有比較多資料。
▲圖4:BoardContentViewModel
***
區分Command和Query
Command是會修改系統狀態但不回傳資料的操作,Query是不會改變系統狀態但會回傳資料的操作。Command query separation(CQS)是由Bertrand Meyer所提出的設計方法,最早應用於他自己發明的Eiffel語言中。
Command query responsibility segregation (CQRS) 受到CQS的影響,將這個概念套用在軟體架構上。
請注意看圖2裡面關於Board的操作,可以套用CQRS的精神,將使用案例分成兩大類:
- Command:addmember、changetitle、create、delete、enter、leave
- Query:get、getcontent
套用CQRS之後理想狀況是所有的Command共用相同的Output、Presenter以及View Model。雖然理想上Command不應該回傳任何值,但實務上在分散式系統中,可以讓Command回傳有限的值,例如所產生物件的id,以及執行的結果(成功或失敗)與錯誤訊息。
▲圖5:可以給Command共用的Presenter與View Model
▲圖6:簡化後Board功能只需要兩個給Query使用的Presenter與View Model
***
友藏內心獨白:Clean Architecture + CQRS = 好棒棒。
沒有留言:
張貼留言