1. 程式人生 > >ddd的戰術篇: domain object之一

ddd的戰術篇: domain object之一

首先ddd的戰術這個講法是不太好的。ddd書中說的是戰術性建模(tactical modeling)。其意思是在戰術層面的建模,那當然有戰略層面的建模啦。以後會專門講。

domain object是ddd區別於其他建模/設計方法的一個部分。他定義了概念幫助我們去建立model。如果沒有接觸過ddd,一開始會覺得有點莫名其妙,為什麼要定這種規矩,這種規則?

Entity,value object, Aggregate

entity

entity是一類可識別的可追蹤的物件。

說簡單了,它必須有identifier,再簡單點id(可識別,可被追蹤)。

另外它是有可變物件,mutable。但即使狀態變化了之後,entity還是原來的entity。(好繞口)

  現實一點的例子。一個人家“王帝”,他改名交了“王皇”,名字雖然變了,但還是同一人。當然現實世界裡我們很難去尋找一個identifier(識別碼),如何定義一個不變的identifier會是個哲學問題,但程式設計時就簡單多了,直接搞個id就就行。

value object

與entity對應的一個概念叫value object

它是一個值,是不可變的,immutable。沒有identifier,也不需要被追蹤!

  比如java中的字串和value object的感念很相近。字串生成之後就是不可變的。而且也沒有什麼id來識別它。

什麼時候使用entity,什麼時候使用value object

具體問題具體分析

比如我們需要對地址這個東西建模。如果我們關心的是地址的履歷之類的資訊,過去30年前這個地址可能叫霞飛路,現在可能叫淮海路,而且需求是我們必須知道霞飛路,淮海路指的是一個地址。那很可能我們需要的是entity。這個entity可能還要開發change()的方法來改變路名。

但如果我們做的是一個送貨軟體。地址只是表示一個目的地而已,霞飛路和淮海路在我看來就是不同的,那就說明,你不必對地址本身的變化進行追蹤(送貨地址變了,對你很重要。但霞飛路改名成淮海路對你不重要。)。那value object就夠了。

  你可能覺得何必這麼費事搞個表示地址的value object, 搞個字串不就行了?

   首先這不一定是一個關於ddd的問題。淡然很多情況下,我們可以的確用java的基礎類來建模的。但從面向物件的封裝角度來說,我們可以考慮創造專門的類。

   如果我們建立value object,它是可以擁有行為的。比如Address是一個value object。它可以擁有getCountry(), getProvince(), getCity()等方法。

Aggregate

Aggregate,集合。是有多個(也可以是一個)entity,value object組成的物件。

Aggregate可以看作一個樹狀結構的東西。根是一個entity。Aggregate的一個作用是保持domain object的關聯性的正確。

Aggregate和Repository

Repository

Repository是用來存放一個aggregate的object。(是不是聽起來像DAO?)

Repository的存在,讓我們感覺我們存放在它裡面的aggregate就好像on memory一樣,不必去關心它具體是和rdb對接還是其他的形式。

請注意的是Repository對應的是aggregate而不是entity!雖然我們在實際偏碼時不會去專門寫aggregate的類,有關具體實現,之以後的文章會寫。簡單地講根entity就可以代表aggregate。

domain object的做法與active record的區別

active record pattern也是很常見的一種模式。大概是建立於資料表的一一對映的類,然後有各自的DAO類。乍看起來和domain object的做法是一樣的。

1. 對映關係

active record一般以一個類對應一個數據表為前提

repository則沒有這個限制。當一個aggregate需要對應多個數據表時,那repository自然就對應多個數據表。repository隱藏了資料層的物理實現。

這裡想多提一點。domain model的建立,稱作理論設計比較合適。它儘量不關心物理的實現,只求對domain的正確反映。

而data model的設計,可以稱作物理實現。是以資料永久化為目的。與ddd相關聯,自然就是如何將domain object永久化。

2. domain object主張充血模式

active record常常會導致製造大量的於資料表對應的類,這些類一般不會有行為,而描述業務邏輯的職責就會到很多service類上。

domain object則希望類有自己的行為,而不是開放好多setter,讓外部的類來控制自己的狀態變化。

總結

講了好多理論,大致介紹了domain object。

entity: stateful, mutable.

value object: immutable

aggregate: entity和value object的集合

repository: stateless,儲存aggregate

之後的文章準備寫一些例子來更好地說明這些概念。