Android中的MVC _ MVP模式

简述MVC / MVP模式


MVC

  • Model(实体层):适合做一些业务逻辑处理,比如数据库存取操作,网络操作,复杂的算法,耗时的任务等都在model层处理-----业务逻辑和实体类JavaBean……
  • View(视图层):应用层中处理数据显示的部分,XML布局可以视为V层,显示Model层的数据结果-----布局文件
  • Controller(控制层):Controller控制器用于更新UI界面和数据实例,Model层和View层的交互-----Activity(具有很大耦合性)

MVC

例如:View层接受用户的输入,然后通过Controller修改对应的Model实例;同时,当Model实例的数据发生变化的时候,需要修改UI界面,可以通过Controller更新界面。(View也可以对Model进行简单的数据修改)。

在Android的UI系统中,控制器Activity主要起的作用是解耦,将视图View和Model分离,两者在Activity中进行绑定或者其他的逻辑。Android的本身开发就已经用到将视图与数据模型分开的思想。


  • “高内聚低耦合”
  • 某些模块必然要关联起来才能工作,这是由业务逻辑决定的,不能否认。所以解耦并不是字面意义上的把关联拆掉,而是把模块之间的关联放松到必要的程度。
  • 模块只对外暴露最小限度的接口,形成最低的依赖关系(比如持有另一个对象的引用)。

MVP

  • MVP模式是MVC模式在Android上的一种变体。
  • 让Controller和View解耦。在MVC模式中,Activity应该是属于View这一层用于展示UI,以及接受用户的输入,此外还要承担生命周期的工作,而实质上,它既承担了View,同时也包含一些Controller的东西在里面。如果将所有UI和事件逻辑都写在里面会造成Activity太臃肿,开发与维护来说不太友好,耦合度很高了。
  • 把Activity的View和Controller抽离出来就变成了View和Presenter,之间通过接口来通信,这就是MVP模式。Presenter是Model和View之间的桥梁,为了让结构变得更加简单,View并不能直接对Model进行操作;
  • MVC和MVP之间最大区别就是MVC是允许Model和View交互的,而MVP是不允许的。
    Google的MVP

  • Model:业务逻辑与实体类,主要提供数据获取、存、取、网络访问(提供回调在Presenter中处理)等耗时工作功能。
  • View(Activity):对应于Activity,负责生命周期、View的初始化绘制以及与用户交互,Activity加载时自身new一个Presenter的实例,将Activity自身作为参数传过去(View与Presenter建立关联),使得Presenter中可以直接调用其方法对View进行操作,Activity可以直接用Presenter中的方法进行事件逻辑处理。
  • Presenter:负责完成View和Model之间的交互,通常有一个业务逻辑实体类的实例,一个View的接口引用。

保证View里面有Presenter的实例,Presenter有View的实例,Model的实例。


  • 内容:
  • Model(class):通常用接口进行规范,实体类实现这个接口及其中的方法,也可以持有Presenter的引用实现回调;
  • View(interface):对view之上操作的规范,相应Activity/fragment实现这个接口及其中的逻辑方法,规范在Contract之中;
  • Presenter(class):通常自身有一个业务逻辑类的实例(建立Presenter与Model之间的关系),并持有view的引用;

  • 为了更加规范增加一个Contract将View和Presenter规范在一起

MVP

  • 核心思想:把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成Presenter接口,Model类还是原来的Model。这样Activity就只负责响应生命周期,其他工作都丢到Presenter中完成。

来自《android源码设计模式》

使用此模式的好处:

  • 分离了视图逻辑和业务逻辑,降低了耦合
  • Activity只处理生命周期和少量事件逻辑,代码变得更加简洁,提高代码的可阅读性(主要读Presenter和各个规范接口中的代码)
  • Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试
  • 把业务逻辑抽到Model中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露,避免造成类似于Handel消息异步处理时的内存泄漏问题。

  • 注意事项
  • Activity/fragment中持有Presenter的引用,Presenter中持有Activity/fragment的引用,相互持有引用,相互持有引用也在一定程度上增加了耦合度,为了减少耦合,取消Presenter对Activity/Fragment的引用。解决方法:在Presenter类里声明一个方法, 重置接口引用为空; 在Activity/Fragment的onDestroy里调用Presenter的重置方法。
  • 网络请求应该放在Model的线程中异步进行,Model提供回调接口,结果在presenter中处理。
  • 假如快速打开并关闭Activity/Fragment,这时还有很多网络接口正在执行或在队列里的请求,费流量,在回调里刷界面会导致崩溃。解决方法:在Activity/Fragment的onDestroy函数里取消所有该界面发出的网络接口,每个Request都可以用tag区分, 在取消请求时通过这个tag找到对应的实例。
  • 编码规范接口命名前面加“I”,接口中的方法加注释,包的分类规范。

java接口回调

  • “你调用我,我反过来调用你”
  • 简单的例子:你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。回答完毕。
  • 回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指函数或者函数指针(应用接口)通过函数参数传递到其它函数中当这个函数调用结束之后回过来调用这个传过来的函数。这一设计允许了底层代码调用在高层定义的子程序。例如:android中的点击事件。
  • 在缺少函数类型的参数的面向对象的程序语言中,例如Java,回调可以用传递抽象类或接口来模拟。**回调的接收者会调用抽象类或接口的方法,这些方法由调用者提供实现。**这样的对象通常是一些回调函数的集合,同时可能包含它所需要的数据。这种方法在实现某些设计模式时比较有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值