仅需6步,教你轻易撕掉app开发框架的神秘面纱(2):MVP比MVC更好吗

9 篇文章 0 订阅
6 篇文章 0 订阅

对于程序框架的选择,由于android天然的MVC,本来不需要另外设计直接使用即可。但是我更加钟情于MVP模式,对于其将ui完全与业务逻辑分离的思路很赞同。

那么什么是业务逻辑?个人认为,对数据(即MVC中的M)的处理即为业务逻辑,数据主要有3个来源:

  • 服务端返回的数据
  • 从其它途径传入的数据
  • 自己定义的数据(需要传递时)。

实际操作中,指不定哪天老板说,啊这个页面颜色太淡了,这个页面按钮太多了,另一个页面文字换成图片。

怎么办?美术负责人说,我做两个版本吧,先上线测试,看看哪个效果好就用哪个。

你该怎么做?

  • 反驳老板,说他是错的,然后第二天你就可以去找一份新工作了。本文到此结束。
  • 不反驳老板,往下看。

既然选择忍辱负重,那么就要努力想解决方案。

如果使用MVC模式,你需要复制你的Activity,建立新的文件 Activity2,然后删除页面相关代码,添加新的页面代码。

这样做可以完成任务,但是有2方面的问题:

  • 修改页面时,其中混杂的业务逻辑就会从中作梗,因为某些业务逻辑会跟view操作写在同一个函数中。因此在修改view的时候,很容易就修改/删除了某些业务逻辑相关代码。这样,等你写完了之后恐怕连你自己都没法保证没有写错。后续就是大量的测试和代码对比。如果明天老板就要验收,或者让你改第三次怎么办?
  • 业务逻辑冗余,你会发现两个activity中有着大量相同的代码。一旦某个业务逻辑需要改变,比如接口名称变化,你需要修改两个地方。

这时候你可能会想,我把业务逻辑封装成一个个函数,给这些函数添加适当的参数和返回值,然后提取到另一个类中,比如就叫做ActivityDataHandler。来表示Activity业务逻辑的处理。

这样问题不就解决了吗!

  • 首先业务逻辑不会跟页面混杂,只要看到ActivityDataHandler的实例就知道是业务逻辑了。
  • 其次不会有2处业务逻辑了。因为都封装到ActivityDataHandler中了。

但是问题又来了,如果说对数据的修改仅仅是来自页面操作,上面这样做是可以解决问题的。

如果数据的修改不是通过页面操作进行的呢?比如某个接口调用之后,数据理应传给ActivityDataHandler,而不是Activity。

Activity怎么才能知道数据回来了,进而刷新页面?

这时候你明白了,需要在ActivityDataHandler中添加一个引用,指向Activity,这样每次ActivityDataHandler中的数据变化都可以直接调用activity中的方法了。

嗯不错,问题似乎解决了。但是你还是忽略了一个问题,那就是Activity不止一个。

在这种情况下你需要在ActivityDataHandler中添加多个Activity的引用,然后在数据变化时,用if-else来判断调用不同activity的不同方法。

这样上面的问题是解决了,但是又引入了新的问题。ActivityDataHandler中添加多个Activity的引用,这本身就是一个冗余,从设计模式角度来讲,如果一个两个还好说,如果需要添加10000个则需要修改ActivityDataHandler10000次,这违反了设计模式中的:开闭原则。

所以这时候你会想,我把Activity中涉及因为数据的改变而需要修改页面组件的部分,封装成不同的方法,然后把这些不同的方法提取到一个接口中,IActivity。这样每次新加入一个Activity只需要继承IActivity,然后把IActivity的引用传给ActivityDataHandler即可。

这样ActivityDataHandler只需要引用一个IActivity就够了,不用关心具体是哪个activity,这体现了设计模式中的依赖倒转原则:只针对接口来编程。
嗯,这时候你舒了一口气,说,这下没问题了吧!哈哈,确实,表面上看似乎没问题,很完美。

但是别高兴的太早,因为此时老板和美术人员可能不找你麻烦了。但是后端程序和产品经理又向你走来。

后端程序说,我这个接口不太稳定,因为网页端需要测试,所以可能某个页面要写2套接口,你这边最好兼容一下,我给你个参数,你用这个参数来判断调用哪套接口。。

产品经理说,这个页面跳转回来后,我不确定应该显示什么内容,到时候要具体根据统计数据来看,所以我希望,一部分用户跳转回来后显示真数据,另一部分用户则显示假数据。。

这时候你说,没问题,我在接口调用的地方加一个if-else来判断调哪个接口。然后,在页面跳转后数据修改这里也加一个if-else,判断这个用户类型,然后给返回不同的数据。

然后你犹豫了一下,觉得似乎哪里不对劲。回头看了看上面Activity修改时所遇到的问题,于是明白了问题所在:违反开闭原则。

找到问题就简单了,解决方法同上面解决多个Activity引用的方法一致:建立IActivityDataHandler,为不同的逻辑添加多个ActivityDataHandler。然后Activity中添加IActivityDataHandler引用。

问题至此完美解决。

Activity,IActivity,ActivityDataHandler,IActivityDataHandler。这四个类及上述分析,就构成了MVP模式。

如此看来,MVP确实是个不错的框架,解决了不少问题,但是在我看来,它实践起来还是有一定的困难的。

MVP其实就是把MVC中的C再次拆分为V和P的一个框架。

主要问题有3个:

  1. 做功能的程序员每写一个activity需要写多个文件一个Activity,一个Presenter,一个IActivity的接口,一个IPresenter的接口,麻烦,对于一个快速迭代的项目(已知不会有太多的变化和修改)来说不是很轻便。而且文件一多,有些思维不连贯的程序员就会混乱。
  2. Activity和Presenter任务不明确,有时需要2个类同时处理的某些操作,会令程序员造成迷惑。
  3. Activity和Presenter相互引用,耦合很重。其实这一点是难以避免的。

后续会介绍我是如何搭建具有个人特色的MVP模式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值