Git Product home page Git Product logo

drones-example's Introduction

drones-example

Про архитектуру

Приложение разделено на слои:

  • data
  • models
  • presentation

Data слой отвечает за получение / изменение / удаление данных. Основные его классы - репозитории. Задача репозитория состоит в том, чтобы взять данные из доступного источника. Например, если у нас есть сервер и локальная база данных, то репозиторий сначала обратится к классу, отвечающему за соединение с интернетом, и если интернет есть - сходит в сеть. Если интернета нет - возьмёт данные из локальной базы.

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

Репозиторий может

  1. брать данные
  2. сравнивать их (когда мы передаем объект на апдейт, репозиторий может сравнить текущий объект и новый, и если они одинаковые, лишний раз не перезаписывать данные)
  3. принимать решение о том, откуда взять данные (локальная бд, сеть, преференсы)
  4. обращаться к другим репозиториям за данными ( в такой ситуации можно создать медиатор - класс, который будет вызывать сначала один, потом второй репозиторий. )

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

Presentation слой - здесь хранятся все классы, отвечающие за пользовательский интерфейс. Активити, фрагменты, диалоги, и так далее. Задачи этого слоя:

  1. получить данные (неважно откуда, вьюмодель, репозиторий, или ещё что-то)
  2. показать их
  3. получить данные о вьюшках и изменить их вид (например из вьюмодели может придти сообщение (в виде livedata) о том, что юзер не заполнил поле "имя", и пытается сохранить данные). В таком случае наша Активити или Фрагмент должны принять эти данные и показать, например, Snackbar или Toast, уведомить юзера о том, что нужно заполнить это поле.

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

Вьюмодель - это паттерн для связи вьюшек и логики / данных, который в андроиде реализован классом ViewModel(), от которого должны наследоваться все наши вьюмодели. Задача вьюмодели - получить данные из фрамента / активити, проверить их, если будет найдена ошибка - уведомить фрагмент / активити через livedata. Также вьюмодель ответственна за получение данных из репозиториев. Ей неважно, откуда приходят данные - из сети, из БД, или это просто руками сгенерированные рандомные данные. Важно получить их, и передать во фрагмент / активити через livedata.

LiveData - этот класс реализует паттерн Observer. Создается во вьюмодели, а дальше на неё могут подписаться активити / фрагменты, и они будут уведомлены, когда данные изменятся. Хорошая практика: оставлять livedata закрытой везде кроме вьюмодели. Например, фрагмент не должен делать этого:

someLiveData.value = 123

Вместо этого, стоит создать отдельный метод во вьюмодели, который будет отвечать за изменение livedata:

fun changeLiveData(value: Int) { someLiveData.value = value }

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

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

В основе такой архитектуры лежат принципы, но не правила. Нет единственно верного или в корне неверного решения (если оно не нарушает общие принципы).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.