Может ли репозиторий DDD сохранять состояние?

Я разрабатываю приложение для доставки и пытаюсь использовать чистую архитектуру. Я пытаюсь выяснить, где хранить состояние объекта Shipment, чтобы мне не приходилось повторно создавать экземпляр нового объекта каждый раз, когда пользователь нажимает кнопку в пользовательском интерфейсе. Вот поток.

  1. Пользователь вводит номер доставки в пользовательском интерфейсе
  2. Контроллер пользовательского интерфейса обрабатывает событие пользовательского интерфейса и создает экземпляр варианта использования Interactor a. Экземпляр репозитория передается в конструктор варианта использования Interactor.
  3. Интерактор Use Case создает экземпляр Shipment, вызывая Factory (например, CREATE_BY_DELIVERY). Фабрика вызывает репозиторий для сбора данных из базы данных.
  4. Данные о доставке заполняются в пользовательском интерфейсе.
  5. Затем пользователь нажимает кнопку «Расценка».
  6. UI Controller обрабатывает событие нажатия кнопки и вызывает метод RATE_QUOTE Interactor варианта использования a. Должен ли интерактор варианта использования снова вызывать фабрику отгрузки, как на шаге №3, или может ли интерактор варианта использования получить экземпляр объекта «Отгрузка», который уже был создан на шаге №3?
  7. Тарифы отображаются в пользовательском интерфейсе
  8. Затем пользователь нажимает кнопку ОБРАБОТКА отправки.
  9. Контроллер пользовательского интерфейса обрабатывает событие нажатия кнопки и вызывает метод PROCESS_SHIPMENT Interactor варианта использования a. Должен ли интерактор варианта использования снова вызывать фабрику отгрузки, как на шаге №3, или может ли интерактор варианта использования получить экземпляр объекта «Отгрузка», который уже был создан на шаге №3?

Должно ли состояние объекта отгрузки быть переменной экземпляра в контроллере пользовательского интерфейса, в интеракторе вариантов использования или в репозитории? В идеале я хотел бы сохранить его где-нибудь, чтобы мне не нужно было создавать новый объект каждый раз, когда пользователь нажимает кнопку в пользовательском интерфейсе.

Заранее спасибо!




Ответы (2)


Может ли репозиторий DDD сохранять состояние?

Да, абсолютно — это было частью первоначального описания.

РЕПОЗИТОРИЙ представляет все объекты определенного типа в виде концептуального набора (обычно эмулируемого). Он действует как коллекция, но с более сложными возможностями запроса.... Для каждого типа объекта, которому требуется глобальный доступ, создайте объект, который может обеспечить иллюзию находящейся в памяти коллекции всех объектов этого типа.

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

В идеале я хотел бы сохранить его где-нибудь, чтобы мне не нужно было создавать новый объект каждый раз, когда пользователь нажимает кнопку в пользовательском интерфейсе.

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

Тем не менее, нет абсолютно никаких причин, по которым реализация репозитория не может включать кэш недавно использованных объектов. Вы просто должны быть готовы инвестировать в стратегию инвалидации кеша.

Помните, Фил Карлтон учил нас много лет назад

В компьютерных науках есть только две сложные вещи: инвалидация кеша и присвоение имен вещам.

person VoiceOfUnreason    schedule 15.12.2017
comment
Согласованный. Я добавлю, что ваша фактическая реализация репозитория не должна включать никакого кэширования. Вместо этого используйте шаблон декоратора для включения кэширования. Этот декоратор будет обертывать фактическую реализацию (возможно, внедрение конструктора), а затем выполнять кэширование. Ваш вариант использования по-прежнему потребует, скажем, IShipmentRepository, но вы создадите экземпляр оболочки и передадите экземпляр репозитория. Таким образом, вы можете содержать свои репозитории в чистоте. - person Eben Roux; 16.12.2017

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

В этом конкретном случае использование кеша ухудшает горизонтальную масштабируемость приложения. Трудно иметь несколько экземпляров. Трудно использовать оптимистическую блокировку на уровне базы данных/постоянства, версия агрегата должна быть правильно установлена ​​при загрузке агрегата (она должна быть наибольшей), иначе ожидаемая версия (загруженная версия + 1) не совпадает. Другими словами, как сказал @VoiceOfUnreason, трудно сделать кеш недействительным эффективным способом.

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

P.S. это не относится к совокупным репозиториям, полученным из событий. В этом случае вы можете сохранить снимки в памяти, но по-прежнему касаться/запрашивать хранилище событий для новых событий.

person Constantin Galbenu    schedule 16.12.2017
comment
Спасибо Вам за информацию. Является ли сохранение объекта в интеракторе прецедентов возможным? Или это нарушит принципы чистой архитектуры? - person Tony Raimo; 16.12.2017
comment
@TonyRaimo это ничего не нарушит. В этом случае Interactor` будет действовать как Cache. - person Constantin Galbenu; 16.12.2017