简单理解MVP

仅作个人记录


以前用过MVP,发现他的接口太多了,并且基类要封装很多东西,就弃用了

所有就正常开发,在一个Activity里写逻辑,尽量简化、拆分

但是项目大了以后,改动起来是真的麻烦了

所以拆分了UI和数据,纯写一个类封装View,提供刷新UI的API,以及扔接口去处理数据

但是渐渐发现操作数据的时候,UI对数据层是不透明的,需要调用UI的API,操作UI的时候倒还好,直接扔动作接口就好了

最近阅读了某项目,才发现P层不是我过去理解的转发层,而是组织层

他协调了UI的API和数据的使用的先后次序

这样才可以实现,写UI的时候真正写UI,写数据的时候专门写数据

当然仅仅一个裸MVP是不够的,需要进行大量的封装以及冗余的接口声明

封装是必要的,你需要同步生命周期及使用许多API,但是接口就最好可以用EventBus+tag取代掉,这个是我最新的思路,我觉得这样很好,我未来会在自己项目中使用上这种变种的MVP


总结一下

M 数据处理的api

V view

P 组织者

所以个人认为在P层里写数据处理是不对的

一般是在V层写UI,也有更新UI的api,写不下去了扔接口给P,P帮你到M层找数据处理api,没找到就写需要的api


再对MVP理解深一点——初始化(处理点击回调、网络回调很简单,但是如何优雅处理初始化呢?)

在一个项目中看到

在初始化一个页面的时候,Title的值需要计算得出,项目代码的做法是present.setTitleData,计算好了后,调用view.setTitleData。

我个人觉得是不太好的,我是UI,我何必关注P层具有怎样的方法呢?

我有两种想法

1.MVVM,现在我终于明白了为什么要有这个框架了。我们用了Databing,就可以免去了view.setTitleData的回调操作了。那么present.setTitleData呢?P层是组织者,所以initTitleData应该从P层的构造方法里发起,然后需要一些api的话,到M层去取,由于这里用了Databing,甚至不需要回调了。这就是我对原项目代码的优化

2.在V层,直接getTitleData,然后进行设置。这个getTitleData又谁来实现呢?其实在分析了第一种方法之后我感觉我原来的做法是错的,事件流不该从V层开始,而是应该从P层组织者层开始。我之前的做法、想法都是错的。不应该是V层碰到数据做不下去了就扔接口出来,而是P层决定是更新UI还是调用数据接口。


分析下点击按钮登录的场景

事件流从click listener开始。然后this.showloadingDialog。然后我就陷入了纠结,是该叫p.sendRequest还是p.onClickLogin呢???p.onClickLogin对于V层很友好,V层不必关注我点了这个按钮到底该做啥数据处理的操作,但是我在clickLogin后还进行了this.showloadingDialog的操作,显然接下来再用onClickLogin不能包含on click login的全部含义了;选择前者就意味着V层是知道接下来要进行网路请求的,不透明了。后来我真的是灵机一动(真的得赞叹一下我的智商,真的太高了),苦恼了一会后,我想到了,我上面的P层托管了init,是为了剥夺原来我给予V层的事件流。现在OnClickListener无疑是使得事件流重新给了V层,我也需要剥夺他!所以我在V层,btLogin.setOnClickListener(p::onClickLogin());就成功剥夺了。我在p.onClickListener方法中,执行v.showloadingdialog,然后m.sendRequest(ps:m中也是简单地封装一下,由于接口隔离原则的充分贯彻,m 中的sendRequest代码无疑是这样的:NetworkManager.sendRequest(request)。堪称完美!


总结一下:

P层剥夺V层所有事件。初始化,虽然他本不属于V层事件,但是正常人包括我之前一直认为的如此,setTitleData的那份源码里 也是这样的思维。点击事件,这个完全就是V层的事件,强行获取。还有一些事件的剥夺,暂时没碰到,想不起来。那么理所应当,V、M层都成了API库,V提供更新UI的API,M提供数据处理的API,P层中有初始化事件流,click事件流,他是组织者,可以决定何时调用V层的API去更新UI,何时调用P层的API去处理数据。从此以后开发就变得极度简单了。这才是对MVP的真正理解,只有引入事件流这个概念才能彻底拆分了数据、UI。我感觉我看到的许多的MVP、MVVM框架在项目中使用的源码,都是错误的。不久后我会用事件流MVP+EventBus打造一套光速开发模式,让开发和维护简单万倍!!!


最后再次推翻一下

在看某项目的动画监听的时候,想到能不能和click一样,也让P层实现动画监听接口的方法。这样一来突然感觉P层美名其曰组织者,可是还是把UI和数据放在一起写了,只不过都经过UI和数据的封装了。不过一想也无可避免,因为业务逻辑本身就是这样处理的,交互的顺序无可避免。

回头看一下扔接口形式的MVP,请求title那就presenter.getTitleData这个倒么什么问题,click login先showDialog再present.login,再在onLoginSuccess里dismissDialog以及更新其他的UI。这里有个问题,是扔个onLoginSuccess的接口给P,还是等P的onLoginSuccess方法里调用V的更新UI的逻辑。我觉得onLoginSuccess方法由p层控制绝对是不好的,因为事件流从V层转换到了P层,应该在V层声明一个onLoginSuccess方法,在网络请求成功后,p.onLoginSuccess立刻调用v.onLoginSuccess把事件流直接托管给V层,然后onLoginSuccess后肯定还有一些业务逻辑,再由v扔接口出来就行了。

总而言之事件流在V层和事件流在P层,这两者我犹豫不决,可能还需要实战中去比较。


最近看了鸿洋的MVP文章,又多领悟了一点

P是专门为你处理复杂逻辑的,一万行的复杂逻辑,就V层就是一个接口,V层可以通过一句话就可以实现所有的功能,宛如上帝模式一样。M层是P层的API、工具类库,也可以认为是配合者,配合处理复杂逻辑。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值