拒绝纸上谈兵--从维护了一年的项目中抽取的MVP框架

本框架抽取自本人真实项目,持续维护了近一年时间,不过几个月前才真正放到远程仓库。对于mvp的理解,从一开始的网上初步了解,到自己进行项目重构,一路下来仅仅针对mvp这块的重构大大小小差不多有5,6次的样子,也算是略有体会,特此贡献出来,希望能对才开始用mvp或者已经使用了mvp框架进行开发的同学们带来一丝灵感╮(╯▽╰)╭。

备注:
本框架取自项目,所以会一直维护,不存在停更的情况,如果有同学大胆尝试我的开源框架,本人也会尽力满足大家的要求,当然大家看完后,有什么意见也欢迎在评论中提出。
再来个备注:
基于专一职能的原则,本人的框架没有集成任何网络,图片,rxJava之类的框架,仅仅引用了一个动态权限库和官方的dataBinding,这是和大多数架构类框架开源库的一个很大的区别。
开源地址:https://github.com/AcgnCodeMonkey/MVPLibrary

MVP模式扩展-->MVPH模式

使用简单,易扩展,易维护,低耦合,高复用是MVPH的目标


引用方式 :

compile 'com.xujl:BaseLibrary:0.1.2'

架构思路简介

  MVP的基本思想这里不做过多解释,有兴趣的同学可以在网上找相应资料学习一下。

  比较深入学习过MVP模式的同学都知道,MVP现在比较大众的使用方法有两种:

  1. 使用activity作为view层,创建一个presenter和model与之对应,配合使用。
  2. 使用activity作为presenter层,创建一个view和model与之对应,配合使用。

  这两种方式各有优劣,这里不做过多阐述,本库采用的是第二种方式实现。MVPH与传统MVP的最大区别在于逻辑的实现上。以model为例,
传统MVP中通常会把存储数据的逻辑写在某些BaseModel中,这样Presenter需要获取某些数据时就可以直接调用
Model中封装好的对应方法。一般来讲这么写没有太大问题,但是特别的,如果我们遇到某个特定业务,需要处理某些
数据,并且这个处理有可能还会出现在其他很多界面,此时基于传统MVP通常会有两种方法来解决:

  1. 因为一个Presenter是可以包含多个Model的,所以让多个需要处理这种业务的Presenter都引用这个处理数据的Model
  2. 封装这段处理业务的逻辑成为一个新的BaseModel,这样,其他地方的Model只需要继承这个Model就能包含这段业务处理能力

  以上两种方法都有比较致命的问题,第一种方法的问题在于,Presenter虽然可以对应多个Model,但是通常每个Model会有自己
比较特别的业务逻辑,如果直接引用,会造成一些不该出现的方法也能被Presenter调用,而且采用一个p对应多个m,会造成对Model管理的复杂度增加。第二种方法的问题就更明显了,继承已经是最大的问题
,由于Java中类只能单继承,所以说当你继承了这个特定业务的Model时就代表无法再去继承其他类了,那么问题来了,如果这时需求变更,
又突然出现一个需要多次使用的数据处理逻辑,并且和之前的Model没有任何联系时,你要怎么办呢?

  当然,这种问题对于有一定经验的程序猿当然是没有任何难度的,我们通常可以选择单独封装一个类来处理一部分特定通用逻辑
,这样Model再去引用这个Helper类就能使用通用的数据处理逻辑了。这个其实就是大家常说的少用继承多用组合的设计原则。

MVPH的核心思想也正是基于这种思想,MVP只提供基本的设计框架,实际的业务逻辑(这里特指那些很多界面多次出现的业务逻辑)
全部交由每种业务对应的ViewHelper,PresenterHelper,ModelHelper去处理具体逻辑,MVP各个模块只管调用Helper
类中几个方法就能实现需要的业务,采用这个方法把需要复用的逻辑独立与MVP之外的Helper类。

总结

  总的来说MVPH与传统MVP的区别在于,传统MVP对于复用逻辑的是一个View对应多个Presenter或Model(如果是以
Activity为Presenter则是一个Presenter对应多个View和Model),而MVPH的思想则是MVP只能一一对应,即一个Presenter
(Activity)对应一个View和一个Model,对于需要复用的逻辑采用组合的方式使用Helper类来实现,以达到逻辑和数据甚至视图的
多次复用,同时每个helper由mvp每个对应角色自己管理,这样,一个model可以只由自己独立的逻辑构成也可以自主或由Presenter添加某个通用功能的helper到自己内部进行功能扩展。

  注意点:虽然思想是这样的,但是我们在编写helper类的时候应该有自己的把控,因为通常helper的编写就涉及到三个,ViewHelper,ModelHelper,PresenterHelper,就像mvp一样,如果对于helper划分的粒度过细的话,非常容易造成类爆炸(mvp划分不好会造成方法数爆炸)。所以,目前来讲,只建议抽离通用性较强或者虽然使用的地方不多,但是逻辑非常复杂的业务逻辑,这样才能达到一个平衡点。


框架功能介绍

支持的功能:

  1. ToolBar动态加载.无需每个布局引用相同的ToolBar布局,只需配置一次ToolBarModule实现类。同时,支持每个activity
    单独修改ToolBar。

  2. 动态权限管理集成.框架使用了第三方权限管理库easypermissions,需要申请权限的activity只需要复写下面的方法
    并返回需要申请的对应权限数组即可,当然你也可以自己引用其他库处理权限,这并不会冲突。

    String[] needPermissions ();

  1. 框架中集成了activity栈管理.可以方便的一键退出所有activity或某几个activity,具体使用参考ActivityManager类
  1. 支持关闭MVP模式进行开发.我们都知道,app中某些界面的逻辑有时候非常简单,并且基本上不用过多考虑扩展性的问题,这时,使用MVP模式进行开发无疑是臃肿的,因为你可能不得不为了几行显示数据的逻辑去给他写上几个接口和类。所以MVPH提供了方法可以关闭MVP模式,让你重回MVC模式,通常你只需要复写下面的方法并返回false就可以了。而且只需要在你自己的实现基类稍作处理,就算不使用MVP模式,你依然可以使用View和Model调用他们中基础方法。

    boolean isMVP();//是否使用MVP模式
  1. 支持DataBinding.从0.1.0版本开始,正式兼容使用DataBinding进行开发

  由于为了提高框架的自由度与可扩展度,所以MVPH本身并没有封装太多功能,仅仅提供了基本的MVPH架构思路。不过在demo里
我展示了通过使用MVPH框架为基础进行扩展的一个简单套路,目前demo还比较简单,打算在后面丰富demo的功能,主要是涵盖
开发者们的大部分业务场景,这样大家在遇到一些特别的界面时能有一个参考进行开发。


1.属性方法说明

2.部分功能说明

交流群:275885217  入群密码:mvp
友情鸣谢:接口提供-http://gank.io/api

版本更新日志:

更新日期:2017/09/25 库版本:0.1.2 demo版本:1.5

  • presenter新增通过类名反射创建view和model,可以不用再传递类名
  • 抽取部分方法到接口
  • 修改activity加载流程,采用界面完全可见时才进行逻辑初始化,防止初始化时进行popupWindow弹窗引起的异常
  • 增加说明文档

更新日期:2017/09/20 库版本:0.1.1 demo版本:1.4

  • 新增mvp基础框架支持dataBinding
  • 布局加载逻辑统一由BaseViewHelper进行控制,加载配置由新增类LayoutConfig进行
    控制
  • 优化view和presenter的部分加载逻辑,去除部分无用方法,简化调用逻辑
  • 修正部分不规范的方法名,逻辑复杂处添加更多注释
  • 修改BaseFragment懒加载的部分代码
  • demo中原dataBinding示例界面,改为直接继承CommonPresenter,去除之前封装的
    dataBindingPresenter等类
  • 新增方法说明文档(持续更新,逐步完善)

更新日期:2017/09/18 库版本:0.0.9 demo版本:1.3

  • 更改helper基类用法,基础model,view,presenter,helper类改为继承BaseMvpHelper
    (原BaseHelper)类,新的BaseHelper类为其他自定义helper类的基类,并且只有
    基础BaseMvpHelper的子类才具有添加BaseHelper类的功能(之前是任意BaseHelper
    子类都可以添加),自定义的helper类无法往自己内部添加helper类。
  • baseView新增findView方法,可以直接调用,不用再需要使用mRootView,也不需要类型强转
  • demo依赖RxLibrary方式变更
  • demo资讯新增viewPage+fragment分类,增加启动页面,首页导航增加二维码扫描
  • demo的AppLibrary新增结合DataBinding的使用封装基类,demo中新增结合DataBinding的使用
    示例,下次更新会更改为基础库支持DataBinding。
  • 修改基础库部分字段访问权限
  • 下次更新目标:优化ToolBarModule和helper类代码,优化view和presenter的模板代码,释放
    部分逻辑到helper类中,基类兼容DataBinding

更新日期:2017/09/6 库版本:0.0.8 demo版本:1.2

  • 新增baseview可控制在不使用toobar时是否为布局添加父布局
  • 修复activity和fragment销毁时未清空model和view引用
  • demo更新,引入rxjava2,新增RxLibrary,修改demo部分加载逻辑
  • demo首页变更,新增安卓资讯栏目,点击跳转webview详情页,详情页采用非mvp编写

更新日期:2017/07/24 库版本:0.0.6 demo版本:1.1

  • 修改基础库BaseView加载判断,兼容activity和fragment
  • 优化BaseToolBarModule加载逻辑,支持页面本身包含toolbar布局
  • 修复权限弹窗可以被关闭的Bug

更新日期:2017/07/14 库版本:0.0.4 demo版本:1.1

  • 修改基础库方法加载顺序,防止动态授权时引起的空指针
  • 优化toolbar,改为view引用toolbar而不是presenter引用toolbar
  • demo新增图片搜索,收藏,下载功能

更新日期:2017/07/06 库版本:0.0.3 demo版本:1.0

  • 修改exposeActivity方法返回值类型
  • 优化部分类方法
  • 从此版本开始,框架库接入了我自己的正式项目中

更新日期:2017/07/05 库版本:0.0.1 demo版本:1.0

  • 上传初步基础框架
  • 完成简单demo基础Library封装
  • 编写简单demo

Licence

Copyright 2016 Shintaro Katafuchi, Marcel Schnelle, Yoshinori Isogai

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,392评论 25 707
  • 作者:李旺成 时间:2016年4月3日 “Android MVP 详解(下)”已经发布,欢迎大家提建议。 MVP ...
    diygreen阅读 128,812评论 86 1,321
  • MVP这种架构在Android界已经基本成为标配,MVP本身也有很多写法和变种,当然,没有最好的架构,只有最合适的...
    蓝灰_q阅读 1,466评论 0 12
  • 写在前言:在即将毕业的一个晚上,我和N小姐在床上谈天说地,她历数着她的小情人,我回忆着我的小情史。这个篇章的启动,...
    任柠檬阅读 255评论 0 1
  • 我想很多人都有这样的经历:不喜欢现在的工作,每天都过得不开心,却又不得不去上班。 离开当然是最好的做法,可是很多时...
    Saraking_阅读 317评论 1 1