博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[译]Google官方关于Android架构中MVP模式的示例
阅读量:5321 次
发布时间:2019-06-14

本文共 3855 字,大约阅读时间需要 12 分钟。

概述

该示例(TODO-MVP)是后续各种示例演变的基础,它主要演示了在不带架构性框架的情况下实现M-V-P模式。其采用手动依赖注入的方式来提供本地数据源和远程数据源仓库。异步任务通过回调处理。

5409-20161119173704451-1954894236.png

注意:MVP中View的概念是有所不同的:

  • android.view.View类我们叫它 "Android View"
  • MVP中从P接收命令的东西我们叫它”View”,后文说了,就是Fragment

Fragment

采用Fragment作为视图的载体有两个原因:

  • Activity 和 Fragment分离恰好适合用来实现MVP:Activity是创建和连接View与Presenter的总控制器
  • 适配平板设备的布局或多视图屏幕的场景都可利用Fragment框架的优势

关键概念

该App(指官方TODO-MVP示例)中有四个功能:

  • Tasks
  • TaskDetail
  • AddEditTask
  • Statistics

每个功能拥有下列代码分工:

  • 定义VIew和Presenter之间的“契约”接口
  • 一个Activity类负责创建Fragment和Presenter
  • 一个Fragment类实现VIew接口
  • 一个Presenter类实现Presenter接口
    一般来说,业务逻辑存在于Presenter中并依赖View完成Android中UI相关的工作。

View中几乎不包含逻辑:它将Presenter的命令转换为UI动作,并监听用户动作传递给Presenter。

“契约”接口用于定义View和Presenter之间的联系。

(译注:

有人立马就问到M哪去了,官方实例里M是轻的,与Repository和DataSource概念分离。在官方的另一个示例中有进一步的描述:http://www.cnblogs.com/x3d/p/6108998.html

/** * Immutable model class for a Task. */public final class Task {    @NonNull    private final String mId;    @Nullable    private final String mTitle;    @Nullable    private final String mDescription;    private final boolean mCompleted;@NonNull    public String getId() {        return mId;    }    @Nullable    public String getTitle() {        return mTitle;    }    @Nullable    public String getTitleForList() {        if (!Strings.isNullOrEmpty(mTitle)) {            return mTitle;        } else {            return mDescription;        }    }    @Nullable    public String getDescription() {        return mDescription;    }    public boolean isCompleted() {        return mCompleted;    }    public boolean isActive() {        return !mCompleted;    }    public boolean isEmpty() {        return Strings.isNullOrEmpty(mTitle) &&               Strings.isNullOrEmpty(mDescription);    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Task task = (Task) o;        return Objects.equal(mId, task.mId) &&               Objects.equal(mTitle, task.mTitle) &&               Objects.equal(mDescription, task.mDescription);    }    @Override    public int hashCode() {        return Objects.hashCode(mId, mTitle, mDescription);    }    @Override    public String toString() {        return "Task with title " + mTitle;    }}

DataSource、Repository相关代码布局:

5409-20161119180217998-512366159.png

契约接口定义:

package com.example.android.architecture.blueprints.todoapp.taskdetail;import com.example.android.architecture.blueprints.todoapp.BasePresenter;import com.example.android.architecture.blueprints.todoapp.BaseView;/** * This specifies the contract between the view and the presenter. */public interface TaskDetailContract {    interface View extends BaseView
{ void setLoadingIndicator(boolean active); void showMissingTask(); void hideTitle(); void showTitle(String title); void hideDescription(); void showDescription(String description); void showCompletionStatus(boolean complete); void showEditTask(String taskId); void showTaskDeleted(); void showTaskMarkedComplete(); void showTaskMarkedActive(); boolean isActive(); } interface Presenter extends BasePresenter { void editTask(); void deleteTask(); void completeTask(); void activateTask(); }}

)

项目依赖

  • Common Android support 库 (com.android.support.*)
  • Android Testing Support 库 (Espresso, AndroidJUnitRunner…)
  • Mockito
  • Guava (null checking)

特性

复杂度 - 易理解性

使用架构性框架/库/工具类:

概念复杂度

低,基于Android的纯MVP实现。

可测试性

单元测试

高,Presenter可被单元测试,和仓库与数据源一样。

UI 测试

高,允许使用fake模块注入伪造(fake)数据进行测试。

代码对比

相比于不使用架构的传统项目,该示例引入了额外的类和接口:Presenter、Repositiy、契约接口等,所以MVP中代码行数更多一些。

语言 文件 空行 注释 代码
Java 46 1075 1451 3451
XML 34 97 337 601
SUM 80 1172 1788 4052

可维护性

简化功能的维护或新功能的迭代

学习成本

相关功能代码能容易查找定位、代码职责清晰。开发者无需熟悉任何外部的依赖就能对该项目开展工作。

Github项目地址:https://github.com/googlesamples/android-architecture/

转载于:https://www.cnblogs.com/x3d/p/android-mvp.html

你可能感兴趣的文章
初入计算机图形学(二):对bidirectional path tracing的一些困惑
查看>>
关于hive的优化
查看>>
MPLS LDP随堂笔记1
查看>>
[Algorithm] 二分查找之旅
查看>>
[02] mybatis-config.xml 全局配置文件解析
查看>>
centos7安装redis单机版
查看>>
微商竟然靠这样引流?佛山抖音培训老师告诉你其中奥秘
查看>>
function语句和function表达式的随笔
查看>>
ASCII键值查询
查看>>
hdu4393 Throw nails(只用模拟前面500来次,后面根据速度、位置、id值排序即可)
查看>>
生成器函数 推导式
查看>>
Linux下ctrl+c/z/d的区别
查看>>
P3377 【模板】左偏树(可并堆)
查看>>
require和import的区别
查看>>
Final发布文案+美工
查看>>
扩展entityframework.extended使之支持整个实体类更新
查看>>
FFMpeg框架代码阅读
查看>>
网络流模板
查看>>
leetcode 493 Reverse Pairs
查看>>
Objective-C、C++和swift 的运行效率比较
查看>>