Паттерны и их реализация через интерфейсы — как сделать корректно?
Приложение достаточно простое - будильник. Ломаю голову по реализации конкретно одной части - списка будильников.
Пока мысль такая. Базовый шаблон - MVP с использованием внедрения зависимостей. В жизненном цикле View экземпляр презентера берётся из класса Application, в конструктор/метод onInit которого передаётся экземпляр репозитория (которому, соответственно, передаётся экземпляр базы данных) и (к вопросу отношения не имеет) планировщика сигналов. В том же жизненном цикле вьюха дёргает презентер, тот - репозиторий на предмет отображения списка и добавления/ удаления будильников. Также применяется шаблон Наблюдатель - View подписывается на Presenter, тот, в свою очередь, на Repository - только по изменению списка будильников (например, удалили будильник - от репозитория идёт уведомление об изменении количества элементов).
Типами презентера и репозитория указываются интерфейсы - условно говоря, IAlarmsPresenter и IRepo. Для Наблюдателя - свои интерфейсы (с подпиской, отпиской и событиями обновления). Вот в этой части и загвоздка. Если для указания типа использовать интерфейс A, то вызвать методы интерфейса B не получится. В конкретном случае - вьюха не сможет подписаться на презентер, тот - на репозиторий.
Как решить такую ситуацию? Единый интерфейс - это лапша, должно быть разделение функционала/ответственности. Приведение к типу (интерфейсу) - как-то костыльно, да и приводить каждый раз к другому интерфейсу - лишнее. Использовать абстрактные классы, методы которых так же абстрактные, но от обоих интерфейсов, и реализовать эти методы уже в наследниках абстрактных классов, с дальнейшим указанием в качестве базовых типов те самые абстрактные классы?
RxJava и прочие фреймворки и библиотеки (иногда хочется использовать EventBus, но там будут свои заморочки) не предлагать. Цель - базовое понимание вещей.
В жизненном цикле View экземпляр презентера берётся из класса Application
презентеры это просто логика вынесенная из View, лучше их пересоздавать вместе с View и связывать с текущим состоянием модели
Зачем работать через интерфейс презентера если каждому View соответствует свой конкретный класс презентера? Презентер может реализовывать любое количество интрефейсов, но View работает с самим классом презентера.
На мой взгляд, Passive View работает лучше. Смысл:
View ни на что не подписывается, у неё есть только методы обновления и подписки на UI-события
Presenter подписывается на изменения Repository и на UI-события, и соответственно дергает методы отображения View.