Android中的MVP笔记之一:MVP是对处数据进行增删改查的原则

网上关于MVP的博客很多,本笔记作为学习google提供的MVP的学习笔记,

谷歌开发中国中文内站:https://developers.google.cn/

在网站上找到Android,点击进入后可以找到一些开发的说明帮助,谷歌也提供了一些开发模板,浏览示例代码里,可以找到 Google Samples page on GitHub。里面提供了一些开发demo,例如本文里的MVP开发模式就可以从找android-architecture  找详细的demo。

网上也有很多对于官方MVP demo解读的文章。例如这篇文章就有比较详细的说明http://www.cnblogs.com/mengdd/p/5988104.html

 

以下是MVC的框架图:

这里写图片描述

以下是MVP的框架图:

这里写图片描述

借用网上的图对于MVC与MVP的区别, 在MVC框架中,View是可以直接读取Model模型中的数据的,Model模型数据发生改变是会通知View数据显示发生相应的改变,导致View既需要负责视图的显示和数据的处理。而在MVP中Model和View之间的没有任何联系,是两个完全独立的模块,当Model模型发生数据改变时,通过Presenter通知View视图发生相应的UI改变,View层只需要接受 Presenter的数据,并在视图上做相应的改变。

SampleDescription
todo‑mvp Demonstrates a basic Model‑View‑Presenter (MVP) architecture and provides a foundation on which the other samples are built. This sample also acts as a reference point for comparing and contrasting the other samples in this project.
todo‑mvp‑loadersFetches data using the Loaders API.
todo‑databindingUses the Data Binding Library.
todo‑mvp‑cleanUses concepts from Clean Architecture.
todo‑mvp‑daggerUses Dagger2 to add support for dependency injection.
todo‑mvp‑contentprovidersBased on the todo-mvp-loaders sample, this version fetches data using the Loaders API, and also makes use of content providers.
todo‑mvp‑rxjavaUses RxJava to implement concurrency, and abstract the data layer.

Samples in progress

SampleDescription
dev‑todo‑mvp‑tabletAdds a master and detail view for tablets.
dev‑todo‑mvvm‑databindingBased on the todo-databinding sample, this version incorporates the Model‑View‑ViewModel architecture.

For information about planned samples, see "New sample" issues.

External samples

External samples are variants that may not be in sync with the rest of the branches in this repository.

SampleDescription
todo‑mvp‑fragmentlessUses View objects instead of Fragment objects.
todo‑mvp‑conductorUses the Conductor framework to refactor the app to use a single Activity architecture.

官方中对MVP有一个比较详细的demo代码,一个完整的数据增删改查的过程。

共有11个完整的示例,从简单到复杂,一步一步的说明MVP如何的工作。

先看第一个todo‑mvp工程,demo分四个界面,

1.列表页,具体功能有A:显示全部Task列表,B:显示状态为Active状态的Task列表,C:显示状态为Completed状态的Task列表 ,D:刷新列表,E:清除Completed状态的数据。

2.详情页,修改页,两个页面是同一个,可以从详情状态变成修改状态,并有删功能。

3.创建页,创建一个task,

4.统计页 ,统计Active状态的Task和Completed状态的Task有多少个。

 

先分析列表页的View, Presenter和Data三层接口

Data层接口

public interface TasksDataSource {
    interface LoadTasksCallback {
        void onTasksLoaded(List<Task> tasks);
        void onDataNotAvailable();
    }

    interface GetTaskCallback {
        void onTaskLoaded(Task task);
        void onDataNotAvailable();
    }
  
   
    void getTasks(@NonNull LoadTasksCallback callback);//获取Tasks列表
    void saveTask(@NonNull Task task);//保存一个tasks
    void completeTask(@NonNull Task task);//把一个task标记为completed
    void clearCompletedTasks();//清除completed状态的task
    void deleteTask(@NonNull String taskId);//删除一个task
    void refreshTasks();//刷新列表。
    一系列的增删改查的方法....省略,具体可以查看官方提供的完整demo.
}

TasksDataSource   的子类除了TasksLocalDataSource,TasksRemoteDataSource外,还有一个TasksRepository,TasksRepository组合了TasksLocalDataSource,TasksRemoteDataSource两个实例,TasksRepository负责与Presenter层交互,作为P层与Data层交互的桥梁, TasksLocalDataSource,TasksRemoteDataSource 并不直接与Presenter层交互。TasksRepository是一个单例。

 

Presenter与View层

这两层都写在一个叫TasksContract的接口类中

public interface BaseView<T> {
    void setPresenter(T presenter);
}
public interface TasksContract {

    interface View extends BaseView<Presenter> {
       /* 与数据相关的一些方法*/
        void showAddTask();
        void showTaskDetailsUi(String taskId);
        void showTasks(List<Task> tasks);

        /*告知Presenter层View层的一些状态相关的方法。*/
        boolean isActive();

        /*单纯的界面显示方法*/
        void showFilteringPopUpMenu();
        ...省略,一系列界面的显示与提示。具体请查看官方完整代码。
    }

    interface Presenter extends BasePresenter {
        
        /**与界面交互的一些方法*/
        void result(int requestCode, int resultCode);
        void addNewTask();

        /*对数据增删改查的一系列操作*/。
        void loadTasks(boolean forceUpdate);
        void openTaskDetails(@NonNull Task requestedTask);
        void completeTask(@NonNull Task completedTask);
        void activateTask(@NonNull Task activeTask);
        void clearCompletedTasks();

        /**一些与数据相关的和界面相关的过程变量*/
        void setFiltering(TasksFilterType requestType);
        TasksFilterType getFiltering();
    }
}

由上面的接口定义可知,

View层定义是一些与数据相关的并与界面相关的一些方法,例如

  • void showAddTask();
  • void showTaskDetailsUi(String taskId);
  • void showTasks(List<Task> tasks);

或者是一些Presenter层与View层的交互时,Presenter需要知道的View层的一些生命周期状态相关的方法。例如

  • boolean isActive();

或者单纯的界面的提示的一些方法如void showNoTasks()

一些与数据操作无关的方法,一般不定义在View层的接口里,如从列表页跳转到统计页就是与数据操作无关的方法,相应的因为View层不处理数据,所以View层只处理动作与数据展示,Presenter层处理数据相关的逻辑。

 

Data层的实例创建需要的对象与参数

private TasksRepository(@NonNull TasksDataSource tasksRemoteDataSource,
                        @NonNull TasksDataSource tasksLocalDataSource) {
    mTasksRemoteDataSource = checkNotNull(tasksRemoteDataSource);
    mTasksLocalDataSource = checkNotNull(tasksLocalDataSource);

View层

todo‑mvp的官方示例中,View层就是一个实现了TasksContract.View接口的Fragment,和普通的Fragment并没有什么的不同

public static TasksFragment newInstance() {
    return new TasksFragment();
}

Presenter层的实例创建需要的对象与参数

public TasksPresenter(@NonNull TasksRepository tasksRepository, @NonNull TasksContract.View tasksView) {
    mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
    mTasksView = checkNotNull(tasksView, "tasksView cannot be null!");
    mTasksView.setPresenter(this);
}

从上面的构造方法中可以知道。

Presenter用成员变量组合的方式, 持有 了View层实例与Data数据层的实例,

而 mTasksView.setPresenter(this);这句也表明了View层也持有Presenter的引用

数据层是独立的一层,只提供一个单供给外部对象用。这样就实现了

这里写图片描述界面与数据逻辑操作的分离,View层只关注与界面的展示。

 

下面分析一下,数据查、改、增、删操作时,MVP三层工作的过程。

用一个加载全部Task列表的过程来说明MVP对数据查找与展示的过程。

获取全部Task的显示和获取Active状态和Completed状态的Task列表显示是相同的过程,只是在

View层在调用 Presenter层的void loadTasks(boolean forceUpdate);前先调用了Presenter的void setFiltering(TasksFilterType requestType);,加载数据时,会判断当前的TasksFilterType  并加载相应类型的数据。

Task状态的改变等操作与加载列表显示的过程大同小异。

官方todo‑mvp项目个人总结。

1.定义数据层,View层,和Presenter接口,View层接口一般定义一些与数据展示有关的方法和界面上的操作会引起数据变化需要Presenter逻辑处理数据后过才能展示的接口方法。

2.View层和Presenter层相互持有对方的实例引用,数据层只被Presenter层持有,不被View层持有,所有需要处理数据的逻辑都放在Presenter层处理。这样就达到了View层与数据层分离。

转载于:https://my.oschina.net/u/3038281/blog/846564

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值