Android MVP模式分析

MVC和MVP简单对比

MVC

MVC要加载数据时,一般来说vClass(通常是Activity)如下

    public class VClass extends Activity{

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            loadData();
        }

        private void loadData(){
            XxxBiz.loadData(new XxxCallback()){
                void onSuccess(T t){
                    // 加载完成后的动作
                }
            };
        }
    }

虽然请求数据的具体实现交由XxxBiz了,但是Activity还是申明有关请求数据的方法,也建立了XxxCallBack回调类对象。并没有做到完美的分离,再看看MVP如何做的。

MVP

MVP要加载数据时,通常是V和P协调动作。

    public class V extends Activity implements AbsV{

        private P p;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            p.loadData();
        }

        public void update(T data){
            // bind ui
        }
    }

    public class P implements AbsP{
        private V v;

        public void loadData(){
            // loading
            T data = ... ;
            v.update(data);
        }

    }

由代码可以知道,MVP加载数据时,V只需要让P去加载数据,完成后由P通知V修改UI。
这样子V中无需申明加载数据方法,无需建立加载数据回调对象,做到完全不关心加载数据的事件。
代码分离程度高,V和P只关心自己的事情。

先从了解谷歌官方推荐的几种模式。

谷歌推荐的几种模式Demo

Clean模式

Clean模式下,当Activity/Fragment销毁时,Presenter也会被销毁,在onCreate()重建时重新被创建。可以利用onSaveInstanceState()保存些信息,在重建时获取并设置,但是想要保存对后台线程的引用就很难了。

这是官方的架构图,比较前的架构,新增的这个Domain Layer,用来隔离Presentation Layer和Data Layer,减轻Presentation的负担,明显感受就是代码量的减少。新架构下,Presentation无需进行具体的操作,业务逻辑几种在Domain Layer这层,Presentation 执行调用和结果返回处理。

官方Clean架构图

  • Presentation Layer:该层囊括了 View 和 Presenter。Activity/Fragment属于VIEW层,负责展示图形界面和填充数据;Presenter就是PRESENTER层,负责Domaim Layer业务逻辑的调起和返回数据的接受,并将数据传递给VIEW层,也可以反向过来。
  • Domain Layer:负责实现app的业务逻辑,该层中由普通的Java对象组成,一般包括 UsecasesBusiness Logic
  • Data Layer:负责提供数据,这里采用了 Repository 模式。Domain 只需告诉仓库管理员需求,由仓库管理员查找并递交,Domain无需知道东西的存放位置。

Demo目录

在分析代码 之前,先进行简单的了解。

Demo目录结构

从外层看起

BasePresenter、BaseView

View和Presenter动作的抽象,是MVP模式中所有V和P需要实现的接口。

public class AddEditTaskFragment extends Fragment implements AddEditTaskContract.View
public class AddEditTaskPresenter implements AddEditTaskContract.Presenter

最为VAddEditTaskFragment 实现了BaseView,最为PAddEditTaskPresenter实现了BasePresenter。但中间多了一层接口AddEditTaskContract,再次接口申明AddEditTask任务中VP的动作方法。

UseCase

UseCase是任务的抽象,xxxTask是任务的具体实现。如DeleteTask,输入Domain层。

public class DeleteTask extends UseCase<DeleteTask.RequestValues, DeleteTask.ResponseValue>

UseCaseHandlerUseCaseSchedulerUseCaseThreadPoolScheduler可以完成一个任务的执行流程。

操作交互流程

addedittask任务模块为参考,以一个点击事件为例。

  1. VAddEditTaskFragment中的某个View触发点击事件,调用所持有的P层对象的方法。
  2. PAddEditTaskPresenter对象方法被调用,借助Domain层UseCaseHandler对象进行UseCase业务处理。
  3. UseCaseHandler:任务的执行者,项目中对 UseCase 设置taskIdcallback,并调起UseCaseScheduler.execute()
  4. UseCaseScheduler:方案调度器,实现类 UseCaseThreadPoolScheduler 。调度器执行后,会在建立的 Runnable 中执行 UseCase.run()
  5. TasksRepository:任务库。在此案例中UseCase.run() –> UseCase.executeUseCase() –> TasksRepository.getTask() 调起任务库的查询任务,参数有TaskIdCallBack
  6. TasksDataSource:任务数据源。实现类FakeTasksRemoteDataSourceTasksLocalDataSource。任务库查询TasksRepository.getTask()会调起数据源TasksDataSource.getTasks(),此方法进行数据源进行Cursor游标查询或是API请求等耗时操作。所以任务执行起点UseCase.run()不能在UI线程中执行

总结

架构的作用是:把复杂的系统变成高内聚低耦合,应付几十个人能同时协同作战时能够有序稳定,相对有节奏的开发。
但对于Android App层,2、3个能力差不多的人就能形成一个高效的整体,不存在需要应付几十个人同时协同作战的情景。
并无需过于纠结框架的优秀性,应该把重点放在敏捷开发,高效迭代上,不能为了框架而框架。

  1. 过于复杂的框架设计无法适应越来越快速的产品演进,同时增加了团队学习成本
  2. Android 本身就是 MVC 框架,开发中保持代码的简洁易懂,适度重构
  3. 合适的才是最好的,非必要无需设计复杂的框架

实际开发重点

 1. 保证App的敏捷开发、快速迭代,就是高效的开发模式了
 2. 拆解业务,对功能进行合理划分抽象,拆分library
 3. 良好的接口和模块设计,而非无尽的继承
 4. 保证代码简洁,易懂,一目了然

最后,Android 项目组件化是一个很好的方案。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值