Pull to refresh

CQRS, UI, основаный на заданиях, Источники событий… ах

Reading time4 min
Views14K
Original author: Greg Young
Ремарка от меня. Подобрать терминологию было непросто, поэтому готов в процессе редактировать перевод, чтобы улучшить понимание текста.

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

CQRS Разделение ответственности команд и запросов (Command and Query Responsibility Segregation)

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

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

CustomerService

void MakeCustomerPreferred(CustomerId)
Customer GetCustomer(CustomerId)
CustomerSet GetCustomersWithName(Name)
CustomerSet GetPreferredCustomers()
void ChangeCustomerLocale(CustomerId, NewLocale)
void CreateCustomer(Customer)
void EditCustomerDetails(CustomerDetails)

Применение CQRS на этом приведет к двум сервисам

CustomerWriteService

void MakeCustomerPreferred(CustomerId)
void ChangeCustomerLocale(CustomerId, NewLocale)
void CreateCustomer(Customer)
void EditCustomerDetails(CustomerDetails)

CustomerReadService

Customer GetCustomer(CustomerId)
CustomerSet GetCustomersWithName(Name)
CustomerSet GetPreferredCustomers()

Вот и все. Это вся картина CQRS шаблона. Не более.… Это кажется занимательным, когда мы описываем его в таком виде, не так ли? Данное разделение дает возможность привнести нечто интересное в архитектурном плане. И что очень важно — он помогает остановить процесс ментальной ретардации, потому что двое используют те же данные, и кроме этого, они также должны использовать ту же модель данных.

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

UI, основанный на заданиях (Task based UI)

Пользовательский интерфейс, основанный на заданиях, довольно сильно отличается от интерфейса, основанного на CRUD. В нем вы отслеживаете, что делает пользователь, и продвигаете команды, которые представляют его намерения. Хотелось бы подчеркнуть, что CQRS не требует интерфейса основанного на заданиях. Можно применить CQRS в CRUD приложении (хотя, например, создание отдельных моделей будет при этом гораздо сложнее).

Но есть одна вещь, которая действительно требует подобного интерфейса — это доменная модель.

Сервисный слой приложения в доменной модели представляет собой задачи, которые система может выполнять. Это не просто такие процессы, как копирование данных в доменный объект и их сохранение… Не стоит забывать о поведении с объектом. Прежде чем двигаться дальше, давайте посмотрим, что случится, если мы все-таки так сделаем.

В нашем повсеместном языке не было бы других глаголов кроме как «Создать», «Удалить» и «Изменить». И пока существует много доменов, в которых язык является именно таким, не стоит использовать принцип доменных моделей для построения системы.

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

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

Источники событий

Хотелось бы внести ясность, что когда я использую этот термин, я не имею ввиду всё, что написано в bliki. Я ссылаюсь к хранению текущего состояния, как серии событий и возобновляю состояние системы, повторяя эти серии событий…

На командной стороне уравнения, с тех пор как «чтение» больше не является частью домена, сохранение событий может быть отличным способом поддержания текущего состояния. Значение возрастет, если вы решитесь на две отдельные модели (модель для чтения и модель для записи) и если вам необходимо их интегрировать, то вы вероятнее всего будете это делать через события. Так как событийность сохраняется, почему бы просто не использовать одну модель для управления состоянием?

Шаблон обмена сообщениями

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

Наконец я подошел к последнему «подходу», правда, не люблю его так называть, потому что в действительности это концепция, которую люди кладут в свои определения CQRS, которая идет рука в руку с обменом сообщениями…

Конечная согласованность

Принцип конечной согласованности также довольно часто вводится между сервисами. Это делается ввиду многих архитектурных побуждений. Но наибольшее преимущество — это то, что он позволяет увеличить масштабируемость и доступность. Если вы помните CAP теорему, там сказано, что если нет согласованности — это усиливает другие два свойства. Это очень хорошо для моделей, если они разделены, но это ни в коем случае не является свойством конкретно CQRS.

Сейчас мы можем увидеть, что CQRS на самом деле довольно простой шаблон. Все, что крутится около CQRS, это не только CQRS, а также архитектурные свойства интеграции двух сервисов. Другими словами, самое интересное — это не шаблон CQRS, а те решения, которые принимаются по ходу. Есть много интересных решений, которые были задействованы в системе, где решили использовать CQRS… но это не только CQRS само по себе.
Tags:
Hubs:
+10
Comments8

Articles