再谈MV*(MVVM MVP MVC)模式的设计原理—封装与解耦

精炼并增补于:界面之下:还原真实的MV*模式

图形界面的应用程序提供给用户可视化的操作界面,这个界面提供给数据和信息。用户输入行为(键盘,鼠标等)会执行一些应用逻辑,应用逻辑(application logic)可能会触发一定的业务逻辑(business logic)对应用程序数据的变更,数据的变更自然需要用户界面的同步变更以提供最准确的信息。

在开发应用程序的时候,以求更好的管理应用程序的复杂性,基于职责分离(Speration of Duties)的思想都会对应用程序进行分层。在开发图形界面应用程序的时候,会把管理用户界面的层次称为View应用程序的数据为Model(注意这里的Model指的是Domain Model,这个应用程序对需要解决的问题的数据抽象,不包含应用的状态,可以简单理解为对象)。Model提供数据操作的接口,执行相应的业务逻辑。

有了View和Model的分层,那么问题就来了:View如何同步Model的变更,View和Model之间如何粘合在一起?

MV*模式解决什么问题

MV*就是实现了领域模型数据和UI层的解耦

MVC、MVP、MVVM对其解耦的思路的不同。从历史的角度来看,MVC、MVP和MVVM是一种进化的关系。但是鉴于项目的规模以及模式实现的方式不同,不同的MV*模式各有其优点和缺点,难分孰好孰坏

但是业界越来越认为:MVVM是前端领域最好的MV*模式。Angular、Vue是MVVM模式典范

MVC的依赖关系

MVC出了把应用程序分成View、Model层,还额外的加了一个Controller层,职责为进行Model和View之间的协作(路由、输入预处理等)的应用逻辑(application logic)。

  • Model主要是与业务数据有关。
  • View是应用程序数据的可视化表示。
  • Controller管理应用程序中Model和View之间的逻辑和协调。

用户对View的输入等操作并不会在View的相关模块中处理逻辑,而是由Controller层获得这些操作(所谓的Pass Call),并由Controller层对这些操作中的数据经过应用逻辑的操作,然后在调用Model层的接口,将数据交给Model层。Model层执行与业务逻辑相关的操作,并更新数据。Model和View通过观察者模式联系在一起,即View是Model的观察者,当Model数据变动之后,通知View层进行数据更新。

MVC优点

  • 把业务逻辑全部分离到Controller中,模块化程度高。当业务逻辑变更的时候,不需要变更View和Model,只需要Controller换成另外一个Controller就行了(Swappable Controller)。
  • 观察者模式可以做到多视图同时更新。

MVC缺点

  • Controller测试困难。因为视图同步操作是由View自己执行,而View只能在有UI的环境下运行。在没有UI环境下对Controller进行单元测试的时候,Controller业务逻辑的正确性是无法验证的:Controller更新Model的时候,无法对View的更新操作进行断言。
  • View无法组件化。View是强依赖特定的Model的,如果需要把这个View抽出来作为一个另外一个应用程序可复用的组件就困难了。因为不同程序的的Domain Model是不一样的

MVP模式

MVP比起MVC模式,它的特点很明显。MVP中M和V之间的依赖关系被消除了。

在MVC中,M和V之间通过观察者模式依赖。这种依赖关系在MVP中被转移到M和P层中。这样一来P层必须通过一定的机制通知V层进行数据的更新。所以MVP模式中V层中提供了供P层调用的接口。P层作为观察者获得数据变化是,将调用V层的接口将变化反映到V层中。

在MVP中:

  • Model层依然是主要与业务数据有关。、
  • View依然是应用程序的可视化表示,但是在MVP中它对领域数据(Model层)完全无知,View不再负责同步的逻辑,而是由Presenter负责。Presenter中既有应用程序逻辑也有同步逻辑。所以比起MVC中View层更轻了。但是,View需要提供操作界面的接口给Presenter进行调用
  • Presenter层比较重,它不仅调用Model的接口,也调用View的接口。而且需要作为观察者获得Model的数据更新。

MVP(Passive View)的调用关系

MVP(Passive View)优点

  • 便于测试。Presenter对View是通过接口进行,在对Presenter进行不依赖UI环境的单元测试的时候。可以通过Mock一个View对象,这个对象只需要实现了View的接口即可。然后依赖注入到Presenter中,单元测试的时候就可以完整的测试Presenter应用逻辑的正确性。这里根据上面的例子给出了Presenter的单元测试样例。
  • View可以进行组件化。在MVP当中,View不依赖Model。这样就可以让View从特定的业务场景中脱离出来,可以说View可以做到对业务完全无知。它只需要提供一系列接口提供给上层操作。这样就可以做到高度可复用的View组件。

MVP(Passive View)缺点

  • Presenter中除了应用逻辑以外,还有大量的View->Model,Model->View的手动同步逻辑,造成Presenter比较笨重,维护起来会比较困难。

MVP(Supervising Controller)

Supervising Controller模式中,Presenter会把一部分简单的同步逻辑交给View自己去做,Presenter只负责比较复杂的、高层次的UI操作,所以可以把它看成一个Supervising Controller。

因为Supervising Controller用得比较少,MVVM可以看作是一种特殊的MVP(Passive View)模式,或者说是对MVP模式的一种改良。

MVVM的依赖

Model-View-ViewModel模式中,M层数据的变化不是通过观察者模式通知到V层的(即没有M和V的依赖),也不是通过VM层调用V层的接口将数据传递给V层的(这意味着用户代码不需要手动更新V层)。而是通过在VM层实现一个特殊的binder,将数据从M层直接绑定到V层。这样ViewModel层了解Model层,View层了解ViewModel层。

ViewModel充当了一个数据转换器的作用。它将Model信息转换为View信息,还将命令从View传递到Model。在这里,View可以访问ViewModel,ViewModel可以访问Model。

MVVM的调用关系和MVP一样。但是,在ViewModel当中会有一个叫Binder,或者是Data-binding engine的东西。以前全部由Presenter负责的View和Model之间数据同步操作交由给Binder处理。你只需要在View的模版语法当中,指令式地声明View上的显示的内容是和Model的哪一块数据绑定的。当ViewModel对进行Model更新的时候,Binder会自动把数据更新到View上去,当用户对View进行操作(例如表单输入),Binder也会自动把数据更新到Model上去。这种方式称为:Two-way data-binding,双向数据绑定。可以简单而不恰当地理解为一个模版引擎,但是会根据数据变更实时渲染。

MVVM把View和Model的同步逻辑自动化了。以前Presenter负责的View和Model同步不再手动地进行操作,而是交由框架所提供的Binder进行负责。只需要告诉Binder,View显示的数据对应的是Model哪一部分即可。

MVVM优点

  • 双向绑定技术,当Model变化时,View-Model会自动更新,View也会自动变化。很好做到数据的一致性,不用担心,在模块的这一块数据是这个值,在另一块就是另一个值了。所以 MVVM模式有些时候又被称作:model-view-binder模式。
  • 提高可维护性。解决了MVP大量的手动View和Model同步的问题,提供双向绑定机制。提高了代码的可维护性。
  • 简化测试。因为同步逻辑是交由Binder做的,View跟着Model同时变更,所以只需要保证Model的正确性,View就正确。大大减少了对View同步更新的测试。

MVVM缺点

  • 过于简单的图形界面不适用,或说牛刀杀鸡。
  • 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高。
  • 数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的。
  • 一个大的模块中model也会很大,虽然使用方便了也很容易保证了数据的一致性,当时长期持有,不释放内存就造成了花费更多的内存。
  • 数据双向绑定不利于代码重用。客户端开发最常用的重用是View,但是数据双向绑定技术,让你在一个View都绑定了一个model,不同模块的model都不同。那就不能简单重用View了。

原文地址:https://www.cnblogs.com/zhoulujun/p/10800280.html

时间: 2024-08-25 16:43:54

再谈MV*(MVVM MVP MVC)模式的设计原理—封装与解耦的相关文章

Chromium Graphics: 再谈Chromium WebView硬件渲染模式的演进

摘要:从Android KitKat系统第一个采用Chromium内核的WebView开始,Android WebView一直在持续演进中,自Chromium M38开始,WebView在硬件渲染模式方面发生了较大的变化,最明显的变化莫过于WebGL的支持以及ubercompositor的使用,同时为了吻合Android L的渲染模型变化,DrawGL函数是在Android系统的渲染线程中执行的. Android 4.4系统WebView的硬件渲染 对于Chromium WebView来说,首先

再谈使用X.PagedList.Mvc 分页(ASP.NET Core 2.1)

在以前的博文中写过使用X.PagedList.Mvc组件来对ASP.NET MVC应用程序进行分页,可以参考此篇随笔:Asp.net MVC 使用PagedList(新的已更名 为X.PagedList.Mvc) 分页 但是旧有的X.PagedList.MVC 依赖于.NET Framework版本,为了能够支持ASP.NET Core MVC跨平台的实现,在ASP.NET Core MVC中无需再安装.NET Framework,只需依赖于.NET Core.而且所有ASP.NET Core

浅谈android中的mvc模式

mvc是model.view.controller的缩写.android 鼓励弱耦合和组件的重用,android 中mvc的具体体现如下: 模型(model):是应用程序的主题部分,所有的业务逻辑都应在该层(对数据库的操作.对网络等的操作都应该在model里面处理,当然对计算等操作也是必须放在该层的). 视图层(view):是应用程序中负责生成用户界面的部分.也是整个mvc架构中用户唯一可以看到的一层,接收用户的输入,显示用户的处理结果.一般用xml文件进行界面的描述,使用的时候可以非常方便的引

go案例:客户管理系统流程 mvc模式 分层设计

下面是一个简要的客服系统,主要是演示分层计.. model : 数据部份: package model import "fmt" //声明一个结构体,表示一个客户信息 type Customer struct{ Id int Name string Gender string Age int Phone string Emaill string } func NewCustomer(id int,name string, gender string, age int, phone st

装饰器模式的设计原理

什么是装饰器模式?动态地给一个对象添加一些额外的工作职责,就增加功能来说,装饰器模式比继承的子类更灵活. 从以上图我们可以看到:最核心的类就是Decorator类:它在中间扮演中关键的作用.在继承需要包装类的基础上,其也私有了一个需要装饰类的对象:为什么我们需要继承需要装饰的类呢?我们可以看到在时间调用的时候,我们的方法可以实现我被装饰类的方法一样的调用.我们在Decorator类中的Operation()方法放中,调用被装饰的类的方法.我们的具体的ConcreteDecoratorA 和Con

Swing程序最佳架构设计—以业务对象为中心的MVC模式(转)

前言: 我打算写一系列关于Swing程序开发的文章.这是由于最近我在做一个Swing产品的开发.长期做JavaEE程序,让我有些麻木了.Swing是设计模式的典范,是一件优雅的艺术品,是一件超越时代的产品! 有机会作Swing软件的开发,让我非常有感觉! 呵呵,希望有机会能够用Java3D编写软件,那种感觉一定更棒! Java和Swing都是杰作.我这个人对别人一向很挑剔的,能够得到我由衷地赞誉,可想而知它们有多优秀了.奇怪的是,它们居然一直都无法占领桌面市场.有人说这是技术的原因.我认为这应该

作业七之MVC模式

1.什么是MVC MVC全名是Model View Controller,是模型-视图-控制器的缩写,MVC设计模式的思想就是把Web应用程序分为3个核心模块:模型(Model).视图(View)和控制器(Controller).这三个模块分别充当不同的角色,完成不同的任务.它们之间彼此又相互联系,构成一个结构分明而又高效的整体.MVC的结构如图所示. 在这个三角关系中,它们各自的功能如下所述. 模型:模型是Web程序中用于表示业务数据.进行业务逻辑操作的部分. 视图:视图是用户在Web浏览器中

学习模型-视图-控制器MVC模式

MVC简介: MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.MVC 是一种使用 MVC(Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式: Model(模型)表示应用程序核心(比如数据库记录列表). View(视图)显示数据(数据库记录). Controller(控制器)处理输入(写入数据库记录). MVC 模式同时提供了对 HTML.

实际案例讲解iOS设计模式——MVC模式

MVC模式是iOS编程中提到的最多次的设计模式,也是使用最频繁的设计模式之一.网络上有很多的MVC模式的分析文章,但都是从原理上来解释,很少能找到配套的案例来说明到底在实际的项目中要如何的使用这种模式.小编在经过详细的研究.对比和实验了之后,总结了一下这个模式的一些简单使用方法,希望能起一个抛砖引玉的作用,使得对MVC默认的同学能依葫芦画瓢的了解MVC模式的使用方法,并以此类推出更多.更好的方法出来. 这篇文章先从老生常谈的MVC设计模式的原理说起,然后配上一个简单的案例,以演示如何将一个常规的