В чём суть паттерна MVP в разработке под Андроид?
Слой View - Activity с виджетами (EditText, Button, ListView, etc), в котором кода только что super.onCreate() с установкой макета и определением виджетов, да слушатели событий, но сами методы в слое Presenter?
Слой Presenter - "рабочий класс", реагирующий на каждое событие из View и Model? Заполнили логин и пароль, нажали LogIn - вызвали метод обработки нажатия кнопки в Presenter. Последний принимает данные. Далее отправляет данные на сервер (слой Model), по ответу сервера обрабатывает данные, и отрисовывает интерфейс через методы View (аналогично контроллеру в MVC PHP)?
Примечания-вопросы.
1. Как "правильнее" передать логин и пароль - через параметры метода, или..?
2. Отрисовка данных во View - через статические методы View или создание экземпляра View и вызовом методов экземпляра (зачем такой огород?)?
3. В onResume восстановление состояния (из экземпляра Bundle или ещё как-то) - через вызов Presenter с передачей экземпляра Bundle?
4. Сохранение данных при onPause (пауза или завершение работы приложения) - передавать изменившиеся данные в Presenter через параметры метода?
4.1. Или "правильнее" подписать Presenter на каждое изменение данных во View, а через параметры передавать только, скажем, контекст Activity?
5. Открытие-закрытие бокового меню по нажатию "гамбургера" или аппаратной кнопки Меню - тоже через Presenter? Т.е. во View - только заполнение данных, никаких запросов, никакой обработки данных, единственная реакция на события - вызов методов из Presenter?
6. Применение интерфейсов обязательно? Т.е. прописали в интерфейсе список методов заполнения данных, класс Activity наследуется от этого интерфейса, и в этой Activity методы уже реализуются.
Cуть в том, что код в активити сложно тестируем. Кроме того, проблема разрастания активити, включение в него разного рода кода который работает с вьюхами, логикой, базой данных, сервисами и проч и проч.
Поэтому программистами искались выходы и находились. )
MVP был придуман задолго до андроида. Суть его (как и других аналогичных шаблонов) в разделении модели и ui. Особенность в том, что мы делаем полностью пассивную вьюху, логику вьюхи переносим в presenter.
схематично это так: есть интерфейс view. активити реализует этот интерфейс. презентер знает об этом интерфейсе.
Получается презентер не зависит напрямую от активити, только от некого интерфейса. Поэтому его сравнительно легко тестировать (подставляя свою заглушку view)
Так решается две основных проблемы:
- код стал более тестируемым
- код разделен на пассивную активити и ее логику в презентере.
По вопросам:
1. активити читает пароль и логи и передает их в презентер (вызывая соотвествующие методы презентера). а он далее из обрабатывает.
2. отрисовку данных делает активити с интерфейсом (названным например ActivityView). презентер имеет ссылку на этот интерфейс (активити передает свою ссылку ему), а далее вызывает например activityView.setText(text)
3. есть два подхода
а) время жизни презентера равен (не больше) времени жизни активити
б) время жизни презентера больше времени жизни активити
соотвественно а) данные сохраняются в budle и передаются в презентер
б) данные хранятся в презентере
4 - выше
5. активити - пассивный объект. управление через презентер. любая хоть немного сложная логика в презентер.
Применение интерфейсов обязательно. иначе потеряем тестируемость и не избавимся от жесткой зависимости презентер-активити.
это все описано очень неточно. например вместо "активити" можно подставить "фрагмент". но суть надеюсь понятна.
6. Интерфейс не обязательно, но желательно.
Фишка в чем: если у вас нет интерфейса, то вы в ашем Activity можете писать любые методы как угодно, а если вы сперва описываете интерфейс а затем делаете его реализацию, то приходится соответствовать требованиям интерфейса. И когда у одного интерфеса появляется несколько реализаций их методы будут одинаковыми, а не какими попало, что значительно облегчает дальнейшую разработку и развите проекта.