MVP模式讲了很久了,自己实际中也运用过,但总觉得运用的不够优雅跟简洁。这次终于等到官方出MVP的例子了,有了一个借鉴模仿的模板todomvp系列。这次先来讲一下todomvp的基础版。
todomvp代码可以分为两块
一块是公共类和基类:
一块是具体页面的实现类,比如:
先分析公共部分:
BasePresenter和BaseView很简单,主要还是作为P和V的一个类型标记作用:
public interface BasePresenter {
void start();
}
public interface BaseView<T> {
void setPresenter(T presenter);
}
剩下的四个类中,UseCase(包含UseCaseCallback接口)和UseCaseHandler是直接提供给开发者使用的类。UseCase、UseCaseCallback相当于一个任务和一个任务的回调,而UseCaseHandler起到一个分发处理任务的入口,它实际代理了UseCaseScheduler类,最终任务的执行还是交由UseCaseScheduler的实现类UseCaseThreadPoolScheduler。
来看一下执行任务相关类的类图:
主要由UseCaseHandler作为一个代理类,将任务UseCase交给UseCaseScheduler处理,UseCase自身任务执行完成后,通过持有的UiCallbackWrapper对象通知到UseCaseHandler,再由UseCaseHandler通知真正的处理者UseCaseScheduler执行回调。
(其中UiCallbackWrapper只是UseCaseCallback的一个简单实现,持有回调对象和UseCaseHandler对象,理解过程中可以忽略)
UseCase打头的四个类定义处理具体逻辑任务的框架,承担M层的作用。
再看具体页面的MVP应用:
其中
TaskDetailFragment作为V的职责
TaskDetailPresenter承担P的工作
TaskDetailContract是对于TaskDetailFragment、TaskDetailPresent的方法的一个统一定义接口
TaskDetailActivity是创建和连接V、P的总控制器
这里其实TaskDetailFragment可以算多余的,让TaskDetailActivity来直接承担V的工作也是可以的。但多出一个Fragment会显得更加灵活,在多设备的适配上也更方面。举个例子,在实际项目开发中,我遇到一个界面的布局与逻辑,我会有意识的去分拆成几块地方,分别用Fragment来实现,Activity的作用只是把几个Fragment按顺序添加进来,然后碰到产品经理设计师对界面重新布局与逻辑块的删除或重排序或新增页面需复用部分块时,,我仅需要对Fragment单个整体来操作即可,,轻松快速的完成了产品不可控的需求变更。(也是被产品随意变更需求和设计师页面的变动逼的木有办法想到的法子···)
TaskDetailFragment与TaskDetailPresenter分别实现TaskDetailContract中预先定义的方法,,TaskDetailFragment中仅实现与UI有关的工作,其它非UI逻辑操作均放置于TaskDetailPresenter中。因为V、P之间是互相持有对象的,所以逻辑处理完成通知UI层,UI层又能触发逻辑层的方法执行。
贴一下其中一个事件的触发执行的闭环代码:
//V层触发
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_delete:
mPresenter.deleteTask();
return true;
}
return false;
}
//P层开始处理
@Override
public void deleteTask() {
mUseCaseHandler.execute(mDeleteTask, new DeleteTask.RequestValues(mTaskId),
new UseCase.UseCaseCallback<DeleteTask.ResponseValue>() {
@Override
public void onSuccess(DeleteTask.ResponseValue response) {
//回调到V层
mTaskDetailView.showTaskDeleted();
}
@Override
public void onError() {
// Show error, log, etc.
}
});
//V层回调显示UI变动,这里直接是退出了页面
@Override
public void showTaskDeleted() {
getActivity().finish();
}
整体来说,todomvp的结构是很清晰简洁的,MVP方面的运用相差无几,其中靓点在于V、P方法的统一预定义,与Activity的弱化、Fragment承担V的职责。