Управляемый доменом дизайн и агрегаты - PullRequest
3 голосов
/ 24 февраля 2012

Я создаю небольшой проект Recipe Organizer MVC с использованием кода EntityFramework и выпуска Sql Server Compact, чтобы узнать больше об DDD и шаблоне репозитория.

Вот некоторые из моих доменных сущностей, я упростил их для этого вопроса.

public class Recipe {

    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    /// <summary>
    /// Represents a common meal type of “Breakfast, Lunch or Dinner” 
    /// or type of course “Appetisers, Soups, Salads, Fish, Poultry & Game, Meat, Side dishes, Desserts, Miscellaneous", etc.
    /// (for scope I am not considering brunch or supper or any other type) 
    /// </summary>
    [Required]
    public Course Course { get; set; }


    public virtual ICollection<Ingredient> Ingredients { get; set; }
}

public class Ingredient {
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
}

public class Course {
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
}

По моему мнению, для объема этого проекта я бы сказал, что Рецепт - это Совокупный Корень, а Ингредиент и Курс - совокупность Рецепта.

Если я возьму этот пример и использую скаффолдинг MVC, чтобы дать мне пример реализации шаблона репозитория, я получу интерфейс ниже и класс EFRecipeRepository, который реализует интерфейс и имеет ссылку на контекст БД EF.

public interface IRecipeRepository
{
    IQueryable<Recipe> All { get; }
    IQueryable<Recipe> AllIncluding(params Expression<Func<Recipe, object>>[] includeProperties);
    Recipe Find(int id);
    void InsertOrUpdate(Recipe recipe);
    void Delete(int id);
    void Save();
}

Следуя этому руководству:

В контексте шаблона хранилища агрегированные корни являются единственными возражает, что ваш клиентский код загружается из хранилища.

Хранилище инкапсулирует доступ к дочерним объектам - из в перспективе он автоматически загружает их, либо в то же время root загружен или когда он действительно необходим (как при ленивой загрузке).

Я ожидал бы добавить больше к этому интерфейсу, чтобы получить Ингредиент или Курс по Рецепту.

Проблема, с которой я столкнулся, заключается в том, что я хочу добавить в свои представления некоторые функции, включающие только ингредиенты или курс, например: навигацию по всем различным типам курсов (не только тем, которые связаны с рецептами) и авто -полный список ингредиентов.

В рамках моего проекта Ингредиенты не существуют вне Рецепта, поэтому представляется целесообразным, чтобы это был совокупность Рецепта. Конечно, кажется, что это должен быть сам Aggregate root, из-за того, как он существует сам по себе?

Я изо всех сил пытаюсь понять, как все это должно работать, если бы я хотел получить список каждого Ингредиента, это означало бы, что мне сначала нужно было бы использовать Репозитарий рецептов, чтобы загрузить все Рецепты, чтобы найти все ингредиенты?

Курс имеет аналогичную проблему, за исключением того, что он используется в качестве пути к категориям рецептов и поэтому может существовать и за пределами этой границы.

Есть какая-то концепция, по которой я скучаю? Возможно, способ создать Сервис, который используется для таких требований уровня презентации? У кого-нибудь есть мнение о том, как это сделать? или есть предложения получше? Спасибо

Кстати, это небольшой проект, и DDD может быть не лучшим подходом, но я считаю, что шаблон репозитория очень полезен для постоянного невежества в моей модели Домена.

Спасибо

1 Ответ

2 голосов
/ 24 февраля 2012

Я изо всех сил пытаюсь получить представление о том, как все это должно работать, если бы я хотел получить список всех ингредиентов, это означало бы, что мне сначала пришлось бы использовать репозиторий рецептов, чтобы загрузить все рецепты вЧтобы найти все ингредиенты?

Если все, что вам нужно, это список различных названий ингредиентов для автозаполнения, я бы просто предоставил услугу, которая извлекает необходимые отчеты избаза данных.Я совершенно в порядке с отчетами, которые тыкают в агрегаты, потому что они просто - отчеты.Вы просто не должны позволять сервису возвращать полезные сущности из агрегата (т.е. не возвращать Ingredient []), потому что это откроет границы агрегата для вызывающей стороны.Просто верните строку [] или подобное.

Опять же, я бы рассмотрел корни агрегата и курса, и ингредиента во всех, кроме самых тривиальных приложениях.Могут ли ингредиенты существовать без рецепта?Абсолютно!Является ли «сахар» № 1 (принадлежащий рецепту № 1) чем-то иным, чем «сахар» № 2 (принадлежащий рецепту № 2)?Я так не думаю.Там сахар.И есть рецепты, которые используют сахар.Делать ингредиенты из агрегатов корней имеет большой смысл.Например, вы можете легко просматривать свои рецепты по ингредиентам.

То же самое относится и к курсу, это концепции, которые сами по себе абсолютно понятны.

Хорошим примером концепции, которая НЕ должна быть агрегатным корнем, является строка заказа (то есть вещь, которая говорит: «3 телевизора Foobar по 700 долларов за штуку»).Без заказа строки заказа не имеют смысла.Но даже в этом случае служба, которая генерирует отчеты по строкам заказа, имеет смысл (теоретически) и является законной ИМО.Например, кто-то может захотеть узнать, сколько телевизоров Foobar обычно покупают вместе, чтобы представить великолепный новый 3-пакет Foobar TV (да, что угодно ...).Это снова будет означать поиск в базе данных внутри данных, которые обычно не доступны напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...