• 结合实际业务场景聊一聊MVP模式的应用


    MVP模式出来不是一天两天了,不过最近开始比较热(当然也可能是我最近才发现……)。

    考虑到部分公司和团队还在使用Eclipse开发兼容Android2.2的应用,需要AndroidStudio1.3才支持的MVVM模式自然是不太适用,因此还是采用兼容度比较高的MVP模式比较适合。

    MVP的基础知识不必多说,Model模型访问数据,View视图显示数据,Presenter表示器负责连接两者,前人已经有过不少好文章了,随手丢几个:

    对MVC、MVP、MVVM的理解Android中的MVPIntroduction to Model View Presenter on Android

    但是大部分文章的问题在于例子过于基础,基本上都是简单的输入输出保存读取,理解基本概念是够了,看完觉得哇塞这个好屌我要用到我的项目里,但是一敲代码你就抓瞎了。

    比如信息访问的例子,用户输入数据,点击按钮,View层捕获事件,调用Presenter执行保存逻辑,通过Model建立Domain,固化数据到数据库。

    但是看完了你一琢磨。

    嗯?这跟MVC有区别吗?

    然而并没有什(

    于是我们来讨论几个问题。

    1. 谁来做异步?

    某篇讲解MVP的文章下有人问了,『我的Model层是异步访问网络的,(并不能马上返回数据,)那样Presenter要怎么更新View呢?难道用回调接口的方式吗?』

    看到的时候我还真思考了一下。

    首先代入传统的思考方式,在编写上帝Activity类的时候我们是怎么做异步的?线程在哪里start,AsyncTask在哪里execute?

    直接在事件逻辑里执行异步好像是比较常规比较蠢的办法,线程执行完毕通过Handler之类的线程间通讯传递执行结果,AsyncTask则在onPostExecute里直接在主线程处理。

    多说一句,AsyncTask写起来真丑啊……

    如果要做得比较高端则可以用上第三方框架,比如Volley,各种ImageLoader等等,这类框架要么是通过监听器返回结果,要么是通过主线程的回调函数返回结果,要么像ImageLoader一样,干脆把返回结果的过程给封装住。

    那么话说回来,你告诉我,

    谁TM干不TM行啊!(╯°Д°)╯( ┻━┻

    ┬—┬ ノ( ' - 'ノ)只要不让View来做

    让谁TM干不TM一样啊!(╯°Д°)╯( ┻━┻

    2. 弹Dialog/Toast/PopupWindow到底是UI操作还是后台逻辑?

    首先把思路从UI线程和后台线程的区别里抽离出来,这个和问题是两回事。

    这些东西由UI来显示,看似应该放在View层,但是创建的过程又仿佛是业务逻辑,放在View层显得啰嗦,似乎应该放到Presenter层。

    细化到创建的过程,以Dialog为例,好像设置内容的部分属于UI,处理内容操作和监听事件属于后台逻辑。

    那把创建放到View层,处理内部View的逻辑和监听到按钮事件的时候再调用Presenter中的接口?似乎传递来传递去又太麻烦。

    还是根据实际业务场景来决定吧。

    对于操作简单的对话框,比如退出确认,就在View里创建并显示,事件交由Presenter来处理。

    对于比较麻烦的,比如内部显示了一个复杂的视图,子View之间还会互相联动,比如拖动进度条改变文字显示之类的,能在View层直接处理就不要往Presenter里再多跳一次。如果逻辑复杂,不如干脆把创建放到Presenter里,只通过View接口来做显示算了。

    3. 上下文怎么搞?

    首先明确一条原则:理想化的Presenter是纯Java实现的。

    当然实际情况下尽可以灵活一点,不必要这么轴。

    这条原则描述的是MVP模式的优越性之一,即是业务逻辑可以脱机进行单元测试。

    通过单独实现了View接口和Model接口的测试用例,可以在不依赖Android环境的情况下对Presenter进行测试。

    但是,也不可能把所有Android代码都扔到View和Model里去,比如startActivity操作属于Activity类,一些API的调用还需要Context实例。

    尽管我们知道View层无非也就是Activity、Fragment和View这几个类的各种实现,而且它们理论上都能拿到上下文,但是就因为这样就把这些需要上下文的操作丢还给View层来执行吗?

    我觉得大可不必。

    只要能避免Presenter长时间持有上下文导致出现内存泄露的可能性,该交给后台的还是由后台来做。

    我的做法是在View层接口里加入上下文的访问函数,Presenter只在需要的时候作为临时变量调用,内部不保存。

    使用全局ApplicationContext也是一个办法,至于用这个实例到底好不好暂且按下不表。

    …………那……

    4. Adapter算前台还是后台?

    Adapter需要访问数据,需要执行业务逻辑,需要将数据绑定到视图。

    Adapter在MVP模式里站那个位置?

    如果要绑定Presenter的话应该绑在Adapter上还是getView方法里初始化的那个View对象上?

    是不是觉得这种情况有点似曾相识?

    这是不是毅种循环?

    ActivityAdapter是不是Controller?』

    『那个……』

    『你有没有见过超过五千行的ActivityAdapter?』

    『…………呃……』

  • 相关阅读:
    有return的情况下try catch finally的执行顺序
    java面试题
    JSTL常用标签
    文件引入路径设置
    JavaScript配合button.onclick()使用总结
    Java NIO vs IO
    如何在Oracle官网下载历史版本JDK
    常量池之String.intern()方法
    MyeclipseJRE版本设置
    JVM常用参数配置
  • 原文地址:https://www.cnblogs.com/chihane/p/4788477.html
Copyright © 2020-2023  润新知