l

2020年8月20日 星期四

Clean Architecture(7):套用CQRS簡化Presenter與View Model

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 = 好棒棒。

沒有留言:

張貼留言