Is it ok for a DDD repository work with summary objects in addtion to “real” objects

北城余情 提交于 2019-12-07 09:39:50

问题


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


回答1:


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.

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)
}

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/




回答2:


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




回答3:


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:

public interface IBookRepository
{
    void AddBook(Book newBook);
    void DeleteBook(int bookId);
    void UpdateBook(Book updatedBook);
    Book GetBook(int bookID)
}

And your BookSummary read model and its methods look like this:

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);
}

Note, there are no methods to update Book here, just querying



来源:https://stackoverflow.com/questions/6299655/is-it-ok-for-a-ddd-repository-work-with-summary-objects-in-addtion-to-real-obj

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!