UserRepository,这个接口,描述了Repository提供给用户的功能就是getUsers,getUser(ID)。用户只管使用,其它细节无需理会。
/** * Interface that represents a Repository for getting {@link User} related data. */ public interface UserRepository { /** * Get an {@link rx.Observable} which will emit a List of {@link User}. */ Observable<List<User>> getUsers(); /** * Get an {@link rx.Observable} which will emit a {@link User}. * * @param userId The user id used to retrieve user data. */ Observable<User> getUser(final int userId); }
UserRepository的一个实现类。通过委托的方式,通过委托userDataStoreFactory,来实现数据获取的功能。
/** * {@link UserRepository} for retrieving user data. */ @Singleton public class UserDataRepository implements UserRepository { private final UserDataStoreFactory userDataStoreFactory ; private final UserEntityDataMapper userEntityDataMapper ; private final Func1<List<UserEntity> , List<User>> userListEntityMapper = new Func1<List<UserEntity> , List<User>>() { @Override public List<User> call (List<UserEntity> userEntities) { return UserDataRepository. this.userEntityDataMapper .transform(userEntities) ; } }; private final Func1<UserEntity , User> userDetailsEntityMapper = new Func1<UserEntity , User>() { @Override public User call (UserEntity userEntity) { return UserDataRepository. this.userEntityDataMapper .transform(userEntity) ; } }; /** * Constructs a {@link UserRepository}. * * @param dataStoreFactory A factory to construct different data source implementations. * @param userEntityDataMapper {@link UserEntityDataMapper}. */ @Inject public UserDataRepository(UserDataStoreFactory dataStoreFactory , UserEntityDataMapper userEntityDataMapper) { this .userDataStoreFactory = dataStoreFactory; this. userEntityDataMapper = userEntityDataMapper ; } @Override public Observable<List<User>> getUsers() { //we always get all users from the cloud final UserDataStore userDataStore = this.userDataStoreFactory .createCloudDataStore() ; return userDataStore.getUserEntityList().map( userListEntityMapper ); } @Override public Observable<User> getUser( int userId) { final UserDataStore userDataStore = this.userDataStoreFactory .create(userId); return userDataStore.getUserEntityDetails(userId).map( userDetailsEntityMapper ); } }
-------------------------------------------------------------------------------------------------------------------
UserDataStore,UserDataStoreFactory
UserDataStoreFactory,选用不同的UserDataStore来实现获取数据的功能。不同的UserDataStore实现代表不同的数据源。
/** * Interface that represents a data store from where data is retrieved. */ public interface UserDataStore { /** * Get an {@link rx.Observable} which will emit a List of {@link UserEntity}. */ Observable<List<UserEntity>> getUserEntityList(); /** * Get an {@link rx.Observable} which will emit a {@link UserEntity} by its id. * * @param userId The id to retrieve user data. */ Observable<UserEntity> getUserEntityDetails (final int userId) ; }
UserDataStoreFactory,两个create方法,提供了两个不同的UserDataStore实现
/** * Factory that creates different implementations of {@link UserDataStore}. */ @Singleton public class UserDataStoreFactory { private final Context context; private final UserCache userCache; @Inject public UserDataStoreFactory(Context context , UserCache userCache) { if (context == null || userCache == null) { throw new IllegalArgumentException( "Constructor parameters cannot be null!!!") ; } this .context = context.getApplicationContext() ; this. userCache = userCache; } /** * Create {@link UserDataStore} from a user id. */ public UserDataStore create( int userId) { UserDataStore userDataStore; if (! this.userCache .isExpired() && this.userCache .isCached(userId)) { userDataStore = new DiskUserDataStore(this. userCache); } else { userDataStore = createCloudDataStore(); } return userDataStore; } /** * Create {@link UserDataStore} to retrieve data from the Cloud. */ public UserDataStore createCloudDataStore() { UserEntityJsonMapper userEntityJsonMapper = new UserEntityJsonMapper() ; RestApi restApi = new RestApiImpl(this .context, userEntityJsonMapper) ; return new CloudUserDataStore(restApi , this.userCache ); } }
-----------------------------------------------------------------------
数据源实现一览
CloudUserDataStore数据源,是通过网络获取数据的。它只要实现了UserDataStore声明的接口便可以,这样,它就是一个UserDataStore了。
/** * {@link UserDataStore} implementation based on connections to the api (Cloud). */ public class CloudUserDataStore implements UserDataStore { private final RestApi restApi; private final UserCache userCache; private final Action1<UserEntity> saveToCacheAction = new Action1<UserEntity>() { @Override public void call(UserEntity userEntity) { if (userEntity != null) { CloudUserDataStore.this .userCache.put(userEntity) ; } } }; /** * Construct a {@link UserDataStore} based on connections to the api (Cloud). * * @param restApi The {@link RestApi} implementation to use. * @param userCache A {@link UserCache} to cache data retrieved from the api. */ public CloudUserDataStore(RestApi restApi , UserCache userCache) { this .restApi = restApi ; this. userCache = userCache; } @Override public Observable<List<UserEntity>> getUserEntityList() { return this .restApi.getUserEntityList() ; } @Override public Observable<UserEntity> getUserEntityDetails (final int userId) { return this.restApi.getUserEntityById(userId).doOnNext( saveToCacheAction); } }
--------------------------------------------------------------------------------------------------------
我从中可以学习到的内容是:
1.先用接口,声明你将要提供给用户的功能。
2.而关于数据获取方面的实现,则是按照如下的方式进行:
实现一个工厂,这个工厂负责选择不同的数据源实例,然后通过方法暴露给调用者。
比如,UserDataStoreFactory,它提供了两个方法,这两个方法都是用来返回一个UserDataStore实例,至于实例是采用哪种实现的,用户无需关心。采用什么实现,这是在UserDataStoreFactory中控制的。
在这个例子中,有如下的UserDataStore实现:CloudUserDataStore, DiskUserDataStore
这两个实现,就提供了数据源的具体实现。其实,还可以添加,从数据库获取用户列表,用户详情,可以添加一个DataBaseUserDataStore。总之,可以添加不同的数据源,只要它们实现了UserDataStore接口所声明的功能就可以。
-------------------------------------------------------------------------------------------
参照上述的实现方式,假如我自己要实现一个登陆功能,那么,我要怎么做?
登陆功能不适合上述的实现方式。上述的实现方式,适合于专门用户获取数据的场景。
登陆功能,只是一个REST调用,不是用来获取数据的。