Pull to refresh

MVC без C: Что изменит SwiftUI в архитектуре приложений?

Reading time 4 min
Views 8K
Original author: Matěj Kašpar Jirásek
MVC был давним стандартом в паттернах проектирования, используемых для написания iOS приложений. Структура iOS приложений, которые создавались ранее, была основана на одном базовом компоненте, который присутствует везде, и называется он — Controller. На WWDC19 был представлен SwiftUI, который не имеет такого компонента.

Проблема с так называемыми massive view-controllers должна быть решена в SwiftUI. Так, необходимо найти новый способ правильной декомпозиции кода. Давайте посмотрим на текущее состояние платформы и подумаем, какие парадигмы мы можем использовать при разработке для iOS13 и более поздних версий.

image

Однонаправленные и двунаправленные архитектуры


Большенство архитектурных решений, которые используют крупные корпорации являются двунаправленными. Это означает, что вы можете думать о них как о слоях друг над другом и они могут общаться между собой передавая данные как вверх, так и вниз. Такие шаблоны, как MVC, Model-View-ViewModel и даже многие реализации паттерна MVVM с координаторами, также являются двунаправленными архитектурами.

Примером широко используемого в настоящее время однонаправленного потока данных на платформе iOS является цикл VIP (представление-интерактор-презентатор) в архитектурах Clean Swift или Viper. Эти архитектуры не являются чисто однонаправленными. Router и исполняемые модули связываются с циклом VIP в обоих направлениях.

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

Data flow в SwiftUI


Согласно презентации WWDC, элемент, соединяющий view и model/state в SwiftUI, был некий класс Store, соответствующий протоколу BindableObject. Нам остается только надеяться, что у нас не будет приложений с massive store, содержащим всю логику приложения со всеми состояниями без какой-либо четкой структуры. Я считаю, что iOS сообщество, достаточно продвинуто и может добиться большего успеха в этом направление.

Если мы поместим MVC и SwiftUI с view и store рядом друг с другом, мы сможем увидеть почти один и тот же шаблон, который может привести к аналогичным проблемам, которые были у нас с контроллером представления, но без какого-либо стандартного кода, что VC имеет по своей природе.

image
Если вы поместите MVC и store в диаграмме, они могут выглядеть примерно так.

На первый взгляд может показаться, что Combine может быть архитектурным паттерном, используемым в SwiftUI. Но Combine — это всего лишь инструмент для обработки значений во времени. Точно так же MVVM, использующий RxSwift, по-прежнему MVVM, просто связь между уровнями, которая реализуется разными способами.

Декларативная архитектура для декларативных пользовательских интерфейсов


SwiftUI может быть кратко изложен в нескольких словах, таких как декларативный пользовательский интерфейс. Я считаю, что можно добиться большего, если мыслить нестандартно и сосредоточиться на слове «декларативный». Самые передовые декларативные архитектурные примеры могут быть найдены при разработке front-end приложений. Такие концепции как ELM, Redux и Flux могут быть легко использованы с инфраструктурой SwiftUI и Combine. Для Swift уже было несколько повторных реализаций таких, как ReSwift, но все же необходимым было бы объединить эти реализации в Combine.

image
Слегка измененный Data Flow в SwiftUI из WWDC19

Мне бы хотелось поиграть с SwiftUI с самого начала без каких-либо зависимостей, и в настоящее время я экспериментирую в Swift с простой реализацией архитектуры ELM. Эта архитектура лучше соответствует диаграммам, которые Apple показала на WWDC.

Мы можем описать приложение посредством данных архитектурных паттернов:

  • Action — это тип, описывающий все события, которые могут произойти в приложении. (В простом приложении это может быть enum с некоторым связанным значением, в крупномасштабном приложении можно использовать множество структур, соответствующих протоколу действий.)
  • Update (или reducer в Redux) — это простая чистая функция, которая принимает текущее состояние и отправленное действие и возвращает новое измененное состояние. (Эти функции не создают сайд эффектов и могут быть легко объединены.)
  • State — это тип, описывающий состояние приложения. (Простой список задач, может использовать массив.)

Все эти три элемента являются декларативными, и каждый из них представляет собой одну небольшую тестируемую и многократно используемую часть головоломки, которая вместе составляет целое приложение. Состояние хранится в Store, и представление может быть вычислено из него.

image
State, Actions и update для простого приложений на Swift.

Для асинхронных операций мы могли бы ввести что-то вроде объекта middleware в Redux или Commands в ELM.

Заключение


Мы можем либо использовать любые известные нам архитектуры, и когда мы постепенно добавим SwiftUI к существующим в настоящее время приложениям, это будет надежным и безопасным подходом. В случае, если реализуется новое приложение используя только SwiftUI, можно использовать более открытый подход и попробовать что-то другое.

Если вы задумаетесь о разработке приложения с использованием SwiftUI в ближайшее время, я бы порекомендовал обратить внимание на некоторые моменты:

  • Apple не предоставляет детального руководства по архитектуре приложений, это означает, что у нас как у сообщества программистов есть много возможностей для инноваций и реализаций новых подходов.
  • Мы определенно увидим гораздо более широкий масштаб различных кодовых баз, поскольку дыра, оставленная после контроллера представления, должна быть заполнена.
  • Сохраняйте открытость и не бойтесь начинать с нуля.

Мои эксперименты можно найти в playground Swift (для сравнения – представлена реализации и использовании UIKit и SwiftUI, одного и того же приложения).

Следующие шаги


Существует много способов, которыми мы можем воспользоваться, но я настоятельно склонен наконец опробовать гораздо более функциональный подход к разработке приложений. Так, можно увидеть некоторые интересные решения от сообщества, и у нас все еще есть довольно много времени, когда мы сможем использовать SwiftUI в повседневной работе, так что еще есть время для экспериментов и никакого давления на нас не оказывается.

Я планирую написать больше об этой реализации однонаправленной и функциональной архитектуры. Я надеюсь, что скоро смогу использовать это в каком-нибудь небольшом реальном проекте, поэтому я смогу подробнее рассказать о том, насколько этот подход жизнеспособен и имеет проблемы с производительностью в крупномасштабных проектах.
Tags:
Hubs:
+9
Comments 1
Comments Comments 1

Articles