Android MVP设计架构优化(灵活、方便迭代)

本架构是通过使用 RxJava + RxAndroid +Retrofit2 + Butterknife搭建的。

写作目的

随着项目逐渐壮大,必须有一个完善的框架作为一个支撑,不然难以维护。针对目前流行的框架,如:MVC,MVP,MVVM,我选择了 MVP 作为 Android APP 整体架构。

下图为 MVP 架构图:

2EBDB2C6-80DD-4C57-9F53-75ED57D6E04D.png

怕我没说清楚,再具体一点:

168F2A09-4EC1-43C4-8530-F9D751376580.png

一开始,我也只是使用简单的 MVP 模式(也就是一个 activity 实现多个 view 接口,同时一个 activity 包含多个 presenter,一个 presenter 包含多个 model,presenter 包含一个 view。其实也就是标准型的 MVP 模式)。但是随着项目逐渐壮大,presenter 里的代码就越来越多,而且业务层代码也越来越不清晰了。由于我的项目架构是使用功能分类的,所以 presenter 也用功能分类,但由于 presenter 只包含一个 view 导致所有需要该 presenter 的 activity 都只能使用同一个 view,这样 view 的耦合度就很高了。对于有代码洁癖的我来说,实在有点难忍。于是我决定优化一下。

在优化之前,必须要知道设计框架目的是什么,设计框架绝对不能为设计而设计!

装逼图.jpg

设计架构的目的是什么:
通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合。这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续的测试以及定位问题。但设计不能违背目的,对于不同量级的工程,具体架构的实现方式必然是不同的,切忌犯为了设计而设计,为了架构而架构的毛病。同时希望设计的架构能够模块化,希望把跟业务无关的东西抽象出来,开发人员根本只需要写业务代码就够了。


整体思想

需要解决的问题:

  • 让 presenter 更加灵活,可以灵活使用到多个 activity 中。
  • 让项目业务更加清晰,由于产品是迭代开发的,一般就两周一个版本,必须方便迭代。
  • 新增功能模块必须方便,能形成模版,可以无脑使用。

下面开始介绍优化内容:
先上一个图,作为一个简单介绍:

179B9FB5-30F4-4037-A49F-5CE465404620.png

如图所示,view 的展示仍然由 activity 处理,presenter 仍然是中间人,model 还是业务逻辑层。不同的是,Activity 包含的 presenter 有多个,并且是放在 SparseArray 数组里面的,presenter 里也包含多个 view 和多个 model,也都是放在 SparseArray 数组里面的。如何获取具体的 presenter 或者 view、model 呢? 答案是通过 Action. Action 是重点。Action 放的是具体功能包含的操作。Action 从 Activity 传入到 Presenter,通过 Action 在 Presenter 可以判断用哪个 View 来展示界面。
我不大会画图,可能大家会喷我了。

文明图.jpg

好吧,骂完了,我继续装逼了,举个栗子吧:

比如说登录功能,个人中心需要登录、购物车结算也需要登录,那么登录就可以作为一种功能写一个 Presenter,而个人中心登录需要展示登录成功也需要展示登录失败,而购物车结算也许只需要登录成功就可以了,而不需要展示登录失败,所以我需要有两个不同的 View,一个是用于个人中心的,一个用于购物车结算。Action 怎么设置呢?就需要根据这个登录功能设置两个 Action,因为我们需要在登录 Presenter 里面根据不同的 Action 来选择 View。Presenter 在 Activity 初始化的时候传进去,并且包含展示 View 的接口和 Action,于是 Presenter 就有 Action 了,当 Action 是来自于个人中心时,Presenter 就可以根据个人中心登录的 Action 调用它独有的 View 来展示。当是来自购物车结算页面时,也可以根据 Action 来调用它独有的 View。这样就让 Presenter 灵活了。

不过马上有人会有问题了,这样 Action 会不会很混乱?
是的,如果没有统一管理的话确实会很混乱,这就是设计 Contract 和 BaseAction 的理由。Contract 跟 Presenter 是成双成对的。一个 Presenter 对应了一个 Contract,Contract 里面就把 View、Presenter、Action 绑架到一起了,这样便于管理同时便于修改。

我还害怕我没说清楚,下面给部分代码便于理解:

例如在登录功能中,用户中心登录的操作。整体使用功能分类,如图所示:

14B84020-ECC2-48F6-8D19-0D9D6A3899E1.png

user 代表用户中心,(原谅我英语不好,只能写个简单的单词)
可见我这是通过功能分类。首先冲 Activity 来。

在 LoginActivity 初始化的时候,将所需要的 Presenter 都加入进来,并且传入 Action 将他们连接起来。如下图:

EEFCE22E-2E10-465C-BD25-FE30337B4A9A.png

这样业务的 Activity 里面已经木有了 Presenter, addPresenter 是来自基类(BaseActivity)的方法,这样的好处在于我们可以统一管理 Presenter。

用户登录的 Action 可以这样写:

54F802E8-41B6-4AF0-9F29-FE7332653A14.png

因为可能有两个 Activity 需要登录功能,而需要展示不同的界面。所以写了两个 Action。

像以前一样 LoginActivity 可以实现多个 View

885CF2D9-5211-49EB-9708-E3FE7998B06A.png

但 View 已经被统一根据具体功能放入了所属的 Contract 里了。

LoginModel 写起来也很简单:

93DD27F4-A277-4A33-95BA-E331EE239FC1.png

Model 跟以前的 MVP 的 Model 层比较没什么差别,主要是考虑到 Model 并不需要抽得太多,Model 也是跟 Presenter 成双成对来写的。

好了,整体思想就是这样的啦。卖个萌:


卖萌图.JPG

有人可能会想到会不会内存泄漏,比如我这里使用 RxJava,在哪里取消订阅呢?内存在哪里释放掉呢?
答案是:不会发生内存泄漏,内存释放都在 BaseActivity 中处理,因为 Presenter 数组存在在 BaseActivity 中的。而且为了统一处理方便,presenter、view、model 都有一个唯一的基类。
那如何通过 Action 转化成对应的 Presenter、Model、View的?
答案是:通过泛型 + Class<T>,见下图:

FDA87210-1EF5-4FCF-BF9B-846B9BA92811.png

点击下载源码(github)

欢迎各位看官 star 我,同时有疑问可以随时提,我可以随时改善。最后,谢谢大家耐心看完!

————2020年3月11日 更新
最近建了微信公众号和微博,由我(卷子)和我的好朋友(樱桃)两只小程序媛经营的。
我们都喜欢程序员这个呆萌的群体,我们希望能给你带来技术上的帮助以及生活上的快乐。嘿嘿~唯一的私心就是 希望你能喜欢我们咯。
大哥,我先敬你一瓶,先干为尽


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

推荐阅读更多精彩内容