4

假设我正在创建一个存储库来存储数字电子书,如下面的界面所示。该存储库将存储图书的实际文本,以及标识图书的元数据(书名、作者、出版商、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 也可以解决这个问题,但我想设计我的存储库而不假设将使用延迟加载

4

3 回答 3

3

如果您的域中有一个支持它的用例,为什么不创建具有自己的存储库的附加实体 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)
}

如果您的 Repository 有方法 update() 或 store() 它比 DDD 的存储库更有可能是 DAO:http: //codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/

于 2011-06-10T03:03:34.113 回答
2

在 DDD 存储库中应仅与聚合根一起使用。在你的情况下,我想,BookSummary 只是 Book 聚合中的一个实体(当然,这里需要更准确的分析),所以应该通过 BookRepository 获取 Book,然后使用延迟加载从聚合根遍历到 BookSummary。否则,您不会在这里应用领域驱动设计

于 2011-06-10T05:58:36.447 回答
1

这是一个古老的问题,但是没有公认的答案,所以我会为了人们从谷歌登陆这里的利益而回答。我一直遇到这个问题,因为我们有许多显示部分信息和/或从多个实体编译的信息的摘要屏幕。我所做的是使用@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的方法,只是查询

于 2016-05-19T18:03:24.900 回答