«Clean Architecture» интересна не схемой кругов, а вопросом, который она ставит в центр: от чего на самом деле должна зависеть система. Книга показывает, как сохранить бизнес-логику устойчивой, даже когда вокруг неё меняются базы данных, фреймворки, интерфейсы и способы доставки.
Внутри сервиса она даёт очень прикладную рамку: границы модулей, направление зависимостей, SOLID, связность и подход с подключаемыми модулями. Такой взгляд помогает отделять домен от инфраструктурных деталей и не превращать кодовую базу в хаотичную смесь сценариев использования, контроллеров и интеграций.
В интервью и архитектурных разборах эта глава добавляет глубину внутрь системы. С её помощью легче обсуждать не только внешнюю схему, но и внутреннюю архитектуру: где проходят границы ответственности и почему зависимости должны смотреть именно в эту сторону.
Практическая польза главы
Границы модулей
Учит проводить чёткие границы между доменом, приложением и инфраструктурой, чтобы снижать связанность.
Направление зависимостей
Формирует дисциплину зависимостей, чтобы бизнес-логика не зависела от деталей фреймворка.
Эволюционность кода
Помогает поддерживать систему изменяемой: проще тестировать, рефакторить и расширять функциональность.
Глубина на интервью
Позволяет аргументированно обсуждать внутреннюю структуру сервисов, не ограничиваясь общей схемой системы.
Источник
Обзор на tellmeabout.tech
Статья из клуба Code of Architecture — часть 1
Clean Architecture: A Craftsman's Guide to Software Structure and Design (Чистая архитектура. Искусство разработки программного обеспечения)
Авторы: Robert C. Martin
Издательство: Pearson, 2017
Объём: 432 страницы
Классика от Uncle Bob про ценность структуры, парадигмы программирования, SOLID, связность компонентов и архитектуру на основе плагинов.
Введение: дизайн и архитектура
Вступление книги строится вокруг простого, но очень требовательного тезиса:
"When software is done right, it requires a fraction of the human resources to create and maintain. Changes are simple and rapid. Defects are few and far between."
Архитектура = Дизайн?
Для Роберта Мартина архитектура и дизайн не противопоставлены друг другу. Это один непрерывный спектр решений: от общих границ системы до деталей реализации.
Главный вывод
“The only way to go fast is to go well” — скорость появляется не вопреки хорошей архитектуре, а благодаря ей.
Дальше книга последовательно объясняет, почему начинается с ясной ответственности перед , как ограничения , и влияют на форму системы, и почему естественным образом ведёт к .
Связанная книга
A Philosophy of Software Design
Ousterhout также говорит о борьбе со сложностью и стратегическом программировании
Два аспекта ценности ПО
Каждая программная система создаёт ценность сразу в двух измерениях:
Поведение (Behavior)
Это функциональная сторона системы: что именно она делает для бизнеса и пользователя. Именно её обычно считают срочной.
Структура (Structure)
Это внутренняя форма решения: насколько систему легко менять, тестировать и расширять. Обычно её относят к важному, но не срочному.
Автор предлагает смотреть на этот конфликт через матрицу Эйзенхауэра. На практике команды слишком часто вытаскивают наверх срочные фичи и откладывают структурные решения, от которых зависит стоимость всех следующих изменений.
"It is the responsibility of the software development team to assert the importance of architecture over the urgency of features."
Парадигмы программирования
Книга напоминает важную мысль: каждая парадигма полезна не тем, что что-то разрешает, а тем, что что-то запрещает. Именно эти ограничения и влияют на архитектуру:
| Парадигма | Ограничение | Преимущество | Для архитектуры |
|---|---|---|---|
Структурное программирование (Structured Programming) | Запрет на goto | Декомпозиция на тестируемые функции | Функциональная декомпозиция |
Объектно-ориентированное программирование (Object-Oriented Programming) | Безопасный полиморфизм | Гибкая замена реализаций и разворот зависимостей | Разделение компонентов и зависимостей |
Функциональное программирование (Functional Programming) | Неизменяемость данных | Меньше гонок данных и скрытых побочных эффектов | Разделение изменяемого и неизменяемого состояния |
Структурное программирование (Structured Programming)
Дейкстра показал, что программу можно выразить через три базовые конструкции:последовательность,выбор иитерацию. Для архитектора это важно как основа ясной декомпозиции и тестируемых сценариев.
"Testing shows the presence, not the absence, of bugs" — Дейкстра
Объектно-ориентированное программирование (Object-Oriented Programming)
Объектно-ориентированное программирование сочетает инкапсуляцию, наследование и полиморфизм. Для архитектора ключевым становится именно полиморфизм: он позволяет разворачивать зависимости в сторону абстракций и разрабатывать детали независимо друг от друга.
"OO is the ability to gain absolute control over every source code dependency in the system."
Функциональное программирование (Functional Programming)
Главная идея здесь — неизменяемость данных. Для архитектуры это означает меньше и . Из этого же мышления выросло и как способ восстанавливать состояние через журнал изменений.
"Event sourcing is a strategy wherein we store the transactions, but not the state."
Часть 2
Обзор на tellmeabout.tech
SOLID и принципы компонентов
Принципы проектирования (SOLID)
Принципы SOLID помогают строить структуры среднего уровня, которые:
- легко менять без лавины побочных эффектов
- просты для понимания
- становятся хорошей основой для переиспользуемых компонентов
Принципы SOLID
Кликните на букву для подробностей
SПринцип единственной ответственности (SRP)
Не “функция должна делать одну вещь”, а модуль должен отвечать перед одним актором. Обычно нарушение видно по повторяющимся изменениям в разных местах и конфликтующим правкам при совместной работе.
OПринцип открытости и закрытости (OCP)
Артефакт должен быть открыт для расширения, но закрыт для изменения уже работающего ядра. Именно так архитектура начинает защищать стабильные части системы от постоянной переделки.
LПринцип подстановки Лисков (LSP)
Подтипы должны быть взаимозаменяемы с базовыми типами. Если это не так, код быстро обрастает ветвлениями и специальными случаями под каждую конкретную реализацию.
IПринцип разделения интерфейсов (ISP)
Клиент не должен зависеть от методов, которые ему не нужны. На архитектурном уровне это означает: не заставляйте компонент тянуть за собой лишние контракты и лишнее поведение.
DИнверсия зависимостей (Dependency Inversion Principle, DIP)
Наиболее гибкие системы — те, где зависимости в коде смотрят только на абстракции. Фабрики помогают вынести создание конкретных реализаций за пределы бизнес-логики и удержать домен в стабильной зоне.
Инверсия зависимостей (Dependency Inversion, DIP)
Как абстракции и фабрика меняют направление зависимостей
Проблема: прямая зависимость
Application напрямую зависит от ConcreteImpl — это делает систему жёсткой и плохо расширяемой.
Связанная книга
Fundamentals of Software Architecture
Richards и Ford развивают тему связности компонентов и согласованности изменений через Connascence
Принципы компонентов
Компоненты — это единицы развёртывания. За десятилетия практика пришла к простому выводу: устойчивое ядро и подключаемые детали почти неизбежно ведут нас к архитектуре на основе плагинов.
Здесь особенно полезно вместе рассматривать , и : книга объясняет, какие элементы должны меняться вместе, а какие лучше держать отдельно.
Связность компонентов
Три принципа определяют, как разбивать классы по компонентам:
REP
Эквивалентность переиспользования и релиза (Reuse/Release Equivalence)
Классы, которые выпускаются вместе, должны иметь общую тему или общую причину существовать рядом.
CCP
Совместное закрытие на изменение (Common Closure)
Держите вместе те классы, которые обычно меняются по одной и той же причине и в одно и то же время.
CRP
Общее переиспользование (Common Reuse)
Не заставляйте пользователей компонента зависеть от того, что им на самом деле не нужно.
Диаграмма напряжения: связность компонентов
Архитектору приходится балансировать между этими принципами в зависимости от того, что системе важнее: переиспользование, независимые релизы или локальность изменений.
Связанность компонентов
Следующие принципы уже отвечают не за состав компонентов, а за отношения между ними:
ADP: Acyclic Dependencies Principle
Не допускайте циклов в графе зависимостей компонентов.
Граф зависимостей должен оставаться направленным ациклическим графом. Если цикл всё же появился, его обычно разрывают через абстракцию и инверсию зависимостей.
SDP: Stable Dependencies Principle
Зависите в сторону более стабильных компонентов.
Полезно смотреть на метрики Fan-in и Fan-out: чем больше входящих зависимостей и меньше исходящих, тем стабильнее компонент. Метрика I = Fan-out / (Fan-in + Fan-out) помогает эту интуицию быстро проверить.
SAP: Stable Abstractions Principle
Компонент должен быть настолько абстрактным, насколько он стабилен.
Метрика A = Na / Nc показывает долю абстракций. В паре с SDP этот принцип фактически переносит инверсию зависимостей на уровень компонентов.
Диаграмма ниже показывает, как компоненты тяготеют к и почему системе вредно застревать в зоне боли или зоне бесполезности.
Главная последовательность и зоны риска
Идеальная диагональ: баланс между абстрактностью и стабильностью. Формула: D = |A + I - 1|
Конкретные и стабильные компоненты (A≈0, I≈0). Их трудно менять, потому что на них завязано много зависимостей.
Абстрактные и нестабильные компоненты (A≈1, I≈1). Много абстракций, но мало связи с реальными реализациями.
Главный архитектурный вывод
Структуру нельзя откладывать
Если архитектура остаётся “на потом”, каждая следующая доработка становится дороже и болезненнее предыдущей.
Архитектура на основе плагинов (Plugin Architecture)
Полиморфизм и инверсия зависимостей позволяют развивать детали отдельно от ядра и не превращать инфраструктуру в центр системы.
Эволюция структуры
Границы компонентов и правила зависимости не фиксируются навсегда: они должны меняться вместе с продуктом, но без потери внутренней дисциплины.
Главная последовательность (Main Sequence)
Хорошая архитектура удерживает баланс между стабильностью и абстрактностью, чтобы компоненты не скатывались ни в жёсткость, ни в бесполезную абстракцию.
Источники
Связанные главы
- Что такое архитектура ПО и зачем она нужна в системном дизайне - даёт общую архитектурную рамку, в которой Clean Architecture становится частью системного дизайна, а не только внутреннего устройства кода.
- Fundamentals of Software Architecture (краткий обзор) - дополняет тему через качественные характеристики, архитектурные стили и системные компромиссы.
- Software Requirements (краткий обзор) - связывает границы и зависимости с корректной формулировкой требований и управлением объёмом решения.
- A Philosophy of Software Design (краткий обзор) - расширяет взгляд на управление сложностью и проектирование интерфейсов, которые упрощают сопровождение.
- Стратегии декомпозиции - переводит принципы Clean Architecture в практику выделения сервисных границ и зон ответственности.
- Архитектура в масштабе: как мы принимаем архитектурные решения - показывает, как фиксировать архитектурные решения в документах и управлять их эволюцией в команде.
