Комментарии 6
На схеме ниже каждый компонент каждого слоя показан с направлением зависимости и Data Flow (Request/Response). Мы можем видеть инверсию зависимостей (Dependency Inversion), которая указывает, где мы используем интерфейс репозитория(протоколы). Объясним каждый слой на примере проект, который упоминали в начале статьи.
у вас же на схеме одни сущности, а дальше в описании - другие
Так для чистой архитектуры есть SwiftUI, зачем вы рассказываете про каменный век?
Вообще говоря, "чистая архитектура" не является архитектурным паттерном (таким, как, например, CQRS), или же архитектурным стилем (таким, как "слоенная", "гексагональная", или "микросервисная"). Она больше относится к тому что в книге Марка Ричардса и Нила Форда "Fundamentals of Software Architecture" определяется как "архитектурные решения", т.е. набор правил которым должна следовать реализация системы. "Архитектурный стиль" при этом может быть по сути каким угодно. Сам Р. Мартин в своей книге нигде её как какую-то разновидность ("стиль") архитектуры и не определяет.
Вы хотя бы для уважения читающего поправьте форматирование кода и вот эти приколы (я про < и т.д): Result<MoviesPage, Error>) -> Void)
Зависимости в коде бывают ооооочень разными.
Все публикуемые примеры архитектур обычно исправляют только самые очевидные зависимости и пропускают менее очевидные неявные, при этом делают иногда еще хуже.
Конкретно в обоих этих примерах не устранена скрытая контекстная зависимость. ViewModel вынуждена знать и говорить на языке View: все эти методы "didSearch", "didSelect", "viewDidLoad" и замыкания (названные в статье "кложурами") для вызова View кода из ViewModel прям кричат о том, что они опустились туда, куда не должны были.
Это приводит к нарушению единой ответственности - при изменении View, приходится менять и вьюмодель вот из-за таких неявных контекстных зависимостей.
Также теряется возможность переиспользовать вьюмодель на других платформах, где логика отображения будет другой и не будет иметь метода viewDidLoad (т.е. мы в нашу вьюмодель внесли зависимость от платформы, под которую написан UI). Например, будет тяжело переиспользовать эту ViewModel в консольном приложении.
Исправляется довольно просто. В обоих случаях ViewModel становится свободной о знании деталей реализации View.
Из ViewModel удаляются замыкания. ViewModel просто возвращает управление вьюхе из той функции, где вызывалось замыкание, а уже View коммуницирует с координатором и осуществляет нужный переход.
С функциями типа "viewDidLoad" аналогично. Скорее всего эта функция должна быть во вьюхе и напрямую вызывать смысловые методы вьюмодели, которые уже объявлены в интерфейсе.
Также имеет смысл почитать, а что же такое замыкание и для чего оно должно быть использовано. Использование замыканий не по назначению – все равно, что саморезы в бетон молотком забивать – только хуже станет, даже если кажется, что будет лучше.
В остальном – статья глубокая. Автор молодец. Переводчик тоже – добро пожаловать в расширенный аккаунт на Хабре :)
Clean architecture и MVVM в iOS разработке