1). 软件工程中的一种软件架构, 全称为"Mode–View–Controller", 即为"模型–视图–控制器"
2). MVC将交互式的应用程序分为3个组件:
缺点:存在问题是Controller层和View层的划分不明显,Model层和View层的存在耦合。
M模型层:
com.mvc.bean: 实体类包
com.mvc.utils: 工具包(简单的业务逻辑处理)
com.mvc.dao: 数据库操作
com.mvc.net: 网络请求
V视图层:
res下的layout, drawable, values等
自定义View类等
C控制层:
Activity
其它应用组件等
1). 如果不用View层(布局)?
问题: 每个Activity都需要创建整个布局视图对象, 一个是代码量更大,
另一个不易实现复用(布局是可以轻松实现复用的), 还有就是修改更麻烦
2). 如果不用Mode层(实体Mode)?
问题: 当应用一个界面需要展示或处理很多数据时, 对应的实体类是必不可少的
3). 如果不用Mode层(非实体Mode)?
问题: 那需要将所有的逻辑处理的代码都写到Activity中, 一个使Activity变得太臃肿,
另一个无法复用业务逻辑功能代码
是MVC进一步演化出来的,由Microsoft的Martin Fowler提出。
这个模式被普遍的引用于ASP.NET Web Forms 应用程序。并且也应用于windows form。
Model层和View层之间不能有交互,要通过Presenter层进行交互,其中View层和Presenter层是通过接口进行交互,可以定义Contract(契约)接口来指定View层和Presenter之间的契约
M、V、P之间双向通信。
View 与 Model 不通信,都通过 Presenter 传递。Presenter完全把Model和View进行了分离,主要的程序逻辑在Presenter里实现。
View 非常薄,不部署任何业务逻辑,称为”被动视图”(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时候可以保持Presenter的不变,这样就可以重用。不仅如此,还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试–从而不需要使用自动化的测试工具。
缺点:内存泄露
在MVP模式中,内存泄漏的主要原因是由于当前View层(如Activity或者Fragment)在卸载时,Model层中仍有业务没有结束(如子线程未完成、网络请求超时等),而这里的Presenter层中拥有Mode层和View层的引用,所以Presenter层也暂时无法释放,最终导致View的引用也没有释放,我们的Activity或者Fragment就算时销毁了,GC也无法回收它们,因为还有引用在指向它们呢。
注意:
在MVP中,View层不会部署任何的业务逻辑,从而比较薄,它被称为被动视图(Passive View),意思是它没有任何的主动性,而且这样的设计也方便做单元测试,但是也会有如下问题:
上图中说明了低层的不会直接给上一层做反馈,而是通过 View 、 Callback 为上级做出了反馈,这样就解决了请求数据与更新界面的异步操作。上图中 View 和 Callback 都是以接口的形式存在的。
MVVM即Model-View-View Model。这个模式提供对View和View Model的双向数据绑定。这使得View Model的状态改变可以自动传递给View。典型的情况是,View Model通过使用obsever模式(观察者模式)来将View Model的变化通知给model。
MVVM(Model-View-ViewModel)是MVP进一步演化出来的,它也是由Microsoft的Martin Fowler提出
这个模式被广泛应用于WPF,Silverlight,Caliburn,nRoute 等。
01.Model:代表了描述业务逻辑和数据的一系列类的集合。它也定义了数据修改和操作的业务规则。
02.View:代表了UI组件,像CSS,JQuery,html等。他只负责展示从Presenter接收到的数据。也就是把模型转化成UI。
03.View Model:负责暴漏方法,命令,其他属性来操作VIew的状态,组装model作为View动作的结果,并且触发view自己的事件。
使用MVVM后,每一层的职责也更加清晰了,也方便做单元测试,同时因为View层和ViewModel层是双向绑定,开发者不需要再去主动处理部分逻辑了,减少了不少胶水代码,如果使用了一些数据绑定的库,例如在Android中的DataBinding,可以减少更加多的胶水代码。
MVP是MVC的进一步解耦,简单来讲,在MVC中,View层既可以和Controller层交互,又可以和Model层交互;而在MVP中,View层只能和Presenter层交互,Model层也只能和Presenter层交互,减少了View层和Model层的耦合,更容易定位错误的来源。
MVP中的每个方法都需要你去主动调用,它其实是被动的,而MVVM中有数据驱动这个概念,当你的持有的数据状态发生变更的时候,你的View你可以监听到这个变化,从而主动去更新,这其实是主动的。
事实上,如果你仅仅使用ViewModel,它是感知不了生命周期,它需要结合LiveData去感知生命周期,如果仅仅使用DataBinding去实现MVVM,它对数据源使用了弱引用,所以一定程度上可以避免内存泄漏的发生。
setValue 只能在主线程调用,同步更新数据
postValue 可在后台线程调用,其内部会切换到主线程调用 setValue
postValue 使用不当,可能发生接收到数据变更的通知:
If you called this method multiple times before a main thread executed a posted task, only the last value would be dispatched.
如上,源码的注释中明确记载了,当连续调用 postValue 时,有可能只会收到最后一次数据更新通知。
原因:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
mPendingData 被成功赋值 value 后,post 了一个 Runnable
mPostValueRunnable 的实现如下:
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
setValue((T) newValue);
}
};
postValue 将数据存入 mPendingData,mPostValueRunnable 在UI线程消费mPendingData。
在 Runnable 中 mPendingData 值还没有被消费之前,即使连续 postValue , 也不会 post 新的 Runnable
mPendingData 的生产 (赋值) 和消费(赋 NOT_SET) 需要加锁
这也就是当连续 postValue 时只会收到最后一次通知的原因。
浅谈 MVP in Android
如何更高效的使用MVP以及官方MVP架构解析
Android MVP架构搭建
Android简单实用的MVP框架
Android MVP模式 入门
一步一步带你认识 MVP+Retrofit+Rxjava 并封装(一)
一步一步带你认识 MVP+Retrofit+Rxjava 并封装(二)
Android架构设计–MVP模式第(二)篇,如何减少类爆炸
Android 中的 MVP 模式(带实例)
Android MVP架构的自述
优化你的代码结构 — MVP
灵活利用泛型的MVP模式T-MVP(附带一个快速创建MVP接口的Android Studio插件-TMVPHelper)
高级MVP架构封装演变全过程
Android 滑动选择控件 & MVP+Retrofit+RxJava资源推荐
Android MVP && MVVM深度解析
巧用MVVM搭建GitHub客户端
正确认识 MVC/MVP/MVVM
关于MVC/MVP/MVVM的一些错误认识
MVC、MVP、MVVM,谈谈我对Android应用架构的理解
从google todo-mvp示例再次学习MVP
MVVM,RxJava和Retrofit的一次实践
MVVM设计模式之Data Binding库的使用
Android开发之MVVM新姿势探索
分享一个我开发的MVVM架构的开源小项目
MVVMLin一个基于Jatpack+Kotlin+协程+Retrofit的快速开发框架
犹豫要不要用DataBinding?这篇文章帮你解惑
一款高仿 Eyepetizer | 开眼短视频的 MVVM 开源项目
关于 Android MVVM 一些理解与实践
Android 架构探索,MVVM 原来如此简单!
MVVM+组件化+Arouter实现
Android Kotlin+Jetpack+MVVM
Kotlin协程与JetPack组件初探
Jetpack MVVM七宗罪 之一 :还在使用 Fragment 作为 LifecycleOwner ?
爱了爱了!我理解的Android中MVVM架构模式!
MVVM中LiveData与Flow最佳实践!
彻底理解Android架构,重构Jetpack MVVM!
浅谈Android开发中的MVVM模式
MVVM 进阶版:MVI 架构了解一下
浅尝MVI
MVI 架构封装:快速优雅地实现网络请求
在两个商业App中使用MVI后,我…
项目 todo-mvp
项目MVPArms