從DDD中實體和值物件的逆向思考想到的

lovejdon發表於2009-09-25
目前好多搞軟體開發的人仍然從資料庫程式設計的思想出發考慮問題。實際在我剛接觸程式設計的時候也是資料庫的設計思想,腦子裡總是想著資料如何儲存的,然後再去設計實現。從DDD的角度,這個是完全錯誤的思想,而且也違背了OO設計思想。
DDD中的實體和值物件在我剛開始接觸的時候,理解了一點,但是總感覺欠缺什麼地方沒有搞明白,總是考慮持久化的問題,總在思考:既然在實體中包含了值物件,那這個值物件的資料如何儲存(也許是資料庫思想深入的緣故)。但是隨著對DDD的深入,突然有了個逆向思維值物件的思考,不知道是否這樣理解妥當。
實體和值物件的思考層面是業務層的內容。在這裡拋棄如何持久化的問題。我們只是在設計我們的領域模型,讓他更符合業務規則。
但是畢竟在軟體實現的時候,持久化是我們要考慮的,雖然思考的時機有可能延後,但是不是可以迴避的問題。我這樣思考,OO是物件的集合,物件間的作用。資料庫是過程化,資料是平行的,沒有先後,沒有主次,那麼如果從資料庫的思想出發,如何將這些平行的資料轉化為OO中的物件是一個出發點(雖然這個出發點不對,但是是逆向的思考),資料庫中的欄位對應著物件的屬性,此時問題來了,如何將這些欄位組裝到一個物件中。欄位在物件中找到合適歸屬是個問題,以往我們從資料庫結構直接生成POJO的做法就是一種,但是從這個角度講,這變成了等價轉換,中間沒有任何的變化,只是表現形式不一樣而已。表對應實體,屬性對應欄位。完全成為了一種資料庫表的物件表現形式,物件完全成為了資料庫的表中資料的載體。這種方式是反模式,也就是我們常說的貧血模型。從這個角度考慮顯然是錯誤。主要是因為中間少了一個環節,這個環節就是如何把資料庫的平行結構轉換為物件結構,而不是單純的複製(注意:逆向思考)。也就是轉換為實體和值物件的結合,代表我們領域裡的真正模型!這個也就是利用DDD分析的一個方面(當然DDD的分析不會是我們這裡討論的從資料庫角度考慮的問題,我們這裡只是逆向的倒推而已)

如何真的能從資料庫的這種結果轉換為真正意義上的實體和值物件。那麼也就完成了關係資料到業務實體模型的轉換。
這樣才能真正將關係平行資料(過程式開發)向真正實體模型(物件導向開發)轉換。
這個時候再想想,我們在開發中的一部分也就是在做目前的逆向思維的操作,透過資料庫表結構,利用eclipse 來生成所謂的貧血實體POJO,這個時候完全失去了物件的意義,POJO完全成為了資料的載體,沒有業務模型存在。
好一點的做法(儘管很荒唐)是:在資料庫結構出來後,自動生成了POJO後,然後再將一些欄位合併成為物件,表示他們應該集中到一個或者多個物件中。但這個時候又要被資料庫牽著總,因為我們要考慮他們如何持久化到對應的表中的問題,所以這個時候的分析始終脫離不了資料庫的結構。依然約束了你的模型分析。
以上說的在開發中很常見,很多人也都是這麼來做的。這個反向思考反映了兩個問題:
一:我們使用的是物件導向的語言JAVA,但是物件導向的特性好象在這個開發過程中沒有任何體現,那我們為什麼要用JAVA,用PB,DELPH也可以吧,開發還快,何必自討苦吃。
二:儘管我們是想利用JAVA來OO,但是從我們開始資料庫結構設計開始,我們都是在設計平行關係。沒有層次行,只是平行的。所以無論你怎麼想在POJO中體現OO,都會被資料庫結構牽著走,因為你的腦海始終有資料庫結構的影子,違背了資料庫設計的結構,就不能被持久化(雖然有hibernate).這樣,你依然不能OO。
綜上,這樣的思考方式終歸應用OO語言沒有任何意義,還不如去換其他過程語言實現來得快點(因為好多人都說JAVA複雜,而且大多數是以過程開發的人居多)
那麼這個時候我們換一下考慮方式,拋開資料庫,從DDD的想法出發,設計出的實體模型,既符合業務,又是OO的,那有人會問,這個時候有實體和值物件的問題,如何持久化呢?大家別忘了,hibernate為我們做了。這個也就是我們為什麼要用hibernate的原因,雖然我們使用的實體和值物件是兩個物件,實體可以對應資料庫中的一張表,但是值物件呢,實際也是同一張表了(這只是一種簡單的方式而已),只是我們把值物件平鋪一下,把裡面的屬性提取出來,和實體中的屬性平行,一同放到資料庫中。這個提取,平鋪的過程也就是hibernate為我們做了,那麼這個時候考慮下,表結構是依據我們的實體和值物件結構來生成的,所以現在不是我們依賴資料庫了,而是資料庫的結構是受實體和值物件結構約束的(利用了hibernate的hbm2dll來實現),這個時候,資料庫已經被我們拋到九霄雲外了。不用理採他。他只用來hibernate資料而已。我們只要用我們的JAVA來做OO的東西就行了。
當然,我們還要熟悉hibernate,你才能更好的理解如何將實體和值物件轉換為資料庫結構。

以上也是我有感而發的,理解不到位的地方請大家指正

[該貼被lovejdon於2009-09-25 17:57修改過]

相關文章