Nano Hash - криптовалюты, майнинг, программирование

Дизайн, управляемый доменом, и агрегаты

Я создаю небольшой проект 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();
}

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

В контексте шаблона репозитория совокупные корни — это единственные объекты, которые ваш клиентский код загружает из репозитория.

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

Я бы хотел добавить больше в этот интерфейс, чтобы получить ингредиент или курс через рецепт.

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

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

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

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

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

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

Спасибо


Ответы:


1

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

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

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

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

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

24.02.2012
  • Спасибо за ответ, ингредиенты самодостаточны, как и само собой... и бывают случаи, когда ингредиент должен существовать сам по себе, в рамках этого проекта им не нужно было существовать вне рецепта.. однако теперь, когда этот список автозаполнения используется при добавлении нового ингредиента в рецепт... похоже, это так, и имеет смысл сделать его совокупным корнем, кажется немного глупым иметь такую ​​маленькую доменную модель и половину хотя сущности имеют свои собственные репозитории: P 25.02.2012
  • Как я уже сказал: если вам нужно получить доступ только к названиям ингредиентов для автоматического завершения, просто используйте сервис, который выполняет правильный запрос, и пусть ингредиенты остаются частью AR рецепта. Если ваш домен не требует, чтобы ингредиенты были AR, не делайте их AR. Это делает вещи простыми. 25.02.2012
  • Новые материалы

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

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..