链接:https://www.zhihu.com/question/45517397/answer/99293671
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
MVP 架构
MVC的C是即持有具体Model,又持有具体View,所以C很臃肿,分层架构就算抽出了DataManager,实质上仍然是一个MVC架构,而MVP和MVVM则是C持有具体View这个问题做了点文章,其中MVP就是将大量的View <-> Model 交互剥离出来交由Presenter,Presenter持有抽象的View。
在去年写这个回答的时候,我曾经写过这么一段:
看上去很美好,但是网上很多博客的那种Demo写法我在尝试应用中发现并不实用,就是抽象出很多View接口,然后建立Presenter类来作为Presenter,这样做写些简单的列表获取,登录之类看起来很漂亮,好像做到了代码分离,但是业务场景一复杂就有点蛋疼
那个时候我还仅仅只是尝试,不实用是一个很感性的认识,也没有多说,那时候是在做一个商城应用,使用MVP编写诸如购物车之类复杂场景的时候遇到了很大的困难,以至于让我怀疑我是不是在用MVP给自己找麻烦,写登录这些还好,写到购物车的时候我就开始怀疑人生了。
一个ICartView,我要写多少接口?购物车查删改、优惠券满减查、凑单、价格计算、运费……二十个接口少不了吧?那么这个抽象的View除了给CartActivity用,还有其它什么卵用吗?
假如我写成ICartView,IBonusView,IXXXView……可是有的界面并不需要删改购物车列表啊,难道我还要再细分?然后让Activity实现一堆接口?搞成这个样子,假如哪天需求变了怎么办……
Presenter听起来很吊,主导者啊,但是没有Activity和Fragment的资源啊,我要怎么才能让它主导?需要获取系统的一些信息(需要Context)的时候怎么办?不持有Context难道再开接口吗?
写这么多接口,接口实现,Presenter,多写了几百行代码n个类,就为了把1~200行代码从Activity移出去?
还是放弃吧……
后来Google出了TODO-MVP,但是发现跟上面那种Demo写法一样很麻烦,我也没有实际运用。后来反编译了某个大型App,发现其正好是MVP架构,于是仔细看了一下代码,就如同我最开始的想法,一个IXXXView有多少功能就写多少接口。再看看Presenter的实现,我忽然就明白我为什么会感觉不实用了:
任何想要构建一个其他什么东西取代Activity/Fragment地位的尝试都是自找麻烦
MVP正是一个典型
既然MVP把Activity/Fragment抽象为View,那么就意味着当它作为一个抽象View去使用的时候,生命周期,Context这些极其重要的资源Presenter是看不到的,但是这些东西是不可能不使用的。为了能让Presenter使用到这些,Presenter就必须持有Context,绑定Activity、Fragment的生命周期,就算如此,在一些需要确定使用Activity、Fragment的场合,仍需要使用强制转型。
正因为Presenter这个“主导”,导致Presenter和Activity/Fragment高度绑定,Presenter和IXXXView,没有什么复用性。