V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kaedea
V2EX  ›  Android

Android MVP 模式 简单易懂的介绍方式

  •  
  •   kaedea · 2015-10-12 17:57:58 +08:00 · 9786 次点击
    这是一个创建于 3336 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Android MVP 模式也不是什么新鲜的东西了,我在自己的项目了也普遍地使用了这个设计模式。当项目越来越庞大、复杂,参与的研发人员越来越多的时候,MVP 模式的优势就充分显示出来了。

    基本信息

    什么是 MVC 模式

    MVP 模式( Model-View-Presenter )可以说是 MVC 模式( Model-View-Controller )在 Android 开发上的一种变种、进化模式。后者大家可能比较熟悉,就算不熟悉也可能或多或少地在自己的项目中用到过。要介绍 MVP 模式,记不得不先说说 MVC 模式。 MVC 模式的结构分为三部分,实体层的 Model ,视图层的 View ,以及控制层的 Controller 层。

    MVC 结构
    可耻盗用Bison的图(/ω\)ハズカシーィ’

    其中 View 层其实就是程序的 UI 界面,用于向用户展示数据以及接收用户的输入;而 Model 层就是 JavaBean 实体类,用于保存实例数据; Controller 控制器用于更新 UI 界面和数据实例。

    例如, View 层接受用户的输入,然后通过 Controller 修改对应的 Model 实例;同时,当 Model 实例的数据发生变化的时候,需要修改 UI 界面,可以通过 Controller 更新界面。( View 层也可以直接更新 Model 实例的数据,而不用每次都通过 Controller ,这样对于一些简单的数据更新工作会变得简单许多。)

    举个简单的例子,现在要实现一个飘雪的动态壁纸,可以给雪花定义一个实体类 Snow ,里面存放 XY 轴坐标数据, View 层当然就是 SurfaceView (或者其他视图),为了实现雪花飘的效果,可以启动一个后台线程,在线程里不断更新 Snow 里的坐标值,这部分就是 Controller 的工作了, Controller 里还要定时更新 SurfaceView 上面的雪花。进一步的话,可以在 SurfaceView 上监听用户的点击,如果用户点击,只通过 Controller 对触摸点周围的 Snow 的坐标值进行调整,从而实现雪花在用户点击后出现弹开等效果。具体的 MVC 模式请自行 Google 。

    重点要说的 MVP 模式

    在 Android 项目中, Activity 和 Fragment 占据了大部分的开发工作。如果有一种设计模式(或者说结构)专门是为优化 Activity 和 Fragment 的代码而产生的,你说这种模式重要不?这就是 MVP 设计模式。

    按照 MVC 的分层, Activity 和 Fragment (后面只说 Activity )应该属于 View 层,用于展示 UI 界面,已经接收用户的输入,此外还要承担一些生命周期的工作。 Activity 是在 Android 开发中充当非常重要的角色,特别是 TA 的生命周期的功能,所以开发的时候我们经常把一些业务逻辑直接写在 Activity 里面,这非常直观方便,代价就是 Activity 会越来越臃肿,超过 1000 行代码是常有的事,如果有进行代码重构经验的人,看到 1000+行的类肯定会有所顾虑。因此 Activity 不仅承担了 View 的角色,还承担了一部分的 Controller 角色,这样一来 V 和 C 就耦合在一起了,虽然这样写方便,但是如果业务调整的话,要维护起来就难了,而且在一个臃肿的 Activity 类查找业务逻辑的代码也会非常蛋疼,所以有必要在 Activity 中,把 View 和 Controller 抽离开来,而这就是 MVP 模式的工作了。

    MVP 结构

    MVP 把 Activity 中对 View 的操作抽象成 View 接口,把业务逻辑的操作成 Presenter 接口, Model 类还是原来的 Model。这就是 MVP 模式,现在这样的话, Activity 的工作的简单了,只用来响应生命周期,其他工作都丢到 Presenter 中去完成。从上图可以看出, Presenter 是 Model 和 View 之间的桥梁,为了让结构变得更加简单, View 并不能直接对 Model 进行操作,这也是 MVP 与 MVC 最大的不同之处。

    MVP 模式的作用

    MVP 的好处都有啥,谁说对了就给他……

    • 分离了视图逻辑和业务逻辑,降低了耦合
    • Activity 只处理生命周期的任务,代码变得更加简洁
    • 视图逻辑和业务逻辑分别抽象到了 View 和 Presenter 的接口中去,提高代码的可阅读性
    • 把业务逻辑抽到 Presenter 中去,避免后台线程引用着 Activity 导致 Activity 的资源无法被系统回收从而引起内存泄露和 OOM
    • Presenter 被抽象成接口,可以有多种具体的实现,所以方便进行单元测试

    说了这么多,没看懂?好吧,我自己都没看懂自己写的,我们还是直接看代码吧。

    MVP 模式的使用

    上面一张简单的 MVP 模式的 UML 图,从图中可以看出,使用 MVP ,至少需要经历以下步骤:

    1. 创建 IPresenter 接口,把所有业务逻辑的接口都放在这里,并创建它的实现 PresenterCompl (在这里可以方便地查看业务功能,由于接口可以有多种实现所以也方便写单元测试)
    2. 创建 IView 接口,把所有视图逻辑的接口都放在这里,其实现类是当前的 Activity/Fragment
    3. 由 UML 图可以看出, Activity 里包含了一个 IPresenter ,而 PresenterCompl 里又包含了一个 IView 并且依赖了 Model 。 Activity 里只保留对 IPresenter 的调用,其它工作全部留到 PresenterCompl 中实现
    4. Model 并不是必须有的,但是一定会有 View 和 Presenter

    通过上面的介绍, MVP 的主要特点就是把 Activity 里的许多逻辑都抽离到 View 和 Presenter 接口中去,并又具体的实现类来完成。这种写法多了 IView 和 IPresenter 接口,这在某种程度上加大了开发的工作量,刚开始使用 MVP 的小伙伴可能会觉得写法比较别扭,而且难以记住。其实一开始想太多也没有什么卵用,就是要在具体项目中多写几次,才能熟悉 MVP 模式的写法,以及享♂受其带来的好处。

    扯了这么多,但是好像并没有什么卵用,毕竟

    Talk is cheap, let me show you the code!

    具体实例项目

    具体实例项目和代码分析这里放不下了,有兴趣请移步 Android MVP 模式 简单易懂的介绍方式

    要说一句话说明 MVP ,那大概是

    通过 IVIew 和 IPresenter ,把 Activity 的UI LogicBusiness Logic分离开来, Activity just does its basic job! 至于 Model 嘛,还是原来 MVC 里的 Model 。

    都是在胡说八道,请轻拍 (〃ノωノ)

    5 条回复    2015-10-12 21:59:15 +08:00
    halou12
        1
    halou12  
       2015-10-12 20:21:45 +08:00 via Android
    回家看看
    kaedea
        2
    kaedea  
    OP
       2015-10-12 21:09:30 +08:00
    @Bison 不来交♂流一下嘛
    taisenjay
        3
    taisenjay  
       2015-10-12 21:49:15 +08:00
    @kaedea 看到你这头像…………
    ybjaychou
        4
    ybjaychou  
       2015-10-12 21:56:25 +08:00 via Android
    收藏个先,等下再看
    z273703837
        5
    z273703837  
       2015-10-12 21:59:15 +08:00
    @kaedea 你的头像。。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2544 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 04:47 · PVG 12:47 · LAX 20:47 · JFK 23:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.