Android 项目框架 使用MVP开发

前言

在Android中使用 MVP 来开发已经出来很久了,刚好Google又出了一系列的architecture samples,在此就整理一下对于MVP的认知和实践总结,这篇文章会随着使用经验的丰富而不断更新。

1. 介绍MVC

在没有使用MVP开发之前,我们一直使用的都是MVC模式,其实也不算的MVC,一般我们听到的都是Android中的Activity既是View,又是Controller,即Activity既负责View的显示,又负责处理业务逻辑,这是我们一般听到的,但其实我们的Activity还负责了数据的保存和读取。

当业务逻辑简单,仅仅只是获取数据、展示数据时,我们的代码是这样:

但其实考虑数据的存储、业务逻辑等等,我们是这样:

所有东西都连在一起,太复杂以至于成了一个面了,这个面就是这个God Object:Activity。

想想看,我们是不是把所有东西都写在这个上帝类中了:网络请求、解析Json、处理数据、展示数据、缓存数据等等,全部都在Activity中,尽管有些东西已经封装的很好,但依旧都和Activity扯在一起,基本上所有代码都在Activity中,于是所谓的MVC,就叫做 massive view controller,超级大的ViewController。

这样做尽管有好处,很容易看清楚业务逻辑,而且写起来很方便、顺手,不知不觉就这样写了。但是很明显,随着需求不断加多,该类代码就越写越多,并且如果需求有改动的话,那改起来很费劲,而且这样写,不敢轻易重构,因为太复杂,动一点可能就会有bug。

那么不想这么做怎么办呢?于是就有了MVP。

2. 介绍MVP

典型的MVP就像这样:

很明显:

  1. MVP中Presenter和View是相互交互的。
  2. MVP拒绝View和Model直接交互,View和Model只能通过Presenter间接交互。这点是合理的,因为Android对UI的操作必须在 UIThread 上,而对Model的处理大多是异步任务。通过转接一层,可以很方便处理线程问题。
  3. Model和View是被动的,一切都由Presenter来主导

我们一般把 Activity/Fragment 当做View,那么这时我们的Activity/Fragment中的代码简单多了,响应Presenter的指令对View进行操作,而这些操作是在IVIEW 接口中定义好的。这样大部分代码转移到了Presenter中,而且一些业务代码被封装到了Model层去,这样的代码就会清晰很多,写完一看,哇塞,太清晰了。而且很容易定位bug,毕竟代码职责越清晰越不容易出错。

那么现在分开来介绍:

  • Model

    为UI层提供的数据,或者保存UI层传下来的数据。

    Model 是用户界面需要显示数据的抽象,也可以理解为从业务数据(结果)那里到用户界面的抽象。

    Model 应该封装业务逻辑,不让Presenter和View知道业务逻辑层

  • View

    View is a layer that displays data and reacts to user actions.

    View提供友好的交互、展示数据、响应用户操作,并都转发给Presenter来做具体的处理

  • Presenter

    逻辑控制层,分发逻辑。处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由业务层做具体的业务操作,然后将得到的 Model 给 View 显示。

到这里,关于MVP的基本概念讲解完了,就是分三层写代码,此处建议使用MVP时分包时按照模块分包,模块比较多时,建一个module包,装所有模块,每个模块再细分三层,这样包很清晰、代码也很清晰。

接下来看一些google的示例。

3. Google samples中的MVP

Google samples中的MVP(google MVP示例中这张图真的很完美的阐述了一个简单的app的架构):

Model层获取数据时,使用DataRepository 分发管理,从Presenter处接收指令从RemoteDataSource 或者 LocalDataSource 中获取数据,并回调给Presenter,Presenter再回调给View用于展示。

下面列出一些官方推荐 的点,这些都可以在代码中找到:

  • Use Fragments as View. The separation between Activity and Fragment fits nicely with this implementation of MVP: the Activity is the overall controller that creates and connects views and presenters,which means the Activity is responsible for the creation of fragments and presenters.

    使用Fragment作为View,Activity作为全局的Controller把presenter和view绑定起来。

  • Create a contract interface defining the view and the presenter,which contains the View interface and the presenter interface. Contracts are interfaces used to define the connection between views and presenters. This is a amazing concept.

    创建 IContract 父类接口来管理同一个模块下的 IViewIPresenter接口,这样很清楚的能看清楚两者的逻辑。

  • In general, the business logic lives in the presenter and relies on the view to do the Android UI work.

    业务逻辑全部在Presenter层,依靠View层来触发。

  • The view contains almost no logic: it converts the presenter’s commands to UI actions and listens to user actions, which are passed to the presenter.

    View几乎没有任何逻辑,响应Presenter层的指令,并接收用户操作传给Prenster。当然很少很轻量的逻辑应该在这一层中处理(判空处理等),这一点应该要自己衡量。View应该是被动的。

4. MVP是一个方法论

我们应该很容易看到在MVP中仅仅有一些基本原则,并没有一个固定的方式去实现MVP,都针对自家的业务需求、逻辑去更好的更合适的使用MVP,只要View和Model分离,代码清晰,易于调试,易于测试,都OK。

MVP的一些指导性原则来约束实现:

  • Model与View不能直接通信,只能通过Presenter
  • Presenter类似于中间人的角色进行协调和调度
  • Model和View是接口,Presenter持有的是一个Model接口和一个View接口
  • Model和View都应该是被动的,一切都由Presenter来主导
  • Model应该把与业务逻辑层的交互封装掉,换句话说Presenter和View不应该知道业务逻辑层
  • View的逻辑应该尽可能的简单,不应该有状态。当事件发生时,调用Presenter来处理,并且不传参数,Presenter处理时再调用View的方法来获取。

知道了MVP是一个方法论,下面说说MVP的另一个实现方式。

5. MVP的另一种实现方式

MVP另一个实现方式(变种)就是不像一般的把Activity/Fragment作为View,而是把他们作为Presenter来使用,单独把View用一个类来管理。

使用该种方式可以大大减少类的个数,因为是依靠 泛型 来解耦的,所以可以不用提供接口,当然提供了也行,我在实现过程中删除了接口,同时把点击事件的响应结果当成逻辑,放在Presenter中,这样就不用传来传去的。(之前使用Fragment作为View时,点击ListItem 需要修改已读状态,传入到Presenter中修改,Presenter修改完后又调用View.showDetailUI()方法又传回到View中,使用变种后这块就大大减轻工作量了)

使用这种方式个人认为有点怪异,一是使用泛型加大了理解难度,写着写着就不知道怎么调用到这块了;二是删除接口后感觉复用性降低了,逻辑也不能复用、View也不能复用,当然可以不删接口,但是不删接口和原来的MVP有什么区别呢。恩,不过这点可能随着使用MVP越深入会越能理解,Activity到底是View还是控制器,可能随着项目的偏重不同,会适合不同的情况吧。

那么说完了MVP变种,下面总结一下个人使用MVP的心得。

6. MVP心得体会

使用MVP开发,顿时感觉清爽很多,虽然多了很多代码,但是瑕不掩瑜,让代码清爽很多。真的很棒,看了重构后的代码,感觉自己之前真是活在噩梦里一样,终于不用把所有代码写在Activity里或是Fragment里了。下面就具体说说使用中的心得体会。

首先是方法论上:

  • 首先分清除什么是 分发业务逻辑、业务逻辑、视图逻辑。

    理解这三点对于设计接口、使用MVP写项目、重构等有很大的帮助。视图逻辑可以更好的写View,分发业务逻辑用于Presenter,业务逻辑用于Model,当然一些业务逻辑是在Presenter中的。

  • 然后看什么是View,什么是逻辑,哪些逻辑展示哪些View,哪些操作调用哪些逻辑,这会很好的帮助我们理清代码逻辑、方便相互调用。
  • 一个 View 可以有多个 Presenter,要用到什么业务就加入什么 Presenter,并且实现这个 Presenter 所需要的 View 接口即可,这就是简单的复用逻辑,即Presenter是可复用的。

然后是代码上:

  • IView接口里的方法全部是UI相关,show()、hide()等,不应该出现逻辑相关。
  • IPresenter接口里的方法应该全部是逻辑相关,进行分发,很明显,要持有Model引用,方便对数据进行操作。不应该出现与Model相关的方法,比如LoadFromLocal,LoadFromRemote,这应该是DataRepository处理的事情。Presenter里面只需要告诉Model说我需要这个数据,即LoadData,而不用管从哪Load数据。这里面只需要负责 分发!!!
  • Model中,对数据进行处理,所有的数据从这里进出,并对数据进行处理。一般创建DataRepository类对LocalDataSource,RemoteDataSource进行管理分发,这三个类都实现IDataSource接口,保证逻辑一致。

最后一些个人体会:

  • 在MVP里面,越来越感到依赖注入的重要性。全部是依赖,全部需要注入,感觉依赖注入框架 Dagger2 是时候展现它强大的功能了。
  • 回调太多。获取数据时,从Presenter中开始callback,再到DataRepository中,再到具体的LocalDataSource或RemoteDataSource的callback,总共回调了三层,增长了链条。很明显,解决这个问题需要用到 RxJava 了,可以省去很多代码,变得简洁是必然的。
  • Google samples 中的 IContract 接口管理类真的非常棒,管理了IPresenter和IView,如果可以的话,应该让它也管理IDataSource 这个接口,非常清晰的一种方式。
  • 尽管MVP实现了一定的分离,但相当于大量代码从Activity中转移到Presenter和Model中,尽管使用接口使代码清晰很多,但避免不了难看和难以查找,随着业务的不断复杂,代码依旧会越来越多。所以使用clean架构应该是最好。
  • 最后不得不说确实方法数、类都增加了好多。但这也是必然的。解耦、方便测试。

7. 代码实现

说了那么说,show me the code.

那么,自己写的代码全在GitHub上,全部以分支形式展现:

之后,肯定会尝试clean架构再次重构。不过由于项目本身较小,所以当个练手的真的不错。

参考:

时间: 2024-08-02 11:03:12

Android 项目框架 使用MVP开发的相关文章

1、Android项目框架搭建 (分析需求、整理资料)

闲来无事.想搭个框架试试 分析一般应用 将资料整理整理 粗略统计 需要以下资料 1.android-pulltorefresh 一个强大的拉动刷新开源项目,支持各种控件下拉刷新 ListView.ViewPager.WevView.ExpandableListView.GridView.(Horizontal )ScrollView.Fragment上下左右拉动刷新,比下面johannilsson那个只支持ListView的强大的多.并且他实现的下拉刷新ListView在item不足一屏情况下也

Android项目模块化/组件化开发(非原创)

文章大纲 一.项目模块化初步介绍二.项目模块化的两种模式与比较三.大型项目模块化的演进四.项目模块化总结五.参考文章 一.项目模块化初步介绍 1. 前言 在Android开发中,随着项目的不断扩展,项目会变得越来越庞大,而随之带来的便是项目维护成本与开发成本的增加!每次调试时,不得不运行整个项目:每当有新成员加入团队时,需要更多的时间去了解庞大的项目...而为了解决这些问题,团队通常会将项目模块化,以此来降低项目的复杂度和耦合度,让团队可以并行开发与测试,让团队成员更加专注于自己所负责的功能模块

【FastDev4Android框架开发】Android MVP开发模式详解(十九)

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49613861 本文出自:[江清清的博客] (一).前言: 今天我们的项目继续更新,今天我们主要讲解MVP开发模式以及具体实例. FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android (二).简介: MVP(Model ViewPresenter)模式是著名的MVC(Model View

框架模式MVP在Android中的使用

前一篇文章中学习了MVC框架模式在Android中的使用,不了解什么是MVC框架模式的亲戳这里 框架模式 MVC 在Android中的使用.其实谷歌Android开发团队是鼓励开发者利用MVC框架模式开发项目的,我们平时写代码也或多或少的在使用MVC框架模式开发项目,比如说谷歌自己退出来的Volley网络请求框架就是遵循MVC框架的.我们可以理解为Volley框架是MVC当中的模型,也就是网络数据处理这一块,无需跟View视图有任何关联.也符合视图和模型分离.可能你会觉得MVC框架已经很好用了,

Android项目开发第五周

本周进展:本周是此次Android项目开发最后一周,按照进度基本上完成了Android游戏开发的各项任务. 总的开发报告如下: 1.需求分析: 当前移动互联网快速发展,人们生活逐渐趋于多元化,以智能手机为代表的电子产品逐渐受到人们的追捧,手机游戏渐渐地成为了人们休闲娱乐的一种方式.本款软件是一款基于Android系统下采用2.5D技术开发的休闲益智类塔防游戏.塔防游戏是目前市场上比较流行的一类游戏. 2.系统设计: 本游戏的策划主要包含:游戏类型定位.呈现技术以及目标平台的确定等工作. 游戏类型

Android项目开发全程(二)--Afinal用法简单介绍

本篇博文接上篇的<Android项目开发全程(一)--创建工程>,主要介绍一下在本项目中用到的一个很重要的框架-Afinal,由于本系列博文重点是项目开发全程,所以在这里就先介绍一下本项目中用到的几个功能: Afinal简介 Afinal 是一个android的sqlite orm 和 ioc 框架.同时封装了android中的http框架,使其更加简单易用: 使用finalBitmap,无需考虑bitmap在android中加载的时候oom的问题和快速滑动的时候图片加载位置错位等问题. Af

IOS 与ANDROID框架及应用开发模式对比一

IOS 和ANDROID操作系统都是目前流行的移动操作系统,被移动终端和智能设备大量采用,两者都采用了先进的软件技术进行设计,为了方便应用开发两者都采用了先进的设计模式.两者在框架设计上都采用了什么技术?都采用了什么设计模式?两者设计思路和应用开发模式有什么异同呢? 两者都采用了框架模式. IOS 的框架称为Cocoa Touch. 框架提供两个作用,一是类的集合,每个类构建一个问题空间,并提供完整的解决方案和服务:二更重要的是框架中的类相互依赖构成一个整体,制订并实现整个应用程序的结构.框架定

J2EE实战开发Android项目视频教程

基于J2EE实战竭诚网上商城B2C购物系统开发配Android版购物客户端(JFreeChart3D) 适合人群:初级 课时数量:100课时 用到技术:J2EE.Android.JFreeChart3D 涉及项目:B2C购物系统 咨询qq:1840215592 一.课程适合的对象: 在javaWeb框架体系中发展的开发人员,和Android初级开发人员,并且想要提升web框架开发技能的Java开发和想从事Android开发人员. 二.课程培养目标: 1.掌握JavaWeb SSH框架组织体系.

mvp模式的android项目构建

多日未回博客园,风萧萧兮易水寒. 话说上一次发表随笔已是去年,而且看看当时关于android视频方面的记录也只写了开篇就自动阉割成了太监,究其缘由已不堪回首. 太监终究还是太监,没必要再为它续弦. 笔锋一转,近日有看几本android应用方面优化和技巧方面的书,便觉得又该在此处记录下了.有一本专门讲技巧的书还不错,<50 Android Hacks>:50个android开发诀窍. 其中有一篇是讲MVP(Model-View-Presenter)模式的,也就是模型-视图-主导器(书中翻译为此)