结合实际业务场景聊一聊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?』

『…………呃……』

posted @ 2015-09-07 15:12  Chihane  阅读(1210)  评论(2编辑  收藏  举报