Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVP Adapter Data Cache

I'm developing project following MVP architecture. Usually, when I use recyclerView, my presenter controls Adapter data. But now I need to make recycler adapter with data from cache (or something like cache), recycler's size dosen't depends on cache size, so I make cache via HashMap where the key is - position of recycler, if there is an item in map then the data shows, else empty row with something like "add events" btn. And I can't realize where the place for that cache in such structure - Model (Dao or something like CacheManager) or in Adapter.

The cache idea is following: I have some types of events which store in database, every event modifying changes it in db - so the cache has to be updated either.

The main questions are: where to keep this cache and load it to adapter, how can i keep it sync with database changes.

P.S. Also I tries to use RX, so if it can be solved with it - would be very interesting to try.

P.P.S If it the Repository pattern is the way to solve - welcome. Read about it sometime ago.

like image 337
shagi Avatar asked Apr 21 '17 06:04

shagi


2 Answers

Your problem doesn't sound like it's related to RecyclerView.Adapter -- and actually you shouldn't try to solve it within your Adapter: the responsibility of the adapter is to act as a bridge (or "adapter" ;-) ) between your data and view component. Giving it more responsibility would turn it into something that is not interchangeable with other Adapter implementations (you don't want this!).

You should probably find a clean way to abstract your data persistence. The in-memory cache should go into that abstraction. You mentioned the repository pattern, this would be good choice IMHO.

Your architecture should roughly look like this:

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

The repository combines the logic for data access (your DAO) and the cache handling (your CacheManager). The repository would always first check the cache and then fetch data from the database. It also updates the cache if non-cached data is fetched. Furthermore, it registers for updates on the database. As soon as the database notifies for changed data, the repository has the chance to update the cache and/or propagate the notification to the view. The important part is that the interface of the repository hides all this logic; it only offers access to data.

You then need to find a way to make your adapter work with your repository. I'd suggest Android's Loader mechanics. By this you get asynchronous loading and correct lifecycle handling for free. Also this nicely decouples adapter and repository.

If you need some inspirations on how to apply the repository pattern, have a look into the googlesamples/android-architecture Github. The Clean Architecture branch could be a good fit for you.

On a side note: try to find real (unique) keys of your data. Using the position within the data list is usually a bad idea and depending on the structure of your data will result in strange side effects in the view.

like image 79
Brian Avatar answered Oct 20 '22 22:10

Brian


I think it's an architecture subject. Rx is out of subject. For example for a repository, Rx is just a way to implement it, and by extension, its cache.

A Google repository provide some samples of architecture. One of them contains an example of architecture with a basic mvp, and a repository who manage cache :

googlesamples/android-architecture/todo-mvp

Another example in the same repository with Rx :

googlesamples/android-architecture/todo-mvp-rxjava

We can be seen here that these two examples share the same scheme of architecture :

enter image description here

like image 29
compte14031879 Avatar answered Oct 20 '22 23:10

compte14031879