Понятие «чистая архитектура» пошло из одноименной статьи Роберта Мартина 2012 года. Оно включает в себя несколько принципов:
- Независимость от фреймворков. Архитектура не должна полагаться на существование какой-либо библиотеки. Так вы сможете использовать фреймворки как инструменты, а не пытаться загнать свою систему в их ограничения.
- Тестируемость. Бизнес-логика должна быть тестируемой без любых внешних элементов вроде интерфейса, базы данных, сервера или любого другого элемента.
- Независимость от интерфейса. Интерфейс должен легко изменяться и не требовать изменения остальной системы. Например, веб-интерфейс должен заменяться на интерфейс консоли без необходимости изменения бизнес-логики.
- Независимость от базы данных. Ваша бизнес-логика не должна быть привязана и к конкретным базам данных.
- Независимость от любого внешнего агента. Ваша бизнес-логика не должна знать вообще ничего о внешнем мире.
Отражение этих принципов в архитектуре программного обеспечения можно представить следующим образом:
В этой схеме слои обозначают:
- Entities — бизнес-логика, общая для всех приложений, а в случае отдельного приложения — наиболее базовые бизнес-объекты.
- Use Cases — логика приложения, “сценарии применения”, которые управляют потоком данных из предыдущего слоя.
- Interface Adapters — адаптеры между Use Cases и внешним миром. Этот слой конвертирует данные в формат, подходящий для внешних слоев, например Web или базы данных, а также превращает внешние данные в формат для внутренних слоев.
- Frameworks and Drivers — внешний слой, содержащий фреймворки, инструменты, базы данных и так далее. В этом слое код должен связываться с предыдущим слоем, но не влиять в значительной степени на внутренние слои.
Все слои связаны правилом зависимости — Dependency Rule, которое гласит, что в исходном коде все зависимости могут указывать только вовнутрь. Например, ничто из внешнего круга не может быть упомянуто кодом из внутреннего круга. Это относится к функциям, классам, переменным или любым другим сущностям. Сам Uncle Bob говорит, что эту схему можно изменять: добавлять или убирать слои, но основным правилом в архитектуре приложения должно всегда оставаться Dependency Rule.
Чистая архитектура в iOS-разработке
Для iOS-разработки чистая архитектура реализована в модели VIP или VIPER, которая позиционируется как замена шаблону MVC. Модель VIP (View — Interactor — Presenter) выглядит следующим образом:
Подробнее о каждом компоненте:
- Models — класс, содержащий структуры Request, Response, ViewModel;
- Router — простой компонент, передающий данные между viewControllers;
- Worker — компонент для управления запросами и ответами API/CoreData, а также передачи информации об успехе или неудаче к Interactor.
- Interactor — посредник между Worker и Presenter. Сначала он связывается с ViewController, который передает все параметры запроса, необходимые для Worker. До передачи данных к Worker, выполняется проверка, и если все в порядке, Worker возвращает ответ, и Interactor передает ответ на Presenter.
- Presenter — Response от Interactor форматируется в ViewModel и передается на ViewController. Presenter отвечает за логику отображения и решает, как данные будут представлены пользователю.
- Configurator — “суперкласс”, который инициализирует все упомянутые выше компоненты.
Примеры проектов с чистой архитектурой на iOS:
- Library — приложение, иллюстрирующее концепции MVP и Clean Architecture;
- Clean Store — пример архитектуры Clean Swift;
- Приложение для Twitter, созданное на основе подхода чистой архитектуры;
- Чистая архитектура с RxSwift.
Чистая архитектура в Android-разработке
Схему чистой архитектуры Android-приложений предложил разработчик Фернандо Сехас. Выглядит она так:
Внутренним слоем в этом случае является Domain Layer, который хранит всю бизнес-логику. В этом же слое находятся и все use cases и реализации. Этот слой является чистым модулем Java без Android-зависимостей. При связи с этим слоем все внешние компоненты используют интерфейсы.
В Presentation Layer происходит логика, связанная с представлениями и анимациями. Он использует модель Model View Presenter, но шаблон может быть другим, например, MVC или MVVM. Фрагменты и активности в этом слое — это представления, в которых происходит только UI-логика и изменение формата данных. Presentors в этом слое формируются из interactors (use cases), которые производят работу вне основного потока UI Android и возвращаются с данными, которые обрабатываются в View.
Data Layer передает все данные через UserRepository, который использует Repository Pattern со стратегией, выбирающей разные источники данных в зависимости от условий. Например, при поиске пользователя по ID с условием существования пользователя в кэше источником данных будет кэш, в ином случае для получения данных будет отправлен запрос в облако. Источник данных прозрачен для клиента, которого волнует, будут ли получены данные.
Пример приложения, созданного автором, чтобы проиллюстрировать свои схемы, можно посмотреть здесь. Другие примеры чистой архитектуры на Android:
- Easy MVP — фреймворк для создания приложений по принципу чистой архитектуры;
- Шаблон для создания приложения с чистой архитектурой на Kotlin;
- Пример приложения на Java.