Это нормально для работы репозитория DDD с объектами сводки в дополнение к "реальным" объектам - PullRequest
4 голосов
/ 10 июня 2011

Скажем, я создаю хранилище для хранения электронных электронных книг, как показано в интерфейсе ниже. В этом хранилище будет храниться фактический текст книги, а также метаданные, которые идентифицируют книгу (название, автор, издатель, 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 с отложенной загрузкой также могло бы стать решением этой проблемы, но я хотел бы разработать свои хранилища без предположения, что будет использоваться отложенная загрузка

Ответы [ 3 ]

2 голосов
/ 10 июня 2011

В репозитории DDD должен работать только с агрегатным корнем.В вашем случае, я полагаю, BookSummary - это просто сущность внутри агрегата Book (конечно, здесь необходим более точный анализ), поэтому следует получить Book через BookRepository, а затем перейти к BookSummary из корня агрегата, используя ленивую загрузку.В противном случае, вы не применяете Domain Driven Design здесь

2 голосов
/ 10 июня 2011

Если в вашем Домене есть сценарий использования, который бы его поддерживал, почему бы просто не создать дополнительную сущность 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 (), то скорее всего DAO, чем репозиторий по DDD: http://codebetter.com/iancooper/2011/04/12/repository-saveupdate-is-a-smell/

0 голосов
/ 19 мая 2016

Это старый вопрос, однако нет принятого ответа, поэтому я отвечу на благо людей, пришедших сюда из Google. Я постоянно сталкиваюсь с проблемой, поскольку у нас есть много сводных экранов, которые показывают частичную информацию и / или информацию, собранную из нескольких объектов. Что я делаю, так это использую отдельные модели чтения, как это было предложено @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, просто запрос

...