Всем привет, сегодня я расскажу про ключевые моменты нашего варианта реализации MVP (а точнее про его гибрид с PresentationModel)
1. Сначала следует сказать что у нас в отличии от каноничного определения MVP добавляется еще одна обязательная сущность - ScreenModel. Это POJO, который полностью описывает состояние экрана. Или другими словами - это логическое представление ui. Например, если у вас на экране есть список книг и рекламный банер + нужно ве это еще загрузить при при старте экрана, то в ScreenModel будут находиться: список книг, данные банера и состояние загрузки (Loading, Error, Success). ScreenModel взаимодействует с вью и презентером следующим образом: Презентер получает событие от вью, затем презентер сразу или после ответа интерактора изменяет ScreenModel, затем ScreenModel отрисовывается на вью. Получается очень наглядный unidirection data flow. Некоторые могут замметить, что и так с этими вашими архитектурами появилась куча классов, а вы хотите добавить еще один, все же станет только сложнее. Вовсе нет, ScreenModel наоборот помогает разгрузить мозги - работать с состоянием намного проще чем с последовательностью команд для вью, к тому же ужимается до минимума и становится более декларативной связь презентера и вью. Есть еще одна причина, по которой мы решили использовать имеено такой подход - после смены конфигурации достаточно одной строчкой кода отрисовать ScreenModel (Презентер и ScreenModel переживают смену конфигурации) для того чтобы перевести вью в нужное состояние.
2. В нашем подходе очень просто решена еще одна проблема смены конфигурации - получение результата асинхронной операции после уничтожения вью. Для асинхронных операций мы использкем rx, во время отсутствия вью все события во всех активных Observable приостанавливаются. Это делается простым навешиванием специального оператора на Observable. Таким образом можно практически полностью забыть про смену конфигурации.
3. В качестве вью могут выступать Activity/Fragment/View, причем dagger Scope для всех будет один -
@PerScreen, но при этом разные компоненты - таким образом можно легко делать доступными для всех экранов такие сущности как Navigator или ErrorHandler, причем у каждого из экранов будет свой инстанс.
4. Навигация (переход и получение результата, получение начальных параметров) происходит только в презентере, а вся низкоуровневая логика инкапсулирована в Navigator и Route.
6. Activity/Fragment занимаются только отображением, все остальное разнесено по другим классам.
8. Все вышеописанное представлено модулями core-mvp, mvp-wiget. В разработке находится модуль binding для связывания ScreenModel c вью.
В следующий раз я расскажу про то что не успел сегодня: диалоги, возможности презентера, запрос runtime permission и остальные полезности