除了“真实”对象之外,DDD存储库是否可以使用摘要对象

时间:2011-06-09 21:40:55

标签: domain-driven-design repository-pattern ddd-repositories

说我正在创建一个存储数字电子书的存储库,如下面的界面所示。该存储库将存储书籍的实际文本,以及标识书籍的元数据(标题,作者,出版商,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>

3 个答案:

答案 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的方法,只是查询