Недавно я проводил рефакторинг метода, который был и командой, и методом запроса.
Разделив его на один метод команды и один метод запроса, я обнаружил, что в коде теперь есть несколько мест, где я вызываю команду, а затем получаю значение из запроса, что выглядит как нарушение принципа СУХОЙ.
Но если бы я обернул этот общий код в метод, этот метод был бы и командой, и запросом. Это приемлемо?
language-agnostic
refactoring
dry
cqrs
Крис Уэлш
источник
источник
Ответы:
Всегда есть компромисс между противоречивыми принципами проектирования. Чтобы решить эту проблему, нужно взглянуть на причины, лежащие в основе принципов. В этом случае невозможность выполнить запрос без выполнения команды является проблематичной, но невозможность выполнить команду без выполнения запроса, как правило, безвредна. Пока есть способ выполнить запрос автономно, я не вижу причин не добавлять результат запроса в команду, особенно если сделано что-то вроде этого:
источник
Раньше я не слышал о разделении команд-запросов (CQS), но, похоже, это будет относиться к принципу единой ответственности (SRP), который гласит, что функция / класс в идеале должна отвечать за выполнение только одного и только одного ,
Если ваш код команды состоит из 20 строк кода, а код запроса - это еще 30 строк, и все они находятся в одном теле функции, очевидно, что вы нарушаете SRP, и я бы также предположил, что CQS и эти две части логики должны быть отделены друг от друга. ,
Однако, следуя вашему гипотетическому примеру, я бы, скорее всего, создал метод-обертку, который бы объединял вашу команду и запрос, чтобы DRY не нарушался во многих местах кода. Я бы также не считал это нарушением SRP (и, возможно, CQS), потому что оболочка по-прежнему несет только одну ответственность: объединять команду с запросом и создавать абстракцию более высокого уровня, которую легче использовать.
Я думаю, что метод обертки является вполне приемлемым решением, и чтобы проиллюстрировать это, давайте сделаем ваш пример еще на шаг вперед. Что делать, если вам нужно было выполнить 2 запроса вместо 1, а затем выполнить командное действие, основанное на этом. Таким образом, ваши две строки кода будут 6 или 8. Что если бы между данными и проверкой была некоторая проверка / проверка данных, то теперь у вас есть 15 строк кода. Не могли бы вы дважды подумать о создании оболочки, которая делает все это, вместо того, чтобы разбрасывать эти 15 строк в несколько файлов?
источник
СУХОЙ является более важным, поскольку он решает гораздо более фундаментальную задачу - избегая лишних, эффективно потраченных усилий. Это фундаментальная вещь - не нужно быть программистом, чтобы понять это.
CQS является ответом на трудность в языках без поддержки эффектов отслеживания понимания кода, который выполняется как для его результатов, так и для его эффектов. Однако:
Нельзя избежать необходимости выполнения кода для его результатов, поскольку это является основой для составления больших программ из небольших модулей.
Нельзя также избежать необходимости выполнения кода для его эффектов, потому что вне математики и теоретической информатики ценность запуска программы зависит от того, что она может сделать для нас.
Нельзя избежать необходимости вызывать эффекты и создавать результаты в одном и том же коде, потому что на практике нам нужны как эффекты, так и композиционность, а не только один или другой.
Реальное решение проблемы слежения за эффектами, которые слишком сложны для людей без посторонней помощи, - это, конечно, чтобы компьютеры помогали нам, людям ! То же самое можно сказать о отслеживании сложных взаимосвязей между значениями времени выполнения (такими как достоверность индексов массива), для которых исключения и принудительно выполняемые контракты представляют собой (не) решения.
В заключение, «решения», такие как CQS, просто мешают проектировать программы в соответствии с разумными принципами, основанными на реальности. Перейти на сухой.
источник