У меня есть часть шаблона CQRS, реализованного с использованием S # arp Architecture, например:
public class MyCommand
{
public CustomerId { get; set; }
// some other fields
}
public class MyCommandHandler<MyCommand> : ICommandHandler<MyCommand, CommandResult>
{
Handle(MyCommand command)
{
// some code for saving Customer entity
return CommandResult.Success;
}
}
Интересно, почему бы просто не иметь класс, Command
содержащий данные и метод обработки? Это своего рода преимущество тестируемости, когда вам нужно тестировать логику обработки команд отдельно от свойств команды? Или это какое-то частое деловое требование, когда вам нужно, чтобы одна команда обрабатывалась разными реализациями ICommandHandler<MyCommand, CommandResult>
?
c#
design-patterns
architecture
cqrs
rgripper
источник
источник
Ответы:
Забавно, этот вопрос только напомнил мне о том же разговоре, который у меня был с одним из наших инженеров о библиотеке коммуникаций, над которой я работал.
Вместо команд у меня были классы Request, а затем - RequestHandlers. Дизайн был очень похож на то, что вы описываете. Я думаю, что часть вашей путаницы в том, что вы видите английское слово «команда» и сразу же думаете «глагол, действие ... и т. Д.».
Но в этом проекте думайте о Команде (или Запросе) как о букве. Или для тех, кто не знает, что такое почтовый сервис, подумайте по электронной почте. Это просто контент, отделенный от того, как следует воздействовать на этот контент.
Зачем ты это делаешь? В большинстве простых случаев, в шаблонах команд нет причин, и вы могли бы заставить этот класс выполнять работу напрямую. Однако выполнение разделения, как в вашем проекте, имеет смысл, если ваше действие / команда / запрос должны пройти некоторое расстояние. Например, через сокеты или каналы, или между доменом и инфраструктурой. Или, возможно, в вашей архитектуре ваши команды должны быть постоянными (например, обработчик команд может выполнять по 1 команде за раз, из-за некоторых системных событий, поступает 200 команд и после завершения первых 40 процессов). В этом случае, имея простой класс только для сообщений, становится очень просто сериализовать только часть сообщения в JSON / XML / двоичный / что угодно и передавать его по конвейеру, пока обработчик команд не будет готов обработать его.
Другое преимущество отделения Command от CommandHandler заключается в том, что теперь у вас есть возможность параллельной иерархии наследования. Например, все ваши команды могут быть производными от базового класса команд, который поддерживает сериализацию. И, возможно, у вас есть 4 из 20 обработчиков команд, которые имеют большое сходство, теперь вы можете получить их из базового класса обработчика команд. Если бы вы обрабатывали данные и команды в одном классе, отношения такого типа быстро вышли бы из-под контроля.
Другим примером для развязки было бы, если вашей команде требовалось очень мало ввода (например, 2 целых числа и строка), но ее логика обработки была достаточно сложной, чтобы вы хотели хранить данные в переменных промежуточного члена. Если вы ставите в очередь 50 команд, вам не нужно выделять память для всего этого промежуточного хранилища, поэтому вы отделяете Command от CommandHandler. Теперь вы ставите в очередь 50 легких структур данных, а более сложное хранилище данных выделяется только один раз (или N раз, если у вас N обработчиков) с помощью CommandHandler, который обрабатывает команды.
источник
Обычный шаблон команды - это наличие данных и поведения в одном классе. Этот тип «шаблона команд / обработчиков» немного отличается. Единственное преимущество по сравнению с обычным шаблоном состоит в том, что ваша команда не зависит от фреймворков. Например, вашей команде может потребоваться доступ к БД, поэтому она должна иметь некоторый контекст или сеанс БД, то есть она зависит от каркасов. Но эта команда может быть частью вашего домена, поэтому вы не хотите, чтобы она зависела от фреймворков в соответствии с принципом инверсии зависимости . Отделение входных и выходных параметров от поведения и наличие диспетчера для их соединения могут исправить это.
С другой стороны, вы потеряете преимущество как наследования, так и состава команд. Что я думаю, это настоящая сила.
Кроме того, незначительный придира. То, что в названии есть команда, не делает ее частью CQRS. Это о чем-то гораздо более фундаментальном. Такая структура может служить как командой, так и запросом даже в одно и то же время.
источник