Кэш-память адаптера MVP

Я разрабатываю проект после архитектуры MVP. Обычно, когда я использую recyclerView, мой ведущий управляет данными адаптера. Но теперь мне нужно сделать адаптер recycler с данными из кеша (или что-то вроде кеша), размер ресайклера dosen't зависит от размера кэша, поэтому я делаю кеш через HashMap, где ключ - позиция recycler, если есть элемент в затем данные показывают, иначе пустую строку с чем-то вроде "добавить события" btn. И я не могу понять, где место для этого кеша в такой структуре - Model (Dao или что-то вроде CacheManager) или в Adapter.

Идея кэша следующая: у меня есть некоторые типы событий, которые хранятся в базе данных, каждое событие, изменяющее изменения в db, - поэтому кеш должен быть обновлен.

Основные вопросы: где хранить этот кеш и загружать его в адаптер, как я могу синхронизировать его с изменениями базы данных.

P.S. Также я пытаюсь использовать RX, поэтому, если его можно решить с помощью него, было бы очень интересно попробовать.

P.P.S Если это шаблон репозитория - способ решить - добро пожаловать. Прочтите об этом некоторое время назад.

Ответ 1

Ваша проблема звучит не так, как она связана с RecyclerView.Adapter - и на самом деле вы не должны пытаться решить ее в своем Adapter: ответственность адаптера должна выступать в качестве моста (или "адаптера" );-)) между вашими данными и компонентом представления. Предоставление ему большей ответственности превратило бы его во что-то, что не является взаимозаменяемым с другими реализациями Adapter (вы этого не хотите!).

Вероятно, вы должны найти чистый способ абстрагировать сохранение данных. Кэш-память в памяти должна входить в эту абстракцию. Вы упомянули шаблон репозитория, это будет хороший выбор ИМХО.

Ваша архитектура должна выглядеть примерно так:

adapter -> repository -> |-> cache
                         |-> database

Репозиторий объединяет логику доступа к данным (ваш DAO) и обработку кеша (ваш CacheManager). Репозиторий всегда будет сначала проверять кеш, а затем извлекать данные из базы данных. Он также обновляет кеш, если извлекаются не кэшированные данные. Кроме того, он регистрирует обновления в базе данных. Как только база данных уведомляет об измененных данных, репозиторий имеет возможность обновить кеш и/или распространить уведомление на представление. Важная часть заключается в том, что интерфейс репозитория скрывает всю эту логику; он предлагает только доступ к данным.

Затем вам нужно найти способ заставить ваш адаптер работать с вашим репозиторием. Я бы предложил Android Loader. Благодаря этому вы получаете бесплатную асинхронную загрузку и правильную обработку жизненного цикла. Также это красиво отделяет адаптер и репозиторий.

Если вам нужно вдохновение в отношении применения шаблона репозитория, посмотрите googlesamples/android-architecture Github. ветвь чистой архитектуры может вам пригодиться.

На стороне примечания: попробуйте найти реальные (уникальные) ключи ваших данных. Использование позиции в списке данных обычно является плохой идеей и в зависимости от структуры ваших данных приведет к появлению странных побочных эффектов в представлении.

Ответ 2

Я думаю, что это тема архитектуры. Rx не соответствует теме. Например, для репозитория Rx - это просто способ его реализации, а также расширение его кеша.

Репозиторий Google предоставляет некоторые образцы архитектуры. Один из них содержит пример архитектуры с базовым mvp и репозиторием, которые управляют кешем:

googlesamples/android-architecture/todo-mvp

Другой пример в том же репозитории с Rx:

googlesamples/android-architecture/todo-mvp-rxjava

Здесь мы видим, что эти два примера имеют одну и ту же схему архитектуры:

введите описание изображения здесь