В статье «Moxy — реализация MVP под Android с щепоткой магии» мы рассказывали, как побороть проблему жизненного цикла и разделить код своего Android-проекта на слои. Однако MVP (даже при умной кодогенерации view state в Moxy) заставляет писать огромное количество лишнего кода (создавать связанные друг с другом классы и интерфейсы presenter и view). На самом деле эту работу за вас должен делать робот! :) Настало время еще сильнее уменьшить boilerplate при помощи кастомизации шаблонов Android Studio под Moxy.
Для того чтобы начать кодогенерацию, нужно зафиксировать структуру проекта.
Содержимое пакетов presenter, view, activity и fragment, в свою очередь, делится на логические модули. Часто такими модулями выступают разделы приложения (к примеру, intro, offers, feed). Ниже — пример структуры проекта с двумя Activity (CarActivity и HomeActivity) и одним фрагментом (CarDetailsFragment)
Наша цель — научиться генерировать эти классы
Как создавать шаблоны в Android Studio можно прочитать в статье от Fi5t про Тотальную шаблонизацию
Добавляем в проект шаблоны для Moxy:
Настраиваем hot keys для быстрого доступа к шаблонам:
Остальные поля наберутся сами.
Далее меняем в поле Package Name слово blank на имя подпакета и нажимаем Finish. Ваш пакет классов готов! Стоит отметить, что при обновлении Android Studio может снести все кастомные шаблоны. В этом случае придется их импортировать заново.
Концепция MVP подразумевает разделение логики приложения на слои и, как следствие, увеличение кодовой базы. Использование шаблонов и кодогенерации максимально избавляет вас от boilerplate, предохраняет от случайных ошибок и позволяет сосредоточиться на бизнес-логике. Пусть код за вас пишет робот!
Структура проекта
Для того чтобы начать кодогенерацию, нужно зафиксировать структуру проекта.
- model
- presentation
- presenter
- view
- ui
- activity
- fragment
Содержимое пакетов presenter, view, activity и fragment, в свою очередь, делится на логические модули. Часто такими модулями выступают разделы приложения (к примеру, intro, offers, feed). Ниже — пример структуры проекта с двумя Activity (CarActivity и HomeActivity) и одним фрагментом (CarDetailsFragment)
Наша цель — научиться генерировать эти классы
Настройка шаблонов
Как создавать шаблоны в Android Studio можно прочитать в статье от Fi5t про Тотальную шаблонизацию
Добавляем в проект шаблоны для Moxy:
- Скачиваем шаблоны с Github либо по ссылке
- Копируем содержимое архива в ANDROID_STUDIO_DIR/plugins/android/lib/templates/activities
- Перезапускаем Android Studio, чтобы изменения вступили в силу
Настраиваем hot keys для быстрого доступа к шаблонам:
- Открываем настройки-> Keymap
- В поисковом окне вводим Moxy
- Добавляем комбинации клавиш (я использую Alt + A для активити и Alt + F для фрагмента)
Использование шаблонов
- Выделяем корневой пакет и нажимаем Alt + A.
- В поле Activity Name пишем «MyFirstMoxyActivity»
Остальные поля наберутся сами.
Далее меняем в поле Package Name слово blank на имя подпакета и нажимаем Finish. Ваш пакет классов готов! Стоит отметить, что при обновлении Android Studio может снести все кастомные шаблоны. В этом случае придется их импортировать заново.
Что в итоге
Концепция MVP подразумевает разделение логики приложения на слои и, как следствие, увеличение кодовой базы. Использование шаблонов и кодогенерации максимально избавляет вас от boilerplate, предохраняет от случайных ошибок и позволяет сосредоточиться на бизнес-логике. Пусть код за вас пишет робот!
Материалы по теме
Поделиться с друзьями
HotIceCream
Так ли нужна концепция разнесения классов по пакетам в соответствии с тем, чем является тот или иной класс? Т.е. вот в вашем примере, не проще ли положить CarView, CarPresenter, CarActivity в один пакет car. Ведь чаще всего их редактировать нужно вместе. Я понимаю, что есть рекомендации гугла по именованию пакетов, да и вообще «всегда так было». Но если бы их не было, то как ответите на мой вопрос?
senneco
Есть мысль, что стоит заводить отдельный пакет под Car, и в нём держать CarView, CarPresenter и CarViewModel. CarActivity стоит оставить в пакете activity. Этому есть несколько причин:
Мы (в arello :D )планируем в ближайшем времени попробовать такую структуру пакетов – может быть будет удобно. А может и нет – время покажет ;)
Xanderblinov
HotIceCream, складывать все в один пакет удобно до тех пор, пока приложение не разрастается. Представим, что к пакету car относятся 4 Fragment и Activity которое ими управляет. Это означает что в одном пакете будет лежать как минимум 15 классов.
Также непонятно куда складывать базовые классы для Presenter, Activty. По такой логике нам нужно создавать пакет base?
senneco, я уже пробовал раскладывать по логическим пакетам, в результате было не очень удобно. Если в пакет складывать только один экран, то получается слишком мелкое деление, а если несколько, то огород.
для data объектов мы используем отдельный пакет ui_data, в нем также сохраняется разбиение на пакеты
HotIceCream
Да, пакет base.
Можно раскладывать так, что в одном пакете может быть только 1 view (+ его fragment, presenter). Если в каком-то фрагменте могут содержаться другие фрагменты, то каждый из дочерних фрагментов (+ его view, presenter) лежит в пакете одного уровня с первым фрагментом. Т.е. группировать не по «темам», а по конкретным вьюхам.
Xanderblinov
В результате на каждое Activity и Fragment будет свой пакет? В большом проекте в корневом пакете будет слишком много вложенных пакетов. Это осложнит навигацию.
Мы используем описанную иерархию. Она зарекомендовала себя как довольно практичная
В любом случае, разделение по пакетам советую делать так, как удобно Вам, т.к. единого мнения не существует
Divers
Ну сейчас тренд как раз таки feature based packaging. Я пробовал и так и так — мне больше понравилось feature based подход. Навигация как раз таки упрощается, потому что почти всегда правка кода необходима только в 1ом пакете.
Xanderblinov
А у Вас все слои архитектуры в одном пакете? А общие классы куда-нибудь выносите? К примеру, если объект продукт нам понадобится и в каталоге и в корзине, то в какой пакет нам его поместить?
Divers
Нет, не все. Вот тут можно посмотреть как я сейчас делаю.