假设我正在创建一个存储库来存储数字电子书,如下面的界面所示。该存储库将存储书籍的实际文本以及标识书籍的元数据(标题、作者、出版商、ISBN 等)。
public interface IBookRepository
{
void AddBook(Book newBook);
void DeleteBook(int bookId);
void UpdateBook(Book updatedBook);
Book GetBook(int bookID)
}
public class Book
{
public int BookId {get; set;}
public string Title {get; set;}
public string Author {get; set;}
public IList<Page> Contents {get; set}
}
public class Page
{
public int PageNumber {get; set;}
public string PageContent {get; set;}
}
在大多数情况下,我不想检索这本书的全部文本,因为那样会相当昂贵。在大多数情况下,我关心的只是元数据,例如我可能只想创建一个书籍列表。那么,就 DDD 而言,允许 IBookRepository 拥有返回 BookSummary 对象的方法是否可以接受?书籍摘要对象将包括元数据,但不包括书籍的实际内容。
拥有 UpdateBook(BookSummary book)
方法怎么样?假设我想更新 Book.Rating 属性,但不需要/不想从存储库中读取本书的全部内容来执行此操作。
public interface IBookRepository
{
//Full Book Methods
void AddBook(Book newBook);
void DeleteBook(int bookId);
void UpdateBook(Book updatedBook);
Book GetBook(int bookID)
//BookSummary Methods
BookSummary GetBookSummary(int bookID)
IEnumerable<BookSummary> GetBooksByAuthor(string authorName);
IEnumerable<BookSummary> GetBooksByGenre(int genreId);
void UpdateBook(BookSummary bookSummary);
}
public class BookSummary
{
public int BookId {get; set;}
public string Title {get; set;}
public string Author {get; set;}
public int PageCount {get; set;}
}
注意:我知道使用带有延迟加载的 ORM 也可以解决这个问题,但我想在设计我的存储库时不假设将使用延迟加载
Say I'm creating a repository to store digital E-Books as shown in the interface below. This repository will store the actual text of the book, as well as the metadata that identifies the book (title, author, publisher, ISBN etc..).
public interface IBookRepository
{
void AddBook(Book newBook);
void DeleteBook(int bookId);
void UpdateBook(Book updatedBook);
Book GetBook(int bookID)
}
public class Book
{
public int BookId {get; set;}
public string Title {get; set;}
public string Author {get; set;}
public IList<Page> Contents {get; set}
}
public class Page
{
public int PageNumber {get; set;}
public string PageContent {get; set;}
}
In most cases I would not want to retrieve the entire text for the book, as that would be rather expensive. In most cases all I care about is the metadata, for example I may simply want to create a list of books. So would it be acceptable in regards to DDD to also allow an IBookRepository
to have methods that return BookSummary
objects? Book summary objects would include the metadata but not the actual contents of the book.
What about having an UpdateBook(BookSummary book)
method? Say I want to update the Book.Rating
property, but don't need/want to read the entire contents of the book from the repository to do this.
public interface IBookRepository
{
//Full Book Methods
void AddBook(Book newBook);
void DeleteBook(int bookId);
void UpdateBook(Book updatedBook);
Book GetBook(int bookID)
//BookSummary Methods
BookSummary GetBookSummary(int bookID)
IEnumerable<BookSummary> GetBooksByAuthor(string authorName);
IEnumerable<BookSummary> GetBooksByGenre(int genreId);
void UpdateBook(BookSummary bookSummary);
}
public class BookSummary
{
public int BookId {get; set;}
public string Title {get; set;}
public string Author {get; set;}
public int PageCount {get; set;}
}
Note: I know using an ORM with Lazy Loading would also be a solution to this, but I'd like to design my repositories with out the assuming that lazy loading will be used
发布评论
评论(3)
如果您的域中有一个用例可以支持它,为什么不直接创建额外的实体 BookSummary 及其自己的存储库来完成这项工作呢? BookSummary 保存在哪里并不重要——它与域无关。
重要的是使用通用语言从域中派生实体,而不是查看数据库结构。
如果您的存储库具有 update() 或 store() 方法,则更有可能是 DAO,而不是 DDD 存储库: http://codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/
If there is a use case in your Domain that would support it why don't just create additional entity BookSummary with its own Repository that will do the job? It does not really matter where BookSummary is persisted - that it not relevant for the Domain.
It is important to derive Entities from the Domain using Ubiquitous language and not to look at the database structure.
If you Repository has methods update() or store() it is more likely DAO than repository by DDD: http://codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/
在 DDD 存储库中应该仅适用于聚合根。在你的情况下,我想 BookSummary 只是 Book 聚合内部的一个实体(当然,这里需要更准确的分析),所以应该通过 BookRepository 获取 Book,然后使用延迟加载从聚合根遍历到 BookSummary。否则,您就不会在这里应用领域驱动设计
In DDD repository should work only with aggregate root. In your case, I suppose, BookSummary is just an entity inside of Book aggregate (of course, more accurate analysis is needed here), so should get Book via BookRepository and then traverse to BookSummary from aggregate root using lazy loading. Otherwise, you are not applying Domain Driven Design here
这是一个老问题,但是没有公认的答案,所以我会为了从谷歌登陆这里的人们的利益而回答。我一直遇到这个问题,因为我们有许多摘要屏幕,显示部分信息和/或从多个实体编译的信息。我所做的是按照 @xelibrion 在他的答案的评论中建议的那样使用单独的读取模型。我没有使用完整的 CQRS,只是使用仅具有查询方法的简单读取模型。所以你的 BookRepository 仍然像这样:
你的 BookSummary 读取模型及其方法看起来像这样:
注意,这里没有更新 Book 的方法,只是查询
This is an old question, however there is no accepted answer so I will answer for the benefit of people landing here from Google. I run into the issue all the time as we have many summary screens that show partial information and /or information compiled from multiple entities. What I do is use separate read models as suggested by @xelibrion in the comments of his answer. I do not employ full CQRS, just simple read models with query methods only. So your BookRepository remains like so:
And your BookSummary read model and its methods look like this:
Note, there are no methods to update Book here, just querying