Когда какой подход применять
SOLID, паттерны, чистая архитектура, DDD, TDD — как выбрать правильный инструмент для конкретного проекта. Decision framework: от простого CRUD до сложного домена.
Почему это важно: Overengineering так же вреден, как и отсутствие архитектуры. DDD для простого блога — потеря времени. Голый ActiveRecord для банковской системы — катастрофа. Нужен фреймворк для принятия решений.
Главная идея
Сложность проекта определяет нужный уровень архитектуры. Простой CRUD → фреймворковые конвенции. Средняя сложность → SOLID + паттерны + Service Objects. Сложный домен → Clean Architecture + DDD. TDD применяется к любому уровню для критичной логики.
Как это выглядит на практике
- Новый проект: оценка — это CRUD-приложение или сложный домен?
- CRUD (блог, каталог): фреймворк (Rails, Django) + тесты на модели и контроллеры
- Средний (e-commerce, SaaS): Service Objects + SOLID + Repository для тяжёлых запросов
- Сложный (финтех, логистика, медицина): Clean Architecture + DDD + TDD для домена
- Ключевой вопрос: если убрать фреймворк, останется ли бизнес-логика отдельно?
- Если да — архитектура правильная. Если нет — логика вплетена в инфраструктуру
Примеры кода
Уровень 1: простой CRUD — фреймворк достаточен
# Для блога, каталога, лендинга — Rails Way
# Не нужно: Service Objects, Repository, DDD
class ArticlesController < ApplicationController
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article, notice: 'Статья создана'
else
render :new, status: :unprocessable_entity
end
end
private
def article_params
params.require(:article).permit(:title, :body, :published)
end
end
# Модель с валидациями — достаточно
class Article < ApplicationRecord
validates :title, presence: true, length: { maximum: 200 }
validates :body, presence: true
scope :published, -> { where(published: true) }
end
# Тест — простой и прямой
RSpec.describe Article do
it 'validates title presence' do
article = Article.new(title: nil)
expect(article).not_to be_valid
end
end
Уровень 2: средняя сложность — Service Objects
# E-commerce, SaaS — бизнес-логика сложнее CRUD
# Service Objects + SOLID, без полного DDD
# app/services/checkout_service.rb
class CheckoutService
def initialize(
payment: StripePayment.new,
inventory: InventoryService.new,
mailer: OrderMailer
)
@payment = payment
@inventory = inventory
@mailer = mailer
end
def call(cart:, user:)
order = Order.create!(user: user, items: cart.items, total: cart.total)
@payment.charge(order.total, user.payment_method)
@inventory.reserve(order.items)
@mailer.confirmation(order).deliver_later
order
rescue PaymentFailed => e
order&.update!(status: :payment_failed)
raise
end
end
# Контроллер тонкий
class OrdersController < ApplicationController
def create
order = CheckoutService.new.call(
cart: current_cart,
user: current_user
)
render json: order, status: :created
end
end
Decision framework: какой подход выбрать
# Задайте себе эти вопросы:
# 1. Сколько бизнес-правил?
# 0-5 правил → Rails Way (CRUD)
# 5-20 правил → Service Objects + SOLID
# 20+ правил → Clean Architecture + DDD
# 2. Сколько разработчиков?
# 1-2 человека → проще = лучше
# 3-5 человек → Service Objects + конвенции
# 5+ человек → Bounded Contexts + чёткие интерфейсы
# 3. Как часто меняются требования?
# Редко → Rails Way достаточен
# Регулярно → SOLID + паттерны для гибкости
# Постоянно → DDD + TDD для безопасного рефакторинга
# 4. Есть ли доменные эксперты (бизнес-аналитики)?
# Нет → Service Objects + здравый смысл
# Да → DDD: Ubiquitous Language + Event Storming
# 5. Критичность ошибок?
# Низкая (блог) → тесты после, Rails Way
# Средняя (магазин) → TDD для платежей и корзины
# Высокая (финтех) → TDD для всего домена + integration tests
# Золотое правило: начните просто, усложняйте при боли.
Что происходит под капотом
- Overengineering = архитектура сложнее проблемы. DDD для блога — overengineering
- Underengineering = отсутствие архитектуры при сложном домене. 2000-строчный god-object = underengineering
- Рефакторинг дешевле, чем преждевременная архитектура: начните просто, усложняйте при появлении боли
- Признаки того, что пора усложнять: тесты ломаются при несвязанных изменениях, классы > 300 строк, новые фичи = правки в 10+ файлах
- Стратегический DDD (Bounded Contexts) можно применять без тактического (Aggregates, Value Objects)
Типичные ошибки и заблуждения
- «Хорошая архитектура нужна с первого дня» — нет, хороший код нужен с первого дня, архитектура эволюционирует с проектом
- «Микросервисы = хорошая архитектура» — микросервисы без DDD Bounded Contexts = распределённый монолит, который ещё сложнее
- «TDD замедляет стартап» — TDD для критичной логики (платежи, авторизация) ускоряет стартап, потому что предотвращает дорогие баги
Ключевые выводы
- Сложность проекта определяет уровень архитектуры: CRUD → Service Objects → Clean + DDD
- Начинайте просто, усложняйте при боли: тесты ломаются, классы разрастаются, фичи дорожают
- TDD — не уровень архитектуры, а дисциплина: применяйте к критичной бизнес-логике на любом уровне
Термины урока
Связь с работой backend-разработчика
Архитектура — инструмент, а не самоцель. Правильная архитектура — та, при которой стоимость изменений минимальна для текущего и ожидаемого уровня сложности. Начните просто, мониторьте боль, усложняйте точечно.
Мини-разбор реальной ситуации
Стартап начал с DDD и чистой архитектурой для MVP интернет-магазина. 3 месяца ушло на инфраструктуру вместо фич. Конкурент запустился на Rails Way за 3 недели и захватил рынок. Урок: для MVP достаточно Service Objects, DDD добавляется при масштабировании, когда домен действительно усложняется.
Что запомнить
- Простой CRUD → Rails Way. Средний → Service Objects + SOLID. Сложный домен → DDD + Clean Architecture
- Начните просто, усложняйте при боли. Рефакторинг дешевле преждевременной архитектуры
- TDD для критичной бизнес-логики на любом уровне сложности
Итог
Нет универсально правильной архитектуры — есть подходящая для вашего проекта. Decision framework: оцените сложность домена, размер команды, частоту изменений и критичность ошибок. Начните просто, усложняйте при реальной боли.
Комментарии к уроку
Войдите, чтобы оставить комментарий.
Пока нет комментариев — будьте первым.