2016-05-03 4 views
2

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

Так, например, у меня есть простой домен с сущностью Worker с некоторой функциональностью (некоторые методы заставляют сущность меняться) и WorkerRepository, чтобы я мог продолжать Рабочие. У меня есть прикладной уровень с некоторыми командами и командной шиной для управления доменом (например, создание Рабочих и обновление их рабочих часов, сохранение изменений) и уровень инфраструктуры, который имеет реализацию WorkerRepository и приложения GUI.

В этом приложении я хочу показать всем работникам некоторые данные и изменить их. Как показать данные?

  1. Я мог бы дать ему ссылку на реализацию WorkerRepository. Я думаю, что это нехорошее решение, потому что таким образом я мог бы добавить новых рабочих в репозиторий, пропустив командную шину. Я хочу, чтобы все изменения проходили через командную шину.
  2. Итак, я бы разделил WorkerRepository на WorkerQueryRepository и WorkerCommandRepository (в соответствии с CQRS) и давал ссылку только на WorkerQueryRepository. Это все еще не очень хорошее решение, потому что репо возвращает объекты Worker, у которых есть методы, которые изменяют их, и как эти изменения будут сохраняться?
  3. Должен ли я создать два типа репозиториев? Один из них будет использоваться на уровне домена и приложения, а другой будет использоваться только для предоставления данных во внешний мир. Второй из них не будет возвращать полнофункциональные объекты Worker, только WorkerDTO, содержащие только данные, необходимые графическому интерфейсу. Таким образом, GUI не имеет другого способа изменить Рабочих, только через командную шину.

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

ответ

3

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

Это подход CQRS; он работает очень хорошо.

Greg Young (2010)

CQRS просто создание двух объектов, где ранее было только один. Разделение происходит в зависимости от того, являются ли методы командой или запросом (то же определение, которое используется Meyer в Command and Query Separation, команда - это любой метод, который мутирует состояние, а запрос - любой метод, который возвращает значение).

Текущий термин для WorkerDTO, который вы предлагаете, - «Проекция». У вас часто будет больше одного; т. е. вы можете иметь отдельную проекцию для каждого вида рабочего в графическом интерфейсе. (У этого есть аккуратный побочный эффект облегчения взгляда - ему не нужно думать о данных, которые ему даны, потому что данные уже отформатированы с пользой).

Другой способ думать об этом состоит в том, что у вас есть представления «только для записи» (совокупность) и «только для чтения» (проекции).В обоих случаях вы читаете текущее состояние из книги записи (через репозиторий), а затем используете это состояние для создания необходимого вам представления.

Поскольку читаемые модели не нужно сохранять, вам, вероятно, лучше подумать завод, а не репозиторий, на стороне чтения. (В 2009 году Грег Янг использовал «провайдера» по этой же причине.)

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

Например, если вам нужно масштабировать производительность чтения, у вас есть возможность реплицировать книгу записей на кучу подчиненных копий и иметь свою фабричную загрузку проектора от подчиненных устройств, а не от мастера. Или начать изучение того, подходит ли другое хранилище сохранения (хранилище значений ключей, база данных графов, полнотекстовый индекс). Udi Dahan рассматривает ряд этих идей в CQRS - but different (2015).

+0

Теперь я понимаю, что я слегка неверно истолковал CQRS, но ваш ответ прояснил это. И спасибо, что подтолкнули меня в правильном направлении с прогнозами и прочитали модельные заводы! – bhaclash

+0

«Вы читаете текущее состояние из книги записи (через репозиторий)» ... Это не то, что CQRS вообще. CQRS означает независимые чтения и модели записи. Если вы не обходите модель домена полностью для запросов, то они связаны и не могут развиваться полностью независимо друг от друга. Я не говорю, что создание DTO из модели домена обязательно плохое, но тогда вы не можете сказать, что используете архитектуру CQRS. – plalx