[译]Google官方关于Android架构中MVP模式的示例

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

概述

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

img_febb2c1aa39b4781e8e55cc83ac312a2.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相关代码布局:
img_29287830319a571576179296ea0e9107.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<Presenter> {

        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/

目录
相关文章
|
5月前
|
设计模式 存储 前端开发
MVVM、MVC、MVP三种常见软件架构设计模式的区别
MVC、MVP 和 MVVM 是三种常见的软件架构设计模式,主要通过分离关注点的方式来组织代码结构,优化开发效率。
116 12
|
26天前
|
前端开发 测试技术 数据处理
Kotlin教程笔记 - MVP与MVVM架构设计的对比
Kotlin教程笔记 - MVP与MVVM架构设计的对比
30 2
|
6天前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
10 0
|
1月前
|
前端开发 Java 测试技术
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
android MVP契约类架构模式与MVVM架构模式,哪种架构模式更好?
19 2
|
3月前
|
开发工具 Android开发
上架Google Play报错:For new apps, Android App Bundles must be signed with an RSA key.
上架Google Play报错:For new apps, Android App Bundles must be signed with an RSA key.
108 1
|
4月前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
66 4
|
3月前
|
安全 Java Android开发
Android 14适配Google play截止时间临近,适配注意点和经验
本文介绍了Android 14带来的关键更新,包括性能优化、定制化体验、多语言支持、多媒体与图形增强等功能。此外,还强调了适配时的重要事项,如targetSdkVersion升级、前台服务类型声明、蓝牙权限变更等,以及安全性与用户体验方面的改进。开发者需按官方指南更新应用,以充分利用新特性并确保兼容性和安全性。
259 0
|
5月前
|
缓存 安全 Java
提升编程效率的利器: 解析Google Guava库之集合工具类-50个示例(八)
提升编程效率的利器: 解析Google Guava库之集合工具类-50个示例(八)
|
5月前
|
缓存 算法 Java
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)
提升编程效率的利器: 解析Google Guava库之常用工具类-40个示例(七)
|
5月前
|
Shell Go 开发工具
How to decompile Google Android .apk file as readable dump【原创】
How to decompile Google Android .apk file as readable dump【原创】
34 0