- PVSM.RU - https://www.pvsm.ru -
Вводная часть (со ссылками на все статьи) [1]
В водной статье я уже писал о том, что планируемым клиентом для проекта должен стать клиент Android: доступный большой аудитории, лёгкий, функциональный, красивый, быстрый (не приложение, а мечта!). Если с основаниями выбора платформы всё понятно, то с тем как реализовывать на базе неё все перечисленные требования – ясно было далеко не всё.
Ранее разработкой под Android не занимался поэтому достаточно ценными источниками информации для меня являлись:
После изучения указанных источников вопросов с архитектурой Android и взаимодействия их компонентов не осталось. Однако остался один наиважнейший вопрос: какова будет структура самого приложения? Пара примеров и прототипов показала, при росте функционала всё быстро начинало превращаться в «лапшу»:
Стало понятно, что нужно сделать шаг назад и осмотреться: Android существует не первый год, есть люди, которые разрабатывают код продолжительное время под эту платформу, есть большие развивающиеся проекты – соответственно есть откуда подчерпнуть информацию о хорошо зарекомендовавших себя практиках.
Основными критериями в поиске хорошей архитектуры для Android-приложения были:
Поиски привели меня к интересному ролику на YouTube: «Пишем тестируемый код» [8] (запись выступления Евгения Мацюк(а) с конференции по мобильной разработке Mobius) (там было МНОГО ВСЕГО!), в котором описывалось то, что было мне нужно. Для реализации потребовалось изучить некоторые дополнительные ресурсы и инструменты:
Разработка прототипа с указанными практиками совместно с изучением RxJava заняла немало времени, однако через какое-то время был готов первый прототип. Отличительной особенностью его являлось ужасное количество создаваемых интерфейсов и классов при добавлении новых экранов: 3 интерфейса и 3 класса (Activity/Fragment и его интерфейс, Presenter и его интерфейс, Interactor и его интерфейс) – классический пример overengineering’а. Формально к текущему моменту ничего не поменялось, но я полагаю это оборотная сторона получаемых преимуществ. Зато на выходе получаем легко тестируемое приложение со слабо связанной структурой.
Приведу для освежения в памяти компоненты Clean Architecture из статьи на Habr’е «Заблуждения Clean Architecture» [10].
Каждый компонент Android и элемент выбранной архитектуры представлены в следующей таблице:
Класс | Уровень | Реализуемые интерфейсы | Назначение |
Реализация Activity/Fragment (XXXX_Activity / XXXX_Fragment) | UI | I_XXXX_View | Фактическая реализация действия с элементами Android: изменение свойств, получение обратных вызовов, старт сервисов, работа с Android API |
XXXX_PresenterImpl | UI | I_XXXX_Presenter | Координация действий уровня представления, логика представления – вызовы методов интерфейсов I_XXXX_View, I_XXXX_Interactor |
XXXX_InteractorImpl | Business/Use Cases | I_XXXX_Interactor | Реализация основной логики приложения, вызовы методов интерфейсов I_XXXX_Repository |
XXXX_RepositoryImpl | Data/Repository | I_XXXX_Repository | Реализация непосредственного взаимодействия с источниками данных, внешними API, сетью и БД Android, ContentProvider’ами и т.д. |
Взаимодействие компонентов и передача данных организована с учётом того, что пользователь любого Android- приложения больше получает данных чем, вводит их. Соответственно:
В оригинальной статье Fernando Cejas предлагалось 2 варианта организации «по уровням» и «по функционалу», я для себя выработал комбинированный подход:
Интересной особенностью стало, то что количество Interactor’ов стало равно «кол-во основных экранов» + «кол-во сущностей»: нередки ситуации, когда требуется организовать хитрое получение данных (например, с комбинированием из разных источников) и копировать данный код в каждый Interactor, где он требуется совершенно не хотелось. При этом с учётом того, что Interactor используются в единственном экземпляре – они могут хранить некое состояние, важное для выполнения метода, я реализовал это следующим образом: Interactor’ы экранов, обращаются к Interactor’ам сущностей за соответствующими методами (что приводит к появлению делегирующих методов в Interactor’ах экранов).
С точки зрения тестирования – ничего революционного:
Спасибо за внимание!
Автор: fedor_malyshkin
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/269450
Ссылки в тексте:
[1] Вводная часть (со ссылками на все статьи): https://habrahabr.ru/post/334510/
[2] Книга «Android Programming: The Big Nerd Ranch Guide»: https://www.bignerdranch.com/books/android-programming/
[3] переводом от издательства «Питер»: https://habrahabr.ru/company/piter/blog/335146
[4] Сайт Google по разработке для Android;: https://developer.android.com/
[5] Книга «Efficient Android Threading» от издательства O’Reilly;: http://shop.oreilly.com/product/0636920029397.do
[6] Видео с проекта Яндекса «Мобилизация».: https://www.youtube.com/watch?v=5EvxWifIgro&list=PLQC2_0cDcSKBNCR8UWeElzCUuFkXASduz
[7] Robolectric: http://robolectric.org/
[8] «Пишем тестируемый код»: https://youtu.be/AlxMGxs2QnM
[9] Оригинальная статья «The Clean Architecture»: https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
[10] статьи на Habr’е «Заблуждения Clean Architecture»: https://habrahabr.ru/company/mobileup/blog/335382/
[11] «Architecting Android...The clean way?»: https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/
[12] «Architecting Android...The evolution»: https://fernandocejas.com/2015/07/18/architecting-android-the-evolution/
[13] Dagger 2: https://google.github.io/dagger/
[14] RxJava: https://github.com/ReactiveX/RxJava
[15] Источник: https://habrahabr.ru/post/343446/
Нажмите здесь для печати.