说我正在创建一个存储数字电子书的存储库,如下面的界面所示。该存储库将存储书籍的实际文本,以及标识书籍的元数据(标题,作者,出版商,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也可以解决这个问题,但是我想设计我的存储库而不假设将使用延迟加载 < / p>
答案 0 :(得分:2)
如果你的域中有一个支持它的用例,为什么不用它自己的Repository创建额外的实体BookSummary呢? BookSummary持久存在并不重要 - 它与域无关。
使用普遍存在的语言从域中派生实体非常重要,而不是查看数据库结构。
public interface IBookRepository
{
//Full Book Methods
void Add(Book Book);
void Delete(Book Book);
Book findById(int bookID)
}
public interface IBookSummaryRepository
{
//Full Book Summary Methods
void Add(BookSummary BookSum);
void Delete(BookSummary BookSum);
Book findById(int bookSummaryID)
}
如果您的存储库具有方法update()或store(),则它更可能是DDD而不是DDD存储库:http://codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/
答案 1 :(得分:2)
在DDD存储库中,只能使用聚合根。在你的情况下,我想,BookSummary只是Book聚合中的一个实体(当然,这里需要更准确的分析),所以应该通过BookRepository获取Book,然后使用延迟加载从聚合根遍历到BookSummary。否则,您不在此处应用域驱动设计
答案 2 :(得分:0)
这是一个古老的问题,但是没有接受的答案,所以我会回答从谷歌登陆的人们的利益。我一直遇到这个问题,因为我们有许多摘要屏幕,显示从多个实体编译的部分信息和/或信息。我所做的是在答案的评论中使用@xelibrion建议的单独阅读模型。我不使用完整的CQRS,只使用简单的查询模型。所以你的BookRepository仍然如此:
public interface IBookRepository
{
void AddBook(Book newBook);
void DeleteBook(int bookId);
void UpdateBook(Book updatedBook);
Book GetBook(int bookID)
}
您的BookSummary阅读模型及其方法如下所示:
public class BookSummary
{
public int BookId {get; set;}
public string Title {get; set;}
public string Author {get; set;}
public int PageCount {get; set;}
}
public interface IBookSummaryQueries
{
BookSummary GetBookSummary(int bookID)
IEnumerable<BookSummary> GetBooksByAuthor(string authorName);
IEnumerable<BookSummary> GetBooksByGenre(int genreId);
}
注意,这里没有更新Book的方法,只是查询