Является ли шаблон репозитория с дизайном, управляемым доменом, анти-шаблоном?

Прежде всего, я хочу уточнить, что я новичок в разработке Driven Driven Design, и я задаю этот вопрос, потому что я прочитал что-то, называемое Anemic Domain Model.

В большинстве случаев я вижу следующее при работе с шаблоном репозитория.

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

Пожалуйста, предоставьте свой ценный ответ для моего запроса.

Позвольте мне пояснить несколько вещей.

Общий репозиторий означает общий интерфейс, который реализуется репозиторием Entity.

Моя путаница касается следующей вещи

Например:  Предположим, я хочу сохранить

    public class User
    {
        public int Id { get; set;}
        public string Name { get; set};
    }

    public class UserRepository : IRepository<User>  
    {  
        // All Operation Like Save / Get /  UserEntity (Domain Object)       
    }

Итак, вот мой класс User ничего не делает, а просто имеет свойства и другой дескриптор операции UserRespository. Так что мой пользователь - это модель анемичного домена. (Так как он ничего не делает)

Здесь, в прикрепленном изображении, я рассматриваю ProductRepository, поэтому мой вопрос: Является ли класс My Product Anemic model?

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

введите описание изображения здесь

Ответ 1

Я согласен с тем, что интерфейс IRepository обычно является пустой тратой времени. Если я поместил основные операции CRUD в мой интерфейс IRepository, то как мне обращаться с данными, такими как данные аудита? Там, где удаление было бы запрещено. Должен ли я просто вернуть a InvalidOperationException при попытке вызвать Delete()?

Некоторые люди предложили меньшие интерфейсы, такие как IReadable, IWriteable, IUpdateable или IDeleteable. Я думаю, что этот подход даже более беспорядочен.

Лично (и это только мое собственное решение после того, как все остальное хорошо работает вокруг блока), для DDD я предпочитаю использовать интерфейс для каждого репозитория (в основном для IoC и модульного тестирования). Это дает мне IUserRepository, IAuditLogRepository и т.д. Мои репозитории также принимают (как параметры) и возвращают объекты домена (совокупные корни или только отдельные объекты). Таким образом, нет никаких анемичных объектов DTO для поддержания или помех для моего решения. Тем не менее, я все еще использую модели просмотра, чтобы сохранять конфиденциальные данные из моих представлений.

Там много аргументов онлайн для шаблона репозитория и против него.

Ответ 2

Шаблон репозитория не является анти-шаблоном как таковым, но я видел далеко не многие реализации DDD, где шаблон репозитория предоставил мало или вообще не имеет значения. Направьте свою многоуровневую архитектуру уровня n-level-offer-no-value на прагматичного эксперта-разработчика hardcore, и он, вероятно, даст вам "анти-шаблонную" критику (и, насколько я могу сказать, допустим).

Профили шаблона хранилища:

  • Абстракция базовой технологии сохранения.
  • Возможность определять свои совокупные корни, только совокупные корни должны иметь репозитории
  • Способ явно указывать, какие операции действительны для рассматриваемого совокупного корня, например, если он недействителен для удаления вашего объекта, ваш репозиторий не должен иметь метода удаления.
  • Что-то, что легко тестировать без базы данных (заглушая ваши репозитории)

Паттерн хранилища минус:

  • Близость к вашей технологии персистентности.
  • Еще один уровень

Лично я предпочитаю использовать шаблон репозитория при DDD, но ваше решение больше похоже на активный шаблон записи, тем самым устраняя большинство преимуществ использования репозиториев в первую очередь. Я никогда не делаю общие репозитории, потому что они удаляют профи 2 и 3 (у меня может быть общая реализация, но я не раскрываю ее непосредственно в код репозитория-потребителя).

А также: не используйте репозитории для совокупности DTO, ViewModels и т.д. Используйте отдельные модели и технологию для моделирования записи (DDD может отлично работать) и читает.