Как PayU улучшает тестируемость кода с помощью архитектуры MVVM:- www.deekpay.com

Как PayU улучшает тестируемость кода с помощью архитектуры MVVM

В этой статье я расскажу о том, как PayU перевела свое приложение и SDK на архитектуру MVVM, чтобы улучшить тестируемость, масштабируемость и читаемость кода. За последние несколько лет мы провели несколько итеративных обновлений пользовательского интерфейса (UI), в то время как основная бизнес-логика оставалась практически неизменной (за исключением новых функций). Однако с первоначальной архитектурой нам было сложно поддерживать темпы обновления, необходимые для развития бизнеса. Поэтому мы сосредоточились на перепроектировании базовой архитектуры, чтобы сделать код более читаемым, масштабируемым и тестируемым, приняв архитектуру MVVM.

Что мы делали раньше?

До этого момента мы следовали паттерну MVC. В теории этот паттерн казался нам хорошо работающим, но по мере роста кодовой базы и увеличения количества итераций пользовательского интерфейса мы поняли, что кодовая база стала неуправляемой по двум причинам:

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

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

Мы движемся в неправильном направлении (слева направо).

Когда мы пытаемся разобраться в проблеме, то понимаем, что и View, и Controller зависят от Model. Кроме того, Activity и Fragment содержат как логику пользовательского интерфейса, так и логику контроллера. В результате количество кода для наших юнит-тестов уменьшается, и код становится неуправляемым.

Архитектура MVC

Архитектура MVVM в помощь

Мы начали искать лучшую архитектуру, и тогда MVVM стал нашим спасением. Даже Google отдал предпочтение MVVM.

MVVM расшифровывается как Model-View-View Model:

Модель: представляет собой уровень данных приложения.

Вид: представляет собой логику пользовательского интерфейса приложения.

ViewModel: является моделью представления. Она служит мостом между представлением и моделью и не ссылается на представление напрямую.

Архитектура MVVM устраняет тесную связь между компонентами. Дочерние компоненты не ссылаются напрямую на родительский компонент, они делают это только через наблюдаемые свойства. Обратите внимание, что каждый компонент зависит только от компонента следующего уровня. Такой дизайн создает целостный и приятный пользовательский опыт.

Еще одним важным компонентом на приведенной выше схеме является модуль Repository. Он управляет манипуляциями с данными. Он предоставляет четкий API, чтобы другие части приложения могли легко получать данные. Он знает, откуда брать данные и какие вызовы API необходимо выполнить при обновлении данных. Хранилище можно рассматривать как посредника между различными источниками данных, такими как модели персистентности, веб-сервисы и кэши.

LiveData - это наблюдаемый держатель данных. Другие компоненты приложения могут использовать этот держатель для отслеживания изменений объектов без создания явных и фиксированных путей зависимостей. Компонент LiveData также учитывает состояние жизненного цикла компонентов приложения, таких как действия, фрагменты и службы, и включает логику очистки для предотвращения утечек объектов и чрезмерного потребления памяти.

vantage

Разделение задач: это распространенная ошибка - писать весь код в Activity или Fragment. Классы UI должны содержать только логику, которая управляет взаимодействием между UI и операционной системой. Сохраняя эти классы как можно более простыми, вы сможете избежать многих проблем, связанных с жизненным циклом.MVVM позволяет гарантировать, что каждый тип класса отвечает только за одну задачу.

Тестируемость: пользовательский интерфейс и взаимодействие могут быть протестированы с помощью тестовых примеров (библиотека Espresso). Модели представлений (ViewModels) и репозиторий (Repository) можно тестировать с помощью JUnit.

Расширяемость: вы можете легко вводить обновления пользовательского интерфейса. Добавляйте новые функции без рефакторинга или изменения больших частей существующей кодовой базы. Мы можем легче вставлять и извлекать компоненты.

Управляемость: кодовая база более управляема - вся логика пользовательского интерфейса в одном месте, бизнес-логика и логика данных - в другом.

недостатки

Для начала работы с MVVM и добавления новых функций может потребоваться некоторый опыт работы с паттернами. Кривая обучения относительно крутая.

Следование паттерну MVVM может привести к созданию большего количества Java-классов.

заключительные замечания

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

В нашем случае MVVM оказался полезным паттерном, поскольку у нас продукт с богатым пользовательским интерфейсом и частыми итеративными обновлениями, мы хотели сосредоточиться на тестируемости продукта и добиться разделения задач, чтобы мы могли просто изменять соответствующие компоненты кодовой базы, не затрагивая остальной код. Архитектура MVVM идеально нам подошла!