Android MVP浅析

作者: Hello_Google | 来源:发表于2016-05-11 14:51 被阅读668次

前言

近期一直在看设计模式相关的资料,每逢结尾都会介绍到 MVC 模式,而最近比较火的却是 MVP 和 MVVM ,更有甚者,将 MVP 和 MVVM 结合起来形成了 MVPVM ,大神的造诣总是让俺望其项背,下面就结合自己的学习,浅析 MVP。

从哪里开始学习呢?当然是从 Google 自身开始咯,Google 推出了自己的官方 MVP 架构例子。源码地址

相关翻译

今天就主要来看看官方写的最基础的 MVP 的例子 todo-mvp。本文不打算讲解里面代码的具体实现,只是从宏观角度看一下,Google是如何实现 MVP 模式的,细节需要自己慢慢体会,每个人的体会都会不一样的。(里面还涉及到了测试相关的东西)

剖析

Step One

首先从 Github 上 clone 下来,然后本地运行起来,效果如下

这是一个简版的便签,相关数据存储在本地数据库中。知道这个 App 是干嘛的,对下面分析相关代码就好理解了。

Step Two

看代码,找关系,官方的代码结构如下

看目录

  • addetitask:添加/修改任务功能
  • statistics:分析功能(位于侧边栏上)
  • taskdetail:查看任务详情
  • tasks:首页界面,展示任务列表
  • data:数据操作相关
  • util:工具类相关

通过目录,这个 App 的相关操作也就一目了然了,接下来就针对 task 目录下的代码进行分析,看看是如何体现 MVP 思想的。

Step Three

分析前,先认识一下 MVP ,至少了解一下代表的含义

MVP (Model-View-Presenter) 该模式包含以下几个方面

  • View:负责绘制 UI 元素、与用户进行交互(Activity/Fragment);
  • View interface:需要 View 实现的接口,View 通过 View interface 与 Presenter 进行交互,降低耦合,方便进行单元测试;
  • Model:负责存储、检索、操纵数据(有时也实现一个Model interface 用来降低耦合);
  • Presenter:作为 View 与 Model 交互的中间纽带,处理与用户交互的负责逻辑。

先掌握上面的基础概念就可以,下面进入正题

Step Four

task 目录下包含了以下几个文件

  • ScrollChildSwipeRefreshLayout:自定义控件,扩展了 SwipeRefreshLayout
  • TasksActivity:程序入口
  • TasksContract:关联了 View 和 Presenter,是个接口
  • TasksFilterType:是个枚举类,里面定义了 Tasks 列表的状态;
  • TasksFragment:展示 Tasks 列表等相关操作的 Fragment;
  • TasksPresenter: Presenter,负责关联 View 和 Model

它们的关系用类图来表示,如下图所示

其中数据类的相关 java 类简化表示了,详细的自行查阅 Github 上的内容

从上面可以看到,Google 首先定义了两个接口文件 BaseView 和 BasePresenter,然后又通过 接口 TasksContract 进行关联,所有用到上面两个接口的都是通过 TasksContract 进行管理。

看上面的图,好像有点繁杂,眼花缭乱的感觉,那就先搬一张 MVP 模式基本的类图,如下

那么结合上图,怎么根据上面进行划分呢,其实非常容易,如下

上面标的还不算特别好,其中 BaseView 也属于 View 里面,BasePresenter 属于 Presenter 范畴

如果大家仔细看的话,就会发现,View 和 Model 直接是没有任何关联的哦,而 Presenter 和 Model 和 View 都是有关联的,现在在和上面标准的类图进行对比,是不是就一目了然啦。如果大家对里面的代码细节感兴趣,请自行查阅源码哦。

对了,说一点,里面的 TasksActivity 的作用就是将 Presenter 和 TasksFragment 关联起来(不贴点代码好像也不行了)

TasksFragment tasksFragment =
            (TasksFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);
    if (tasksFragment == null) {
        // Create the fragment
        tasksFragment = TasksFragment.newInstance();
        ActivityUtils.addFragmentToActivity(
                getSupportFragmentManager(), tasksFragment, R.id.contentFrame);
    }

    // Create the presenter
    mTasksPresenter = new TasksPresenter(
            Injection.provideTasksRepository(getApplicationContext()), tasksFragment);

    // Load previously saved state, if available.
    if (savedInstanceState != null) {
        TasksFilterType currentFiltering =
                (TasksFilterType) savedInstanceState.getSerializable(CURRENT_FILTERING_KEY);
        mTasksPresenter.setFiltering(currentFiltering);
    }

Step Five

再来审视一下 MVP

  • M:Model,数据相关,主要就是提供数据的存取功能,像一个数据仓库。Presenter 需要通过 Model 层存、取数据。
  • V:View,用户界面,也就是Activity、Fragment、View控件等,它持有 Presenter 的一个成员变量。通常 View 需要实现一个逻辑接口(示例就是这样做的),将 View 上的操作会转交 Presenter 来年实现。最后,Presenter 调用 View 的逻辑接口将结果返回给 View 元素。
  • P:Presenter,交互中间人。沟通 Model 和 View 的桥梁,将 Model 和 View 之间的关联斩断掉,改为 Presenter 进行联络。这也是和 MVC 模式最大的不同。

MVP 的优点

  • 看类图就知道,首先就是分离了 View 和 Model,降低了耦合
  • 易于维护、测试,一目了然,接口的存在,大大降低了测试的复杂度
  • 代码的可阅性就变的容易了
  • 类型的职责明确,各司其职,应用 MVP 时,会感觉到,结构清晰明了,爽

说完优点,肯定有缺点的,谁让没有一个模式都是金光闪闪,毫无缺点的。

  • Presenter 负责沟通 Model 和 View ,当然不可避免的就会“臃肿”起来
  • 有 View 的存在,就会有 Presenter 的存在,而在实际项目中,一个界面往往有很多的 View 构成,那么想想也是很“激动”的

最后

每个模式的出现,都会解决其他模式的缺点,却又不可避免的带来自身的缺点,然后等着下一模式的出现来解决上一模式的缺点,周而复始。也正是这样的循环,让我们不断的向更好的方向进步,例如: MVVM 的出现。

想要深入学习,查看具体实现方式,请自行下载相关代码进行研究。

参考资料

Android开发艺术探索[M]. 电子工业出版社, 2015.487-494

Android官方MVP架构示例项目解析

Google Android MVP Pattern 知识整理

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

如何设计MVP中的Presentation层

相关文章

网友评论

    本文标题:Android MVP浅析

    本文链接:https://www.haomeiwen.com/subject/sclurttx.html