获取数据源数据的实现---Architecting Android

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调用,不是用来获取数据的。

时间: 2024-10-12 10:42:41

获取数据源数据的实现---Architecting Android的相关文章

Android:解决客户端从服务器上获取数据乱码的方法

向服务器发送HTTP请求,接收到的JSON包为response,用String content = EntityUtils.toString(response.getEntity(),"utf-8");解码还是出现了中文乱码,在后面加了 String name = new String(response.getBytes("iso-8859-1"), "UTF-8"); 也无济于事.想到服务器好像是用URLENCODER编了码的,怀着试一试的态度

android客户端和网站数据交互的实现(基于Http协议获取数据方法)

android客户端一般不直接访问网站数据库,而是像浏览器一样发送get或者post请求,然后网站返回客户端能理解的数据格式,客户端解析这些数据,显示在界面上,常用的数据格式是xml和json. 可以理解客户端其实是一个你自己定义标记语言的浏览器,一般浏览器能解析的是html+css的数据,而android客户端能解析的是xml和json(或者都不是而是你自己定义的火星格式),服务端为了能满足客户端输出这种数据格式的需求,不得不专门针对客户端开发不同于浏览器访问的接口. 开发一个网站的客户端你需

复制透视表样式时,系统提示“ excel无法从磁盘内获取数据透视表的源数据”

透视表A表定义好了样式,透视表B要应用. 透视表A---选项---选择---整个数据透视表 右键单击透视表A,复制 进入透视表B工作表,空白处粘贴全部, "设计",选择自定义样式,则正常应用 一般在步骤4会出现系统提示" excel无法从磁盘内获取数据透视表的源数据" 解决: 选择透视表B,"选项"----"刷新" 重新选择自定义样式

Architecting Android…The clean way?

Architecting Android-The clean way? 原文链接:http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/原文作者:Fernando Cejas 过去几个月,与@pedro_g_s 和 @flipper83 (顺嘴说一下这两位是android开发大牛)两位同行在Tuenti 站点上友好的讨论之后.我觉得这是一个写一篇关于android应用架构的文章的好时机. 写这篇文章的目的是想

例子Architecting Android…The clean way?----代码分析

Presention层: 整个应用启动的时候,就执行依赖的初始化.编译项目之后,Dagger依赖框架使用ApplicationComponent生成一个DaggerApplicationCOmponent. 1. 首先进行依赖的生成 在Application中,调用initializeInjector()就会促使Dagger框架进行依赖生成. ApplicationComponent 对其它Component提供Context,ThreadExecutor,PostExecutionThread

C#/.NET使用HttpWebRequest、SqlBulkCopy从API获取数据批量插入DB

小弟新手程序员一枚,代码技术和文章水平均不才.所写文章均为对自己所写所学代码的简单记录,可能对于老手程序员营养价值不高,望莫见怪. 我工作上有个需求:从某处API接口上获取数据(大约1W条而已)并插入到数据库中. 楼主刚毕业菜鸟,没做过批量插入操作.借助baidu搜索得知SqlBulkCopy可以实现.SqlBulkCopy相关的原理,我现在还没了解就不摆弄了,以后补上! (不要问为什么不用google,公司内网就连msdn.microsoft.com都不给上!另外我公司是开发C#/.NET的,

淘宝异构数据源数据交换工具 DataX

淘宝异构数据源数据交换工具 DataX 阅读目录 DataX是什么? DataX用来解决什么? DataX特点? DataX结构模式(框架+插件) DataX在淘宝的运用 DataX是什么? DataX是一个在异构的数据库/文件系统之间高速交换数据的工具,实现了在任意的数据处理系统(RDBMS/Hdfs/Local filesystem)之间的数据交换,由淘宝数据平台部门完成. 回到顶部 DataX用来解决什么? 目前成熟的数据导入导出工具比较多,但是一般都只能用于数据导入或者导出,并且只能支持

微软BI 之SSIS 系列 - 使用 SQL Profilling Task (数据探测) 检测数据源数据

开篇介绍 SQL Profilling Task 可能我们很多人都没有在 SSIS 中真正使用过,所以对于这个控件的用法可能也不太了解.那我们换一个讲法,假设我们有这样的一个需求 - 需要对数据库表中的一些数据做一些数据分析,比如统计一下数据表中各列中实际数据的长度,各长度区间范围:比如统计一下各数据列中非空字段的比例,表的行数,重复字段等等.那么如果不是专门做过这种数据源数据分析的话,可能不知道用什么方式能够非常快的得到这些信息.写 SQL 语句?我想这个过程也是非常耗费时间和精力的. 实际上

一个简单的数据增量更新策略(Android / MongoDB / Django)

我在做个人APP - CayKANJI - 的时候遇到一个问题: 怎样增量式地把日语汉字数据地从服务器更新到APP端,即每次用户执行更新操作时,只获取版本高于本地缓存的内容. 数据格式 为了能够与mongoDB无缝结合,并省去编写后台代码的麻烦,索性就把汉字数据保存成json文件,上传到服务器后,交给web应用去读取并写入数据库. 汉字文件就是普通的json格式. { "category": "行為ー2", "contents": [ { &qu