Android 基于流程化设计的项目总结

发表于:2018-4-08 11:32

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:DevSiven    来源:51testing软件测试网采编

  这次讲下自己之前参与SDK开发里,其中一块的功能:
  模块主要负责接收后台下发的所有配置数据、电话本(大概8种数据类型)与负责鉴权SDK操作,并且整个流程必须是线性,不可中断且保持会话(session)一致的。
  分析
  无论写业务代码、还是写库代码,请写代码前多思考思考吧~
  一、结构分层
  根据需求,大概我们可以分为几个层次
  database 层
  这一层属于模块的Model层,专门负责数据操作层
  network 层
  这一层属于模块的网络访问层,专门负责网络请求,包括http与https、session会话保持、失败心跳请求等
  process 层
  这一层属于业务操作层,我将每个流程抽象成一个process(后面会说明),保持process可拓展性
  util层
  这一层主要是辅助工具,包括xmlObjTool、timeTool等
  二、抽象
  这里先大概描述下,在业务场景的每一层中抽象的原因,后面会详细讲下工作流程。
  database 层
  考虑到sdk是允许跨进程访问的,因此model层采用ContentProvider作为通信层。由于在该模块中下发的所有配置数据类型是多种的,这说明在存在一个DBHelper中,必然需要管理多个Dao。所以这里面如何在配合多个Dao中,与contentprovider进行多个监听协同工作?所以这里面首先在模块中抽象一个BaseRole,数据操作角色的工作模板。
  network 层
  该模块网络请求层不打算依赖第三方,因此直接使用apache包作为底层http请求层。至于抽象是比较好理解的,首先请求目标对于模块层是不需要理会的,模块关心的只是请求时、请求结果。因此无论是https、http,只需要抽象一个Iprotocol,负责请求seesion同步、header处理、缓存处理等工作模块为请求目标服务即可。
  process 层
  首先,每个流程操作都是独立线性的,两个流程之间也是不能互相干扰的。例如A流程和B流程,A流程与B流程没有任何直接关系,并且需要保证A流程执行完成后才能进行B流程。因此,这里抽象成一个process工作流程。目前模块只需要两个流程,分别为配置下发process与鉴权process,考虑到以后的拓展性,当然不能“限死”在这两个里面了。
  util 层
  三、设计
  database 层
  database.png
  AppContentProvider继承于ContentProvider,在ContentProvider中会有UriMatcher这个角色,用于解析Uri,并从Uri中获取数据。所以我们在设计role与uri之间关系的时候,可以通过定义一个code作为中间属性、并且定义一个
  关联code与role、因此可以建立如图所示的关系:
  code.png
  整一个设计通过结构图我们可以了解到(a)到(d)的流程
  (a) 定义了一个DBHelper和AppContentProvider,DBHelper负责创建数据库和表结构,以及处理版本升级的职责;而AppContentProvider则负责监听来自上层针对指定uri的数据操作,同时也是负责处理role与uri之间数据操作的中间件
  (b) 根据BaseRole数据库抽象操作模板,根据数据类型的不同定义了具体的数据库操作role,并且将所有role注入到AppContentProvider中的SparseArray表中(底层由两个数组组成,相对hashmap更节约内存),并且通过code建立起uri与role直接的关系
  (c) 假设Application层通过uri进行了query操作,会调用到ContentProvider query方法,通过UriMatcher解析uri等到对应的code之后,再通过SparseArray找到目标role,分发给对应的role去执行数据库操作
  (d) 最后,当分发好的role执行完成后,通过回调给AppContentProvider数据源后通过ContentResolver的notifyChange反馈给Application层。
  本质上ContentProvider是一种观察者模式,可以很好的完成跨进程通信交互。
  设计优势:
  1、数据库操作分层,对应的数据表类型有自己一套操作逻辑。并且支持动态拓展
  2、role动态绑定ContentProvider层,可跨进程访问到数据
  network 层
  这一层相对比较简单,直接可以看结构图理解。
  network.png
  Iprotocol为协议层,具体实现交给下面的HTTP、HTTPS子类去实现(包括session保持、header处理、请求参数处理等),并且网络异步请求依赖于AsyncTask去试下一系列的Http请求。
  process 层
  processmanger.png
  首先要说下process流程,在整个模块执行过程中,应该会有A、B、C...等流程,是线性执行且不可互相干扰的,即A->B->C-....>N。当然,在每个大流程中可能还会有小流程,例如A中,可能会有a、b、c这样的小流程,如图所示:
  Drawing3.png
  其次processManager这里要说两个角色,processWorker与processEvent。在初始化processManager的时候,会自动注册定义好的processWorker和processEvent。processWorker与processEvent直接通过委托IProcessCallback与中间件processManager进行交互工作。
  processWorker
  前面描述过在模块中有流程这个定义,例如A流程和B流程,A流程与B流程没有任何直接关系,并且需要保证A流程执行完成后才能进行B流程。所以我们把每个流程都抽象成一个processWorker,而且都根据IProcess规范好流程的执行流程。在上面的结构图中例如定义了鉴权AuthProcess、配置下载DownloadProcess。两者都是需要提前注册到ProcessManager管理之间,借鉴于要保持两者执行是线性的,因此有一个linkedList保持管理他们的执行顺序,这是processWorker的作用。
  processEvent
  了解到每个流程执行的时候,在保证process执行的完整性前提,要求要告诉processManager中间件执行结果,所以这里涉及到执行结果的成功与失败。前面描述过,每个大流程执行直接有多个执行步骤(a-n),这里允许我们通过processEvent中的dispathEvent进行拦截,只是拦截,其不会干预流程执行的完整性。
  processWorker与processEvent交互
  中间件processManager中维护着一个IProcessCallback回调列表,本身processManager初始化的时候会维护自己一个默认的IProcessCallback,属于强引用。当然允许外界注入监听process的回调,但是属于弱引用。事件传递如下图所示:
  process -> IProcessCallback(processManager或其他)->processEvent
  读者可能会抱着怀疑,事件传递为什么不是process->processEvent就行,process维护自己的事件处理不是更方便维护么?process -> IProcessCallback(processManager或其他)->processEvent 这样设计,有个好处。首先笔者设计的时候,不希望单独给process太大的权限,Manager才是老大,事件决定权大于process,针对以后一些特殊拦截,Manager可以放出接口注入这些特殊拦截事件,所以由Manager进行优先处理。
  最后的Util层不做太多的详细说明,最后贴一个整体设计图
  all.png
  设计的不是很好,望读者多给建议交流交流。架构这种东西只能通过慢慢总结经验和拥有广泛的知识才能够提升。




上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号