Еще вопросы: (это из разных чатов-переписок, чтоб добру не пропадать, может и еще кому-то будет полезно) Q: В чем принципиальное отличие канарейки от А/Б тестирования? A: Предприниматели вынуждены принимать множество решений, часто с неопределенной или неизвестной отдачей. Такими решениями могут быть: какую фичу реализовать, через какой канал вести продажи или какой тип клиентов обслуживать. Общий подход обычно выглядит так: генерация идей для выявления вариаций в количестве и природе стратегических опций, тестирование жизнеспособности отобранных опций и принятие решение на основе результатов тестирования. Вот здесь и может помочь A/B-тестирование, цели которого — проверка бизнес-решений, снижение стоимости оценки конкурирующих идей и принятие решений на основе данных. То есть A/B тестирование — это контролируемый эксперимент, в котором вы держите все переменные постоянными, кроме одной или двух для определения их влияния на целевой показатель. Канареечные и A/B тесты в чем-то схожи. И те и другие позволяют релизить несколько версий фичи параллельно, сокращают радиус поражения от потенциальных багов с возможностью постепенного продвижения по различным демографическим регионам. Но при этом A/B тесты в большей степени специализируются на проверке удобства использования и влиянии на прибыль. Q: Было упоминание про нежелательность прямых запросов к БД - в чем их опасность? (речь о пользе DAO и отделении Domain от базы данных через Repository и DAO) A: В архитектуре активно используется принцип Last Responsible Moment из Lean. Звучит он примерно так (применительно к архитектуре): принятие решения нужно откладывать до последнего момента, когда уже нельзя не принять решение. Например, тип базы данных или конкретную базу данных. Суть здесь в том, что чем позднее в разработке мы примем важное решение, тем большим объемом информации мы будем обладать для принятия качественного решения (снижаем неопределенность). Другое важный поинт в том, что архитектура должна открывать новые возможности. То есть быть достаточно гибкой, чтобы ключевые решения можно было менять. Максимальная гибкость стоит бесконечно дорого, поэтому здесь действуем в терминах компромиссов. Пример: вначале мы вообще можем использовать in memory базу или общепринятую в компании sql-базу. Но со временем мы поймем, что данные слабо структурированы и захотим перейти на mongo (или key-value, или graph based database). И вот тут, если весь наш код будет пропитан SQL-запросами, нам будет ООООЧЕНЬ тяжело) Надеюсь, пример понятен. В микросервисах мы получаем выгоду от такого подхода, так как в рамках микросервиса мы и только мы полностью владеем данными и моделью данных этого микросервиса, то есть если мы перейдем на mongo, никто об этом даже не узнает, а нам стане лучше) Здесь часто приводят контр-аргумент: DAO-слой — лишняя прослойка, генерит кучу ненужного кода, запросы не эффективные, в общем — одна беда с ними. Это действительно так, когда используется единая база данных, а моделирование начиналось с модели данных, а не модели предметной области. Тут вам и нормальные формы и связь всех со всеми через foreign keys. Разумеется, условному hibernate или NHibernate снесет голову. Но вспоминаем про CQRS, что модель записи (та самая нормализация или ES, то есть последовательность событий) и модель чтения (удобная и практичная организация данных для чтения) — это разные модели. И модель чтения в общем случае будет очень похожа на модель предметной области. То есть таблицы для чтения вполне могут быть максимально денормализованными, а значит ORM-системы будут создавать простые, быстрые и эффективные запросы.