Всем привет.
Пытаюсь освоить разработку под Андроид и после пары заходов всегда увязал в спагетти-коде раздутых активити и фрагментов. Поэтому решил применять best practices в плане архитектуры, а конкретнее MVP. В принципе идея красивая и реализуется все довольно просто, но возник принципиальный вопрос.
Предположим, что у нас есть two-pane приложение - для конкретности возьмем карту с маркерами и список этих маркеров. Соответственно имеются два фрагмента: MyMapFragment и MyListFragment. В общем случае события выделения, добавления, удаления, нажатия и прочие могут отлавливаться любым из них. Задача в том, что требуется координировать состояния обоих отображений: если мы выделили маркер на карте, то нужно выделить его и в списке, или если изменили название маркера в списке, то нужно тут же обновить его на карте.
Вопрос: какой способ наиболее корректен?
Я вижу три варианта:
1)
Все вопросы координации вьюшек лежит на Presenter'е.
Соответственно сразу после инстанцирования Presenter'а, мы регистрируем каждый фрагмент в нем как реализацию интерфейсов для колбэков MarkersView. При этом важный момент: Presenter явно знает какая реализация к чему относится и какая именно реализация к нему обращается. Иными словами, помимо функции маршрутизации данных от View к Model и обратно, наш Presenter теперь так же занимается маршрутизацией нотификаций о событиях между известными ему View.
Но как я понимаю, это нарушает идеологию MVP в том плане, что Presenter теперь слишком многое знает о представлениях.
2)
Presenter занимается только маршрутизацией данных, а согласованиями вьюшек - отдельный класс-посредник MarkersViewsMediator.
В этом случае Presenter слеп и принимает события от любого из фрагментов и вызывает колбэки того фрагмента, который к нему обратился. Для согласования своих состояний фрагменты используют MarkersViewMediator в качестве общей шины для передачи обновлений своих состояний.
Но тут можно заметить потенциальную проблему - Presenter ничего не знает о зарегистрированных в нем фрагментах (это хорошо), поэтому может либо дёрнуть коллбэк одного обратившегося к нему фрагмента (похоже на вариант, когда у каждого фрагмента своя копия presenter'а), либо всех сразу (и тут уже могут всплыть проблемы и нехороший код).
3)
Как п.2, но Fragment'ы общаются с Presenter'ом только через посредника.
Иными словами, наш посредник становится мастер-представлением, координирующим работу фрагментов, отсылающим события Presenter'у и предоставляющим реализацию колбэков.
Но размеры такого класса могут быть внушительны и в целом он должен полностью знать подключенные к нему фрагменты.
Можно заметить, что на роль такого посредника может подойти активити, содержащая эти самые фрагменты. Правда придётся тесно завязываться на события её жизненного цикла. Другой вариант - отдельный синглтон.
Или может есть другой более правильный способ?