Что такое правильная архитектура iOS приложения?

Nefedov Denis
Спорим с архитектором
4 min readMar 22, 2020

В прошлой статье я рассказал, почему MVC, MVP и MVVM — это не архитектура всего приложения. Сегодня в посте с провокационным заголовком хотелось бы поговорить о том, как же все-таки она должна выглядеть — “правильная архитектура” приложения на мой нескромный взгляд.

Начнем с того, что сразу расстроим приверженцев какого-то конкретного шаблона. Не существует единственного самого крутого паттерна. VIPER не спасет вас от всех проблем — об этом я расскажу в следующий раз, а MVC в далеко не идущем проекте может оказаться хорошим решением.

Архитектурное решение подбирается индивидуально под каждый проект. Не существует волшебной пилюли, которая подойдет всегда и всем.

От чего же зависит выбор этого самого решения?

Основными факторами влияющими на проектирование архитектуры являются время поддержки проекта и его перспективы. Если проект собирается развиваться и его нужно будет долго поддерживать, то стоит заранее подумать о масштабируемой архитектуре.

Решение архитектурных задач оказывает наибольшее влияние на проект в долгосрочной перспективе.

В моем понимании архитектура — это структурирование намерений(intents) системы, которую мы строим. То есть, понимание domain problem и дизайн(построение) хорошей структуры, которая решает эту проблему. Хорошая/правильная структура должна быть мягкой от слова soft (software engineering), поскольку за время жизни проекта требования могут меняться, цели бизнеса могут меняться, ситуация на рынке может измениться…и т.д. Поэтому архитектура проекта должна позволять подстраиваться и вносить быстрые изменения.

Когда у нас soft архитектура, то команда может четче прогнозировать сроки возникших правок и вносить их быстрее, работая при этом параллельно(на предыдущей работе я неоднократно сталкивался с ситуацией невозможности распараллелить задачу между разрабами из-за плохой архитектуры. Особенно часто с этим сталкиваешься, когда проект уже зрелый и в нем накопилась масса неправильных решений(чаще всего проблемы tight coupling). При хорошей архитектуре продуктивность команды должна оставаться на том же уровне, что и вначале проекта).

Многие воспринимают архитектуру ПО как архитектуру зданий — один раз построили и дальше что-то поменять уже крайне сложно. Это неправильный подход. Архитектура должна уметь двигаться и развиваться вместе с жизненным циклом проекта, а также позволять быстро вносить правки.

На мой взгляд, лучше всего вышеперечисленным требованиям соответствуют принципы Clean Architecture от дядюшки Боба. В ней он предлагает делить всю систему на отдельные слои с минимальной зависимостью друг от друга.

Основное правило заключается в том, что нижний слой ничего не должен знать о верхнем слое и зависимость должна оставаться однонаправленной. Довольно абстрактно? Разберем на конкретном примере.

Возьмем популярную задачу в среде iOS разработки, например, ленту новостей. Таким образом у нас появляется отдельная фича. У заказчика есть конкретные требования к этой фиче. Мелкие детали опустим, выделим крупные Use cases: лента новостей должна грузиться по сети и, например, кэшироваться. Как же будет выглядеть soft и clean архитектурное решение?

Начнем с максимально абстрактной картины и будем постепенно спускаться к деталям реализации.

В центре всей архитектуры у нас Feed Feature. Это платформонезависимые модели и интерфейсы, которые относятся к бизнес-логике нашей фичи. Они не имеют никакой зависимости от окружения, будь то слой презентации или UI.

Следующий слой — это use cases нашей фичи: модуль для работы по сети, модудь для кэширования, модуль презентации. Здесь лежит реализация интерфейсов сервисов из нашего ядра. Этот слой зависит только от ядра архитектуры.

Поднимаемся на уровень выше. Здесь находятся инфрастуктурные адаптеры, которые позволяют слою презентации не зависеть от фреймворков и используемых библиотек. Этот слой уже зависит от платформы и фреймворков.

Придерживаясь данной архитектуры, мы получаем четкое разделение ответственностей и возможность быстро и легко подменять реализации/фреймворки/платформы. Можно легко заменить URLSession для работы с сетью на Alamofire не трогая при этом бизнес логику и ее презентацию. Можно легко перейти на swiftUI, поменяв при этом только UI слой и т.д.

Четкое разделение зависимостей каждого модуля

Я разобрал архитектуру только одной фичи. Как же будет выглядеть архитектура всего приложения, где много фич?

Выводы

MVC, MVVM, MVP… все это лишь UI дизайн паттерны, которые не были созданы для того, чтобы решать задачи всего приложения.
Архитектура должна быть гибкой и позволять разработчикам быстро и легко адаптироваться под изменяющуюся окружающую среду.

Архитектура каждого проекта должна быть индивидуальной и зависеть исключительно от поставленных задач. Для мелких и простых проектов высокий уровень абстракции может стать попросту overengineering’ом.

To be continued…

В следующий раз разберем, какое место в правильной архитектуре занимают VIPER и VIP, какие у них есть проблемы и как с этим жить.

Если статья наберет большую популярность, то сделаю продолжение, где архитектура из примера выше будет разобрана на уровне сущностей классов и связей между ними.

Полезные материалы

Один из моих любимых постов про Layered архитектуру от Vadim Bulavin
Еще один наикрутейший пост про слоистую архитектуру от Redmadrobot
Отличный канал для iOS разработчиков, без которого не было бы этого блога.

--

--