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 层
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这里要说两个角色,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层不做太多的详细说明,最后贴一个整体设计图


all.png

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

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

2018.4.5
siven

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 2.1 Activity 2.1.1 Activity的生命周期全面分析 典型情况下的生命周期:在用户参与的情况下...
    AndroidMaster阅读 2,972评论 0 8
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 1.什么是Activity?问的不太多,说点有深度的 四大组件之一,一般的,一个用户交互界面对应一个activit...
    JoonyLee阅读 5,665评论 2 51
  • 丸子不是专业的,开这个小铺只是为了帮助大家,所以小铺所有的服务均为免费的! 如果有意见要下单的亲们,可以留言,按不...
    桢桢小丸子阅读 892评论 7 5
  • 深宵不寐忆曾经,故事幽幽谁愿听。 多少友人成过客,无情岁月去无声。
    林月寒阅读 213评论 1 7