標籤:
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.*/@Singletonpublic 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}.*/@Singletonpublic 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調用,不是用來擷取資料的。
擷取資料來源資料的實現---Architecting Android