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

简介

各位好,近期回顾下以前的一些架构设计,准备总结一下。分享给其他开发者,希望碰碰架构设计思维,提升下自己。

首先 说说自己,本人2014年底参与Android开发工作,距今已经从事移动客户端开发几年了,所谓T型技能型发展,在深入地学习Android技能开发,再以后端、前端为辅拓展自己的开发思维(感谢下一路上帮过我的朋友们~)。

这次讲下自己之前参与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 层

《Android 基于流程化设计的项目总结(一)》 database.png

AppContentProvider继承于ContentProvider,在ContentProvider中会有UriMatcher这个角色,用于解析Uri,并从Uri中获取数据。所以我们在设计role与uri之间关系的时候,可以通过定义一个code作为中间属性、并且定义一个
关联code与role、因此可以建立如图所示的关系:

《Android 基于流程化设计的项目总结(一)》 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 层

这一层相对比较简单,直接可以看结构图理解

《Android 基于流程化设计的项目总结(一)》 network.png

Iprotocol为协议层,具体实现交给下面的HTTP、HTTPS子类去实现(包括session保持、header处理、请求参数处理等),并且网络异步请求依赖于AsyncTask去试下一系列的Http请求。

process 层

《Android 基于流程化设计的项目总结(一)》 processmanger.png

首先要说下process流程,在整个模块执行过程中,应该会有A、B、C…等流程,是线性执行且不可互相干扰的,即A->B->C-….>N。当然,在每个大流程中可能还会有小流程,例如A中,可能会有a、b、c这样的小流程,如图所示:

《Android 基于流程化设计的项目总结(一)》 Drawing3.png

其次processManager这里要说两个角色,processWorkerprocessEvent。在初始化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层不做太多的详细说明,最后贴一个整体设计图

《Android 基于流程化设计的项目总结(一)》 all.png

设计的不是很好,望读者多给建议交流交流。架构这种东西只能通过慢慢总结经验和拥有广泛的知识才能够提升。
欢迎邮件我:sy.wu@foxmail.com
我的github:https://github.com/YuanClouds/

下一篇准备总结下之前写一个策略项目的设计,运用是工厂+策略结合的设计模式。今年给自己定个小目标,沉下来专研技术为自己的目标做好铺垫。感谢阅读,祝大家拥有一个好的假期!

2018.4.5
siven

    原文作者:DevSiven
    原文地址: https://www.jianshu.com/p/d1f744911559
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞