Найти в Дзене
Nuances of programming

Чистая архитектура с MVVM

Оглавление

Источник: Nuances of Programming

Для лучшего понимания чистой архитектуры давайте создадим примерный проект. Это приложение, на первой странице которого показывается список персонажей из мультсериала «Рик и Морти» с данными. Нажимая на каждого персонаж, на следующей странице можно увидеть серии, в которых эти персонажи появляются.

Поэтому у нас два типа сущностей: персонаж и серия.

Итак, прежде всего разберёмся, почему нам надо использовать чистую архитектуру?

  1. Разделение обязанностей  —  разделение кода на части или различные модули, которые имеют определённые обязанности, облегчает его сопровождение и дальнейшие изменения.
  2. Слабая связанность  —  в гибкий код можно легко вносить изменения, не меняя всей системы.
  3. Лёгкость тестирования.

В проекте у нас три слоя: приложение (представление), данные и предметная область.

Данные: в этом слое есть абстрактное определение различных источников данных и как их следует использовать. Мапперы выполняют отображение ответа сервера на модели баз данных. Модели представляют собой модель ответа сервера. Репозиторий существует для реализации вызовов API. Операции с базами данных  —  для реализации интерфейса «Dao», а пакет API  —  для определения методов API-вызовов с сервера. В обычном приложении мы, как правило, храним репозиторий и интерфейс репозитория в одном пакете. И можем делать это локально, чтобы везде иметь прямой доступ. Но в этом случае слой данных ни в коем разе не должен знать о других слоях.

Предметная область: этот слой известен как бизнес-логика. Это правила вашего бизнеса. Здесь находится пакет model, содержащий модели баз данных. А также репозиторий, являющийся лишь интерфейсом, и прецеденты. А что такое прецедент? Как известно, прецеденты выполняют единственную задачу. И в случае с персонажами, когда надо получить данные из базы данных, мы пишем прецедент с этой самой задачей получения данных из базы данных.

Приложение: этот слой взаимодействует только с UI (пользовательским интерфейсом) и содержит фрагменты, activity (т. е. визуальный интерфейс с отдельным экраном для одного действия пользователя), ViewModel и Di. Под Di подразумевается модуль, предназначенный для этого фрагмента или activity.

На этом рисунке показано, как слои взаимодействуют друг с другом:

-2

Но закончим уже с текстом и перейдём скорее к коду.

Итак, в проекте мы используем:

RxJava

Hilt

databinding

Retrofit

Room

Kotlin

Зависимости:

Для этого проекта в базе мы создаём три пакета: Episode («Серия»), Character («Персонаж») и utils.

Что такое utils? Это пакет, содержащий базовые и общие классы, которые используются более чем в двух классах.

Episode («Серия») и Character («Персонаж») содержат данные, предметную область (бизнес-логику) и представление:

-3

Эти пакеты будут выглядеть так:

-4

Пакет API содержит интерфейс «CharacterApi», который является лишь методом взаимодействия с сервером, и «CharacterApiImpl» для реализации этого взаимодействия.

Пакет базы данных содержит интерфейс «Dao»:

В «CharacterRepositoryImpl» вызываем только те методы, которые нам нужны. Здесь нет бизнес-логики.

В предметной области мы определяем модель, которую надо сохранить в базе данных:

Репозиторий  —  это интерфейс, реализуемый в приведённом выше классе.

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

Мы используем запечатанный класс для передачи данных и наблюдения за ними во ViewModel. И передаём прецедент конструктору для взаимодействия между этими двумя классами.

Для внедрения зависимостей используем hilt, поэтому пакета di нет в Episode («Серии») и Character («Персонаже»), но в util мы определяем «NetworkModule»:

И определяем «AppModule» в utils следующим образом:

А в пакете репозитория в utils определяем модуль репозитория:

Заключение

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

Надеюсь, статья была полезной. Проект с чистой архитектурой загружен на GitHub.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Golnaz Torabi: Clean Architecture with MVVM