2017-04-14 63 views
1

我剛開始學習DDD。所以我很抱歉的問題...如何構建複雜的價值對象?

所以我有Post實體。它看起來很好。但它應該有tags。 在代碼中,它看起來是這樣的(Ruby代碼):

class Post 
    attr_reader :tags 
    attr_reader :title 
    attr_reader :text 
    # ... 
end 

class Tag 
    attr_reader :name 
    attr_reader :description 
    # ... 
end 

標籤都沒有做出意義上的實體。我自己不需要tag。 但是,我應該如何實施郵政倉庫? 我發現2種型號:

在同一倉庫的構建標籤。像這樣:

# PostRepository 
def find(id) 
    # getting post data from storage here 
    # getting tags data 
    Post.new(title, text, tags_data.map { |tag_data| Tag.new(tag_data[:name], tag_data[:description])) 
end 

但它看起來很醜。無法清楚地說出原因。

2. 爲標籤創建單獨的存儲庫。

# PostRepository 
def find(id) 
    # getting post data from storage here 
    Post.new(title, text, tag_repository.find(tag_ids)) # or tag_names or tag_something 
end 

看起來更好。但是,爲價值對象創建單獨的存儲庫可以嗎?

根據DDD,正確的方法是什麼?

UPD: 另一方面,我必須得到所有可用的標籤。而且我從不需要更改帖子的標籤。標籤的名字看起來像身份。也許我從根本上是錯誤的?也許標籤是實體?

UPD2:

這個問題讓我發現,我的設計功力很差。 正因爲如此,我的一個問題有兩個。 它們是:

  1. 什麼是正確的方式來建立實體的倉庫內的價值對象。
  2. 如何查看我的問題中值和實體之間的差異。 畢竟看起來很清楚。根據指定條件,標籤是價值。可以通過Post的倉庫建立它。

但是,這種情況是不好的分析結果。如果我看起來更寬一些,我會看到該標籤有自己的生命週期。儘管在帖子的背景下,標籤是不可變的。

+0

問問你自己,如果一個標籤叫做'ddd',然後你決定將它重命名爲'domain-driven-design'以供將來使用,它應該反映到以前標記的帖子嗎?如果不是,那麼它是一個值,否則它最有可能是帖子上下文中的不可變實體,而是標籤管理上下文中的可變實體。 – plalx

+0

@plalx,你可以移動你的評論回答?這很有用,我想投票。 – anoam

回答

2

標記最有可能只是您的域中的常規值對象。標籤可以是一個實體,如果它有自己的生命週期。坦率地說,我認爲你的域名不是這種情況,因爲你可以用具有相同屬性的另一個副本替換每個標籤。

您可以添加查詢標記到您的域存儲庫的方法。這不違反DDD聚合規則。聚合實際上是一致的 - 如果您可以在聚合上下文之外修改它們,則您的存儲庫不應該返回聚合的部分內容。但是,您可以明確返回聚合的值對象,僅用於閱讀目的(例如,收集選定日期範圍內的所有帖子的所有標籤)。除此之外,爲了提高效率,查詢方法應該放在倉庫中。這就是說,在你的情況下,最好的解決方案是遵循CQRS原則使用單獨的讀取模型(使用例如nosql db)。通過這種方式,您可以明確調整模型以滿足您的查詢需求,因此可以非常高效。