Введение: вопрос, который отличает junior от middle
«Что такое Clean Architecture?» — вопрос, который на Android-собеседованиях отличает junior от middle быстрее любого другого. Junior называет модный термин. Middle объясняет слои, правило зависимостей и показывает, как это выглядит в коде.
Я провожу технические собеседования и могу сказать точно: формулировка «Clean Architecture — это когда код разделён на слои» засчитывается только как начало ответа. Дальше проверяется глубина: какие слои, кто от кого зависит и что ломается, если зависимости направлены неправильно. В этой статье разберу концепцию — от исходной идеи Роберта Мартина до официальных рекомендаций Google для Android.
Что такое Clean Architecture
Clean Architecture — подход к проектированию, который описал Роберт Мартин (в сообществе известный как Uncle Bob). Основная идея: разделить приложение на концентрические слои ответственности так, чтобы бизнес-правила не зависели от фреймворков, UI и базы данных. В центре — сущности и бизнес-логика, снаружи — всё, что привязано к конкретной платформе.
В классической схеме четыре слоя, от центра к периферии:
| Слой | Что живёт внутри | Примеры в Android |
|---|---|---|
| Entities | Бизнес-сущности и правила | доменные модели, User, Order |
| Use Cases | Сценарии приложения | GetProfileUseCase, SaveNoteUseCase |
| Interface Adapters | Адаптеры между слоями | интерфейсы репозиториев, мапперы |
| Frameworks & Drivers | Всё внешнее | Activity, Retrofit, Room, Compose |
Суть одной фразой
Clean Architecture — это бизнес-правила в центре, платформа по краям, зависимости направлены только внутрь. Внутренние слои ничего не знают о внешних: сущность не знает про Retrofit, use case не знает про Activity.
Обратите внимание на четвёртый слой: сюда попадает весь Android как таковой. Именно поэтому Clean Architecture любят на собеседованиях — она проверяет, умеете ли вы отделять логику от платформы.
Слои и их ответственность
Разберём слои чуть глубже, потому что именно в деталях кандидаты сыплются.
Entities — бизнес-модели и правила, которые не зависят ни от чего. В Android это обычно чистые Kotlin-классы: data class User(...), sealed-классы состояний. Они не знают ни про Room, ни про Retrofit.
Use Cases — сценарии использования приложения. Каждый use case делает одно дело: получить профиль, сохранить заметку, обновить корзину. В Android-проектах их называют также interactors.
class GetProfileUseCase(
private val repository: ProfileRepository
) {
suspend operator fun invoke(userId: String): Profile =
repository.getProfile(userId)
}Interface Adapters — прослойка, которая переводит данные между use case и внешним миром. Здесь живут интерфейсы репозиториев, мапперы между DTO и доменными моделями.
Frameworks & Drivers — всё, что относится к платформе: Activity и Fragment, Retrofit, Room, DI-контейнер. Здесь же — реализации интерфейсов из слоя адаптеров.
interface ProfileRepository {
suspend fun getProfile(userId: String): Profile
}
class ProfileRepositoryImpl(
private val remote: ProfileRemoteDataSource,
private val local: ProfileLocalDataSource
) : ProfileRepository {
override suspend fun getProfile(userId: String): Profile {
return remote.getProfile(userId).let { profile ->
local.saveProfile(profile)
profile
}
}
}Обратите внимание: GetProfileUseCase зависит от интерфейса ProfileRepository, а не от ProfileRepositoryImpl. Реализация с Retrofit и Room осталась во внешнем слое — значит, в тестах её можно заменить фейком, не трогая бизнес-логику. Это и есть смысл правила зависимостей.
Направление зависимостей
Главное правило Clean Architecture формулируется просто: исходные зависимости направлены внутрь — от внешних слоёв к внутренним. Внутренний слой не знает, какие внешние существуют.
В терминах Android-разработки это означает:
- UI-слой (Activity, ViewModel) зависит от домена — но не наоборот.
- Доменный слой зависит от абстракций данных (интерфейсов) — а не от Room и Retrofit.
- Реализации данных зависят от домена, реализуя его интерфейсы.
Это же правило подтверждает официальная документация Google по архитектуре: слои приложения — UI, data и опциональный domain — связаны зависимостями в одну сторону, от UI к данным.
Почему это работает
Если зависимости направлены внутрь, бизнес-логика становится независимой от платформы. Меняете Retrofit на Ktor — не трогаете домен. Переносите приложение на новую платформу — домен переезжает как есть. Плюс тестируемость: логика проверяется на JVM без эмулятора.
Clean Architecture в Android: что говорит Google
Теперь свяжем теорию с практикой Android. Официальный гайд Google по архитектуре приложений выделяет три слоя:
- UI layer — отображает данные на экране: UI-элементы и state holders (например, ViewModel).
- Data layer — содержит бизнес-логику приложения: репозитории, каждый из которых работает с источниками данных.
- Domain layer — опциональный слой между UI и data: use cases, которые инкапсулируют сложную или переиспользуемую логику.
Google прямо пишет, что доменный слой не обязателен — его добавляют, когда есть сложная логика или логика, переиспользуемая несколькими ViewModel. Если все use case сводятся к «позвони в репозиторий» — доменный слой просто лишний код.
Кроме слоёв, в официальных рекомендациях есть ещё два принципа, которые стоит упомянуть на собеседовании:
- Single source of truth — у каждого типа данных одно каноническое место хранения.
- Unidirectional data flow (UDF) — состояние течёт в одну сторону, события — в другую.
Сильный ответ на собеседовании: «Clean Architecture — это принцип организации, а не модуль проекта. В Android его практическим выражением стали рекомендации Google: UI-слой с state holders, data-слой с репозиториями и опциональный domain-слой с use cases. Зависимости направлены в одну сторону, состояние движется по UDF». Такой ответ показывает и теорию, и знание официальной позиции Google.
Ошибки на собеседованиях
На собеседованиях по Clean Architecture промахи повторяются из раза в раз. Вот типичный набор.
- «Clean Architecture — это три модуля: app, domain, data». Нет. Это принцип организации кода, а не структура модулей. Модули — один из способов его реализовать, но можно делать слои и в одном модуле.
- «Доменный слой обязателен». Google прямо называет его опциональным. Добавляйте use cases, когда есть сложная или переиспользуемая логика, а не «чтобы было».
- «Use case на каждый вызов репозитория». Если use case просто пробрасывает вызов — это лишний слой. Такое решение принимают по критерию сложности, а не по шаблону.
- «Clean Architecture = MVVM». Это разные вещи: MVVM — паттерн для UI-слоя, Clean Architecture — организация всего приложения. MVVM может жить внутри Clean Architecture, но не заменяет её.
- «Зависимости можно в обе стороны». Нет. Нарушение правила зависимостей превращает слои в кашу, где домен знает про Retrofit, а тестировать ничего нельзя.
Слоя классической схемы
Entities, Use Cases, Interface Adapters, Frameworks & Drivers — четыре уровня ответственности. Назвать их и объяснить правило зависимостей — это уже ответ уровня middle.
Когда я готовлю людей к собеседованиям, я вижу, что архитектура — самый частый пробел у разработчиков с опытом 1–2 года: паттерны знают по названиям, а объяснить, зачем направлять зависимости внутрь и почему доменный слой опционален, не могут. Я провожу технические собеседования и помогаю такие пробелы закрывать — разбираю уровень, показываю, что учить, и тренирую ответы.
Нужна помощь с переходом на middle?
Бесплатная диагностика: разберу ваши пробелы в архитектуре и составлю план роста за 30–40 минут. Без обязательств — если менторство вам не подойдёт, честно скажу.
Итоги
Clean Architecture — это не про красивые диаграммы, а про конкретную инженерную выгоду. Три тезиса для собеседования:
- Слои от центра к периферии: Entities → Use Cases → Interface Adapters → Frameworks & Drivers. Бизнес-логика в центре, платформа по краям.
- Правило зависимостей: исходные зависимости направлены внутрь. Внутренние слои не знают о внешних, поэтому логику можно тестировать без эмулятора, а Retrofit и Room менять без боли.
- Практика Android: официальный гайд Google — UI-слой, data-слой и опциональный domain-слой. Доменный слой добавляют при сложной или переиспользуемой логике, а не по шаблону.
Главное, что нужно запомнить
Clean Architecture — это не структура модулей и не MVVM, а принцип: бизнес-правила не зависят от платформы, зависимости направлены внутрь. Начните ответ с этой формулировки — и интервьюер увидит, что вы понимаете тему, а не выучили термины.
Если архитектура — ваше слабое место и вы не знаете, с чего начать подготовку, — не нужно читать всё подряд. Напишите в Telegram, разберём вашу ситуацию и составим план закрытия пробелов под ваш уровень.