На одном из прошлых проектов наша команда решила реализовать монолитное приложение, построенное на принципах чистой архитектуры. Это был нетривиальный и местами противоречивый опыт: мы добились большей точности в оценках, сократили время вывода фич на рынок — и при этом неожиданно осложнили работу системным аналитикам.
В этой статье мы поделимся практическими наблюдениями: как мы подошли к архитектурным решениям, какие паттерны применяли, какие плюсы и минусы обнаружили, и что в итоге получилось. В качестве технологического стека — Django, PostgreSQL, Redis, ELK и Grafana.
Наш проект представлял собой монолит на Django с вкраплениями микросервисов. К тому моменту система уже работала в продакшене порядка семи лет, и нам регулярно приходилось сталкиваться с легаси. Типичные симптомы — раздутые модели, повторяющаяся логика, хаотичное распределение бизнес-функционала по слоям и неясная картина с покрытием тестами.
Отдельная боль — слой представления. Он был перегружен, бизнес-логика часто дублировалась, а предсказуемость поведения системы страдала. После нескольких неудачных попыток выровнять консистентность базы, стало понятно: нужно менять архитектурный подход.
Кроме технических причин были и организационные:
Так мы пришли к идее применить принципы чистой архитектуры даже в условиях монолитной системы.
Ключевое понятие — бизнес-правила. Это не просто требования к системе, а скорее описания того, что система должна соблюдать: нормативы, регламенты, политики и т. д. Они понятны бизнесу, в отличие от технических требований, и позволяют быстрее выявлять ошибки в постановке задач.
Реализация чистой архитектуры позволила нам строить код вокруг таких правил. Благодаря этому снизилось количество ненужных итераций, а ошибки фиксировались раньше — ещё на стадии анализа требований.
Мы выбрали анемичную (бедную) модель. Несмотря на то что она нарушает классический ООП-принцип инкапсуляции, она отлично справляется с изоляцией бизнес-логики. Это позволяло:
Сущности у нас представляли собой классы-контейнеры. Сложную бизнес-логику мы выносили в отдельные сервисы. Для примеров использовали наследование и миксины — например, сущность "Клиент" могла быть основой для сущности "Пользователь клиента".
Базовый механизм для работы с состоянием сущностей. Он позволял нам:
Благодаря этому мы могли безопасно использовать как реляционные, так и KV-хранилища, не привязываясь к конкретной реализации.
Низкоуровневый интерфейс для работы с хранилищами. Он отвечал за трансформацию сущностей и реализацию CRUD-операций. Mapper позволял:
Этот паттерн позволял отвязать слой бизнес-логики от фреймворка. Репозиторий выглядел как коллекция доменных объектов с возможностью фильтрации. Мы старались не делать логику сложной — валидация и фильтрация выносились в спецификации.
Наша система сама подберет вам исполнителей на услуги, связанные с разработкой сайта или приложения, поисковой оптимизацией, контекстной рекламой, маркетингом, SMM и PR.
Заполнить заявку
13201 тендер
проведено за восемь лет работы нашего сайта.
Позволила формализовать условия фильтрации и валидации отдельно от логики и хранилища. Мы описывали правила в явном виде — это устраняло неясности. Если возникал вопрос "почему так, а не иначе", — ответ был в спецификации.
Use-case описывал конкретный пользовательский сценарий. Он управлял:
Это сделало код модульным, переиспользуемым и проще в сопровождении. Однако у этой модульности был побочный эффект: аналитикам пришлось втянуться в бизнес глубже. Разработчики стали задавать более конкретные вопросы и ожидали точных ответов.
На практике это привело к росту нагрузки на аналитиков. Если раньше на девять человек хватало полутора аналитиков, то теперь нужен был один на троих.
Внедрение чистой архитектуры снизило энтропию в коде. Мы начали:
Толщина сервисного слоя начала уменьшаться, код стал переиспользуемым, а use-case начали мигрировать в разные части системы. Количество багов снизилось, разработчики стали лучше понимать проект, а процессы — прозрачнее.
Благодаря структуре use-case и Unit of Work мы получили видимость действий пользователей в системе. Появились метрики, графики и возможность отслеживать, где и когда возникали сбои. В связке с инструментами мониторинга это дало мощную платформу для анализа поведения пользователей и расследования инцидентов.
После внедрения чистой архитектуры каждый разработчик получил четкий алгоритм работы над задачей. Появился чек-лист: какие шаги сделать, какие артефакты получить, где фиксировать архитектурные решения.
Это:
Такой подход имеет смысл только при наличии опытной и зрелой команды. Он требует вовлеченности, самостоятельности и навыков проектирования. Все участники должны быть готовы обсуждать бизнес, архитектуру, взаимодействие и совместно принимать решения.
Важно: внедрение чистой архитектуры — это не просто «смена подхода к коду», это пересмотр всей командной культуры. Мы провели сессии по ролям, зонам ответственности, проработали процессы — только после этого изменения действительно заработали.
Хорошо реализованная чистая архитектура — это не просто способ организации кода. Это инструмент, который помогает связать бизнес и разработку, ускорить выход фич, и — да, иногда напрячь аналитиков. Но в конечном итоге — сделать проект лучше.