MVC模式、MVP模式、MVVM模式

1,217 阅读4分钟

MVC模式

Model-View-Controller

  • model(模型):用来封装与应用程序相关的数据或处理数据的方法。model对数据有直接访问权,它不关心自己会被如何调用。那些监视此modelview必须先在此model注册。

  • view(视图):用户看到的视图。一般不会包含业务逻辑代码,为了实现view的刷新功能,必须先在监视的model上注册。

  • controller(控制器):起到不同层面的组织作用,用于控制应用程序的流程。它处理事件,并作出响应。"事件"包括用户行为和model上的数据改变。

流程详解

1、首先用户操作view,会捕获到这个操作,并将控制权交给controller

2、controller中进行业务逻辑操作,可能会改变model中的数据。

3、model中的数据发生改变,就会通过观察者模式通知view

4、view通过观察者模式收到model数据变更的通知后,会向model请求新的数据,然后渲染页面。

注意

  • view只会把控制权交给controller,并不会执行业务逻辑代码。

  • controller只会执行业务逻辑代码并操作mdoel,不会改变直接改变view

  • viewmodel的同步是通过观察者模式进行的,而同步操作是view自己请求model中的数据,然后更新视图。

优缺点

  • 优点:实现了功能模块和显示模块的代码分离。同时还提高了系统的可维护性、可扩展性和可复用性。

  • 缺点:简单的小型项目,使用MVC反而会降低开发效率。层与层虽然分离了,但是关联性太强了,没有做到独立的重用。

MVP模式

Model-View-Presenter

MVP由MVC演化而来,通过表示器(presenter)将视图和模型巧妙的分离开来。

  • model(模型):描述了系统的处理逻辑,对于表示器和视图一无所知。

  • view(视图):一般由表示器初始化,将用户输入转发给表示器。通常一个视图对应一个表示器,但是在业务逻辑复杂的情况下会对应多个。

  • presenter(表示器):表示器包含了大多数表示逻辑,用以处理视图。与模型交互以获取或更新数据。

流程详解

1、用户操作view,将控制权交给presenter

2、presenter执行业务逻辑,并更新model

3、model将自身的更新通过观察者模式通知presenter而不是view

4、persenter获取到model变更的通知后,通过view提供的接口,更新view

注意

  • view不再负责同步逻辑,而是由present负责,persent既有业务逻辑也有同步逻辑。这和MVC中的view同步逻辑不同,在MVC中是view直接使用model
  • view需要提供操作用户界面的接口给present调用(非常关键)

优缺点

优点:实现了model和view的真正完全分离,使模块职责划分明显。增加了程序可复用性(presenter可以复用)。隐藏了数据,提高了安全性。更加有利于单元测试。

缺点:增加了代码的复杂度,特别是对于小型程序,会使代码冗余。presenter中含有大量手动同步逻辑,会使得presenter很臃肿,难以维护。presenter如果与视图的交互过于频繁,那么就会使双方的联系过于紧密。不如预期那样降低耦合度和可复用性。

MVVM模式

Model-View-ViewModel

MVP模式的升级版本,将P换成了VM即ViewModel。MVVM有助于将用户界面的开发与业务逻辑或数据模型的开发分离开来。

ViewModel

"model for view",视图的模型。view需要什么数据,ViewModel就要提供什么数据。view有什么操作,ViewModel就要响应这个操作。

由于双向数据绑定,ViewModel发生改变,model也会更新。model发生改变,ViewModel也会更新。

调用关系

1、和MVP中的调用关系相同,ViewModel中有一个Binder。在MVP中,modelview的同步是通过presenter,而MVVMBinder

2、在view的模板语法中,通过指令声明视图中的内容与model中的哪一块数据绑定。

3、ViewModel更新model时,binder就会自动地更新view

4、用户操作viewbinder就会自动地更新model

也就是说MVVMmodelview的同步逻辑自动化了。以前交由presenter手动地进行modelview的同步,现在交给框架里提供的binder了。只需要在view的模板语法里声明内容对用model的哪一块数据。

优缺点

优点:双向数据绑定,开发者可以不用再关心如何去操作视图,而是改变model里的数据就可以了。分离了视图和模型,降低耦合度。

缺点:bug难以被调试,因为双向绑定,不知道是view层有问题还是model层代码有问题。数据绑定使得一个位置的bug被传到另一个位置,定位原始问题就不那么容易了。