Что такое Clean Architecture
Что проверяют
Понимаете ли вы правило зависимостей и умеете ли применить его к iOS-приложению, а не пересказать схему с кругами. Второе, что слушают, это трезвость: видите ли вы цену и понимаете ли, где она не окупается.
Как отвечать
Идея одна: зависимости в исходном коде направлены внутрь, к правилам предметной области. Слои от центра наружу: сущности (правила, не зависящие от приложения), сценарии использования (операции конкретного приложения), адаптеры (презентеры, вью-модели, репозитории, мапперы), внешний слой (UIKit и SwiftUI, сеть, хранилище, системные фреймворки). Внутренние слои ничего не знают о внешних: если сценарию нужны данные, он объявляет протокол у себя, а реализацию подставляет внешний слой.
Как это выглядит в iOS:
- домен отдельным модулем или таргетом, который собирается без импорта UIKit, это и есть проверка чистоты;
- репозиторий объявлен протоколом в домене, реализован поверх URLSession или хранилища, объекты передачи данных отображаются в сущности и наружу не протекают;
- MVVM, VIPER и подобное это способ доставки, то есть внешний слой, а не архитектура целиком;
- сценарии тестируются на подменённых зависимостях, без сети и симулятора.
Цена честная: больше типов, протоколов и преобразований. На небольшом экране это лишняя работа, окупается на долгоживущем приложении со сложными правилами и несколькими разработчиками.
Где спотыкаются
Формулируют правило наоборот: верхние слои якобы не зависят от нижних. На деле детали (интерфейс, сеть, база) зависят от домена, а домен не зависит ни от чего.
Заводят каталоги Domain, Data и Presentation, но тащат в сценарии типы фреймворков: модель с разбором ответа API как сущность, объект хранилища как доменный тип, сетевой клиент прямо в сценарии. Папки появились, зависимости остались прежними.
Пишут сценарии-пустышки, которые лишь пробрасывают вызов в репозиторий, и плодят протоколы с единственной реализацией ради тестируемости, которой никто не пользуется. В итоге тестами покрыты мапперы, а правила, ради которых всё затевалось, не покрыты.