markdown Android中MVP中的存储库模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown Android中MVP中的存储库模式相关的知识,希望对你有一定的参考价值。
*SOURCE:* [StackOverflow](https://stackoverflow.com/a/44146088/1602807), [Hannes Dorfmann](http://hannesdorfmann.com/android/evolution-of-the-repository-pattern)
# Overview about Repository pattern in MVP in Android
## Summary
In short, Repository pattern in Android has a different meaning in comparison with the original Martin Fowler's proposal (see the linked Hannes Dorfmann for details).
The Repository pattern is really just a specific type of the Facade pattern. It is just an abstraction layer which sits between the true data sources (Models) and the consumers.
Let's say we have a system that deals with weather data. In this case I see nothing wrong with having three Modal classes:
- `WeatherHttp`
- `WeatherDb`
- `WeatherPrefs`
These can all be members of your repository class injected through the constructor. All three of these are hidden from the consumers (UI) behind a single repository class:
- `WeatherRepository`
which might have a single public method:
`public void getWeatherForecasts(Callback<List<Forecast> forecastCallback);`
or Rx:
`public Observable<List<Forecast>> getWeatherForecasts();`
Behind the scenes of that method you might well make an http call to fetch the latest data, a database call to save the majority of the details and a shared prefs edit to save the timestamp of the last time the data was fetched. The idea is you are free to change the implementation at any time and the consumers don't care.
The single most important thing about implementing a repository is you must not leak the implementation details. No network classes, database DAOs or SharedPreference keys should be exposed by the public API of the repository.
## Detail Version
If you wants to load an `User` by his id:
```java
interface UserRepository {
User user(int userId);
}
```
The concrete implementation of that repository:
```java
class UserDataRepository implements UserRepository {
private UserDataStoreFactory userDataStoreFactory;
@Override
public User user(int userId) {
UserDataStore userDataStore = userDataStoreFactory.create(userId);
return userDataStore.get(userId);
}
}
```
An `UserDataStore` is, as the name already suggests, responsible to load a `User` from a store like disk or a backend (cloud).
```java
interface UserDataStore {
User getUser(int userId);
}
class DiskUserDataStore implements UserDataStore {
private DiskCache<Int, User> userCache;
@Override
public User getUser(int userId){
return userCache.get(userId);
}
}
class CloudUserDataStore implements UserDataStore {
@Override
public User getUser(int userId){
// Make an HTTP request and return User.
}
}
```
`UserDataStoreFactory` is the component that decides which `UserDataStore` to use when someone calls `UserRepository.getUser(userId)`. For example the factory could check if `DiskUserDataStore` has a `User` and if the `User` object is expired then the factory returns `CloudUserDataStore`, otherwise `DiskUserDataStore`. The factory could also take into account if the smartphone has an active internet connection or not. I guess you get the point.
## Extra: Using Repository as Singleton
For why the [Android Blueprint](https://github.com/googlesamples/android-architecture) using the Repository as a Singleton, see [this post](https://hackernoon.com/presenters-are-not-for-persisting-f537a2cc7962).
以上是关于markdown Android中MVP中的存储库模式的主要内容,如果未能解决你的问题,请参考以下文章