學習筆記 – DCI

  1. DCI 是 Data、Context 和 Interaction 的簡稱,是一個看問題的視角,有點像是 MVC 的感覺,底層用什麼語言沒有分別,就實作而言,就是一種處理問題的方式。
  2. DCI 希望能讓物件能更容易對應到人的心智模型上。
  3. 傳統 OO 的問題是善於 capturing structure,但相對比較不容易 capture behavior,好比說演算法,我們常將演算法放在物件的 method 中,對於影響範圍是單一物件的時候可能不是什麼大問題,但比較大的演算法常包含物件之間的互動,這時就可能被迫將演算法拆分在多個物件中。
  4. 拆分的代價(或表現形式)就是你在看別人的程式碼時,你可能容易看得出資料的結構。但具體的行為,如「按下一個按鈕會發生什麼事情」,就必須進入每一個影響的物件才有「機會」了解。
  5. 覺得和 functional language 的戰點有點相似。
  6. 好的設計應該讓「不變的」將「常改變」的分開,理論上物件(類別)應該要是穩定的,所以我們常用「繼承」來解決這個問題,透過繼承我們可以讓物件(類別)穩定,修改的部分則在子類別實作。但有時會發生問題,好比說要新增功能時(method)該怎麼做?在子類別新增一個實作當然沒問題,但父類別不就沒有這個功能了?所以這樣父類別好像也得提供同樣的介面,甚或需要實作自己的版本。但這樣還稱得上讓物件(類別)穩定(stable)嗎?
  7. 如果用上述的方式,隨著時間過去,功能的增加,物件(類別)只會越來越臃腫,最後會發現這個物件(類別)已經不是原來那個單純的意思了。
  8. DCI 用一種類似「角色扮演」的方式處理這個問題,它認為 Domain Object (類似對比 MVC 的 Model) 應該要是單純的,dumb 的,當一個 smart data 即可,舉例來說「人」類別(中文舉例大好)。人本身沒有什麼意思,也沒有什麼功能。但他在人生中卻可以扮演很多角色。如「人」當「爸爸」的時候,就可以玩女兒,所以就有了「玩女兒」這個功能。而當「老公」的時候,就有了「當載具」的功能、當「Boss」的時候,就有的時候就有「欺負下屬」的功能等等。在 DCI 中,「爸爸」、「老公」、「Boss」都代表 Role。在不同的情境(Context)中,一個人可以代表不同的「Role」。
  9. 上例具體到程式時,會以類似下述的方式實作,在一個 Context 中,Domain object 會以「動態注入」的方式注入 Role 的 method。然後透過這些 method 在 Context 中實現所需要的功能。
  10. Context 可以代表一個 User Story 或說是一個場景,它可能是一個類別、一個函式,反正知道意思就好。
  11. 有了場景後,就可以輸入對應的 Domain Object,這些 Domain Object 會根據在這個場景中扮演的角色(Role),動作注入角色需要的功能(概念如此,可以以各種方式實現,比如說 Python 可以直接新增 method),有了這些功能,這些角色就可以在場景出交互作用,完成這個 Story 發生的事情。
  12. 換言之,演算法會聚合在 Context 裡完成。
  13. 讓每一個 Context 代表一個 Story,除了好讀外,也適合應用 BDD
  14. 動態注入 method 可以讓 Domain Object 保持單純,具體實作不同語言有不同的展現方式。python 有一個 roles 函式庫,C++ 可以用 template 等等。
  15. 一個物件可以扮演多個角色,一個角色也可以被多個物件扮演
  16. 物件都可區分為:核心屬性和行為、場景屬性和行為。核心就是不依賴場景,與變化隔離;反之場景就是進入扮演角色時,動態注入的屬性和行為。
  17. DCI 的設計關鍵是 Domain Object 要非常單純,邏輯和行為則應該放在角色(Role) 裡頭,依附在場景之下。

發表迴響