Автор: Папочка Разработки · Папочка Разработки
Канал «Папочка Разработки», 20 минут. CQRS (Command Query Responsibility Segregation) — паттерн с устойчивой репутацией «понятного на собесе, но непонятного в коде». Видео разбирает, почему так происходит.
Распространённое понимание CQRS: разделить код на команды (пишут данные) и запросы (читают данные), сложить по разным папкам, добавить Handler для каждого — и считать, что CQRS внедрён. Это не CQRS, это просто именование. Настоящий паттерн — про разделение моделей: модель записи оптимизирована для инвариантов и бизнес-правил, модель чтения — для отображения данных в том виде, в котором их хочет видеть клиент. Когда модели разделены по-настоящему, появляется возможность масштабировать чтение и запись независимо, использовать разные хранилища, денормализовать read-side для производительности. Без разделения моделей это просто организация кода, а не архитектурный паттерн.
Кому смотреть: разработчикам, которые используют или планируют CQRS и хотят убедиться, что понимают его правильно — и тем, кто готовится к техническому интервью, где этот паттерн регулярно всплывает.
Из этого можно взять в работу: если у вас уже «есть CQRS» — проверьте: используете ли вы разные модели для чтения и записи? Если read side — это та же доменная модель, просто завёрнутая в Query-объект, вы не используете CQRS, вы используете именование.
Откуда паттерн: CQRS вырос из CQS (Command Query Separation) Бертрана Мейера — принципа, что метод должен либо выполнять команду (менять состояние, ничего не возвращать), либо запрос (возвращать данные, не менять состояние). CQRS применяет эту идею на уровне архитектуры системы, а не отдельных методов.
Три уровня применения: простой (разделение по слоям в монолите, одно хранилище), средний (разные модели для чтения и записи, одно хранилище), полный (отдельные хранилища для read и write side с синхронизацией через события). Каждый уровень несёт разные компромиссы. Видео разбирает все три и говорит честно: полный CQRS — серьёзная архитектурная ставка, которая оправдана не везде.
Eventual consistency: когда read side и write side — разные хранилища, между ними возникает задержка. Пользователь создал запись, но при обновлении страницы не видит её — данные ещё не реплицировались в read store. Это не баг, это свойство архитектуры. Системы должны быть спроектированы так, чтобы эта задержка была приемлемой для бизнеса — или прятаться через optimistic UI.
Event Sourcing и CQRS: их часто используют вместе, но это независимые паттерны. Event Sourcing — способ хранить состояние как последовательность событий, а не как текущий снапшот. CQRS хорошо с ним сочетается (write side хранит события, read side строит проекции), но ни один не требует другого.