MVC MVP MVVM
MVC
视图层(View)对应 xml 布局文件和 java 代码动态 View 部分。
控制层(Controller)MVC 中 Android 的控制层是由 Activity 来承担,Activity 本来主要是作为初始化页面,展示数据的操作,但是因为 XML 视图功能太弱,所以 Activity 既要负责视图的显示,又要加入控制逻辑,承担的功能过多。
模型层(Model)针对业务模型,建立的数据结构和相关的类,它主要负责网络请求,数据库处理,I/O 的数据。
由于 Android 中有个 God Object 的存在,Activity 再加上 Android 中 XML 布局的功能性太弱,所以 Activity 承担了绝大部分的工作。所以在 Android 中 MVC 更像是这种形式:
因为 Activity 扮演了 Controller 和 View 的工作,所以 Controller 和 View 不太好彻底解耦,但在一定程度上还是可以解耦的。Activity 充当了 View 和 Controller,我们仍要区分到底哪一部分是 View 的操作,哪一部分是 Controller 的操作。事件的流向:View -> Controller 获取用户信息事件的触发:Controller -> Model 绑定用户信息到 View:Controller -> View
总结
- 具有一定的分层,model 彻底解耦,controller 和 view 并没有解耦
- 层与层之间的交互尽量使用回调或者去使用消息机制去完成,尽量避免直接持有
- controller 和 view 在 Android 中无法做到彻底分离,但在代码逻辑层面一定要分清
- 业务逻辑被放置在 model 层,能够更好的复用和修改增加业务
MVP
1 | public interface BasePresenter{ |
BasePresenter 类似于 MVC 中 BaseModel,主要负责业务逻辑的实现。Google 的 MVP 实现方案是把业务逻辑放在 presenter 中,弱化 Model。
1 | public interface BaseView<P extends BasePresenter>{ |
BaseView 是所有 View 的父类,将 Android 中的 View 抽象出来,只有跟 View 相关的操作都由 BaseView 的实现类去完成。
1 | public class SampleContract{ |
Contract 契约类这是 Google MVP 与其他实现方式的又一个不同,契约类用于定义同一个界面的 View 的接口和 Presenter 的具体实现。好处是通过规范的方法命名和注释可以清晰的看到整个页面的逻辑。
1 | public class SampleActivity extends Activity implements SampleContract.View{ |
这里的 SampleActivity 实现了 SampleContract.View 只是作为 View 存在的。虽然看起来,跟 MVC 中的实现很类似,但却有本质的区别。mPresenter 为 Model 和 View 之间交互的桥梁。Presenter 跟 View 相互持有,这里 SampleActivity 实现了 SampleContract.View,mPresenter 作为 SampleActivity 的成员变量, SampleActivity 当然持有 mPresenter,由于 mPresenter 是非静态的成员变量,因此默认持有 SampleActivity 的引用。
总结
通过引入接口 BaseView,让相应的视图组件如 Activity,Fragment 去实现 BaseView,实现了视图层的独立,通过中间件 Presenter 实现了 Model 和 View 的完全解耦。MVP 彻底解决了 MVC 中 View 和 Controller 过分交织的问题。但是随着业务逻辑的增加,一个页面可能会非常复杂,UI 的改变是非常多,会有非常多的 case,这样就会造成 View 的接口会很庞大。
MVVM
MVP 中随着业务逻辑的增加,UI 的改变多的情况下,会有非常多的跟 UI 相关的 case,这样就会造成 View 的接口会很庞大。而 MVVM 就解决了这个问题,通过双向绑定的机制,实现数据和 UI 内容,只要想改其中一方,另一方都能够及时更新的一种设计理念,这样就省去了很多在 View 层中写很多 case 的情况,只需要改变数据就行。
一般情况下就这两种情况,这看起来跟 MVP 好像没啥差别,其实区别还是挺大的。在 MVP 中 View 和 Presenter 要相互持有,方便调用对方;而在 MVVM 中 View 和 Model 通过 Binding 进行关联,他们之前的关系处理通过 DataBinding 完成。
MVVM 是一种思想,DataBinding 是谷歌推出的方便实现 MVVM 的工具
总结
看起来 MVVM 很好地解决了 MVC 和 MVP 的不足,但是由于数据和视图的双向绑定,导致出现问题时不太好定位来源,有可能数据问题导致,也有可能业务逻辑中对视图属性的修改导致。如果项目中打算用 MVVM 的话可以考虑使用官方的架构组件 ViewModel、LiveData、DataBinding 去实现 MVVM
如何选择
- 项目简单,没有什么复杂性,未来改动也不大的话,那就不要用设计模式或者架构方法,只需要将每个模块封装好,方便调用即可,不要为了使用设计模式或架构方法而使用。
- 对于偏向展示型 App,绝大多数业务逻辑都在后端,App 主要功能就是展示数据、交互等,建议使用 MVVM。
- 对于工具类或者需要写很多业务逻辑 app,使用 MVP 或者 MVVM 都可。
- 如果想通过一个项目去学习架构和设计模式,建议使用 MVC 然后在此基础上慢慢挖掘改进。最后你可能发现,改进的最终结果可能就变成了 MVP,MVVM。