Как устроены слои в чистой архитектуре?
Что проверяют
Понимаете ли вы правило зависимостей и умеете ли перенести схему Роберта Мартина на реальный iOS-проект: модули, протоколы, SwiftUI или UIKit. Следом обычно спрашивают, как это соотносится с MVVM или VIPER и где в вашем проекте живёт Core Data.
Как отвечать
Четыре круга, от центра наружу:
- Entities: доменные модели и правила. В Swift это
structбезimport UIKitи безNSManagedObject; - Use Cases: сценарии приложения, например
PlaceOrderUseCase. Работают с протоколами репозиториев, обычно черезasync throwsфункции; - Interface Adapters: ViewModel или Presenter, которые готовят данные к показу, и реализации репозиториев, переводящие ответы
URLSessionили объекты Core Data в доменные модели; - Frameworks & Drivers: UIKit, SwiftUI,
URLSession, Core Data, SwiftData, сторонние SDK.
Главное правило: зависимости в коде направлены только внутрь. Протокол OrderRepository объявлен рядом с use case, а RemoteOrderRepository реализует его снаружи. Сборка происходит в composition root: в типе с @main для SwiftUI или в SceneDelegate, зависимости передаются через инициализатор.
Границы удобно закрепить модулями Swift Package Manager: пакет Domain не зависит ни от чего, Data и Presentation зависят от Domain. Тогда запрещённый импорт просто не скомпилируется. Use case тестируется с фейковым репозиторием в XCTest или Swift Testing, без симулятора.
Полезно показать связь с тем, что интервьюеру уже знакомо: MVVM или VIPER описывают внешний, презентационный круг, а чистая архитектура говорит о том, как этот круг отделён от бизнес-логики и данных.
Где спотыкаются
Делают NSManagedObject доменной моделью. Он привязан к своему контексту и его очереди, и эта привязка протекает во все слои, включая ViewModel.
Путают направление: говорят, что внутренний слой вызывает внешний и поэтому от него зависит. Вызов может идти наружу, но через протокол, который принадлежит внутреннему слою.
Строят полный набор слоёв с мапперами для приложения из трёх экранов. Сильный ответ называет, когда это окупается: большая команда, долгоживущий продукт, общая логика между таргетами.