客户端设计中的表现模式

本文详细介绍了用户界面设计的三种主要模式:MVC、MVP和MVVM,包括它们的起源、工作流程、优缺点及应用场景。MVC模式将视图、模型和控制器分离,MVP模式进一步将逻辑移到Presenter中,MVVM则通过数据绑定简化了视图和模型的同步。MVP的变体MVP-VM结合了MVP和MVVM的优点,适用于复杂的UI场景。每种模式都有其适用范围,开发者应根据项目需求选择合适的设计模式。
摘要由CSDN通过智能技术生成

​前言

与用户界面相关的最大的问题就是大量的凌乱的代码, 表现模式(Presentation Patterns)就是围绕如何移除用户界面的复杂性,让界面更加简洁和可管理而产生的。

 

表现模式主要包含:

  • 用户界面包含负责的逻辑用于维护界面相关对象;

  • 包含了应用程序状态的维护;

 

因此, 目前网络上所称的“MVP、MVC、MVVM架构”,本质上并不完全属于一种架构方式,更确切的说,是一种用户界面和逻辑处理间的一种表现模式 。

(注:本文并不包含iOS的VIPER模式。)

 

用户界面三要素:状态,逻辑和同步

我们在客户端设计中,用户界面上遇到的三大问题是:状态 (State)、逻辑 (Logic) 、同步 (Synchronization),其中状态是用户界面最关心的问题之一。

 

主流表现模式一览

目前最常见的表现模式有三种:即MVC模式、MVP模式、MVVM模式。如下图所示:

 

 

MVC模式

早在上个世纪70年代,美国的施乐公司(Xerox)的工程师研发了Smalltalk编程语言,并且开始用它编写图形界面的应用程序。而在Smalltalk-80这个版本的时候,一位叫Trygve Reenskaug的工程师设计了MVC图形应用程序的架构模式,极大地降低了图形应用程序的管理难度。而在四人组(Gang of Four: GoF)的设计模式当中并没有把MVC当做是设计模式,而仅仅是把它看成解决问题的一些类的集合。Smalltalk-80 MVC和GoF描述的MVC是最经典的MVC模式。

 

MVC处理数据、界面的流程如下图:

 

由图中可以看出,MVC模式中,Model、View均与Controller进行绑定,View接收到用户交互后,将事件传递至Controller,Controller负责业务处理,处理完成之后,将操作Model,并通知View进行更新。此时,View更新需要再从Model处获得数据,获得数据后,完成自身的更新。

(注:网上对MVC实现方式较多,这里只选择了一种较为常用的方式进行阐述。)

 

MVC的基础:

  • 没有Presenter,有一个Controller

  • 请求首先到达Controller

  • Controller绑定Model和View

  • 逻辑存储在Controller里

 

MVC优缺点

优点

MVC的方式将业务全部放在了Controller层进行处理,优点是视图层和业务层耦合度低、模块化程度较高,当业务发生变动时,只需调整Controller即可。

缺点

视图与控制器间联系过于紧密,View是强依赖特定的Model的,无法实现组件化,并且视图对模型数据访问效率较低。

 

MVP模式

因为MVC模式的局限性,后续出现了一种变体,最终演变成MVP的模式。

MVP设计模式有分两种,最先提出来的是马丁·福勒(Martin Fowler),最后于2006年将MVP分成监督控制器Supervising Controller(SC)和被动视图Passive View(PV);概念上来说,两者是相同的,最大的不同在于Presenter能控制的View的程度不同。因SC模式使用较少,因此这里只是简单介绍。

 

PV模式

在PV模式中,视图上的所有View的数据(具体点来说可以是控件的属性)都会暴露出来,供Presenter来调用。View的任务就是简单地在需要的时候把数据呈现出来,或者把数据提供给Presenter。涉及到一些UI逻辑的,无论复杂与否都与View本身无关。UI逻辑是Presenter的任务,这种方式使得View以一种很轻量级的形式存在,UI逻辑放到了Presenter里面进行处理,方便了对UI逻辑做测试。

 

MVP-PV模式处理数据、界面的流程如下图:

 

MVP-PV的基础:

  • 状态存储在View里。

  • 所有UI逻辑存储在Presenter里。

  • View与Model完全隔离。Presenter负责处理Model和View以及额外的数据同步任务。

  • Presenter知道View

  • View不知道Presenter

 

SC模式

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

 

MVP-SC的基础:

  • 状态存储在View里

  • Presenter包含复杂的展示逻辑。简单的UI绑定逻辑通过使用绑定技术来完成,例如WPF绑定和Silverlight绑定。任何复杂性有Presenter类处理

  • Presenter知道View

  • View不知道Presenter

  • View视图使用由WPF和Silverlight提供的绑定技术与模型链接

 

MVP的优缺点 

优点

  • 模型与视图完全分离,修改视图不会影响模型。

  • 可以更高效地使用模型,因为所有的交互都发生在Presenter内部

  • 可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;

  • 逻辑放在Presenter中,可以脱离用户接口来测试这些逻辑

缺点

  • 视图和Presenter的交互会过于频繁,使得他们的联系过于紧密。也就是说,一旦视图变更了,presenter也要变更

 

MVVM模式

MVVM模式最早由微软提出,并将其运用在WPF和SilverLight中。与此同时,在技术层面,WPF也带来了 诸如Data Binding(数据绑定)、Dependency Property(依赖属性)、Routed Events(路由事件)、Command(命令)、DataTemplate(数据模板)、ControlTemplate(控制模板)等新特性。MVVM模式其实是MVP模式与WPF结合的应用方式时发展演变过来的一种新型架构模式。它立足于原有MVP框架并且把WPF新特性糅合进去,以应对客户日益复杂的需求变化。

(注:MVVM的模式是马丁·福勒所提出的Presentation Model的模式的一种演变。)

 

MVVM模式处理数据、界面的流程如下图:

 

从图中看出,它和MVP的区别貌似不大,只不过是Presenter层换成了ViewModel层,还有一点就是View层和ViewModel层是相互绑定的关系,这意味着当你更新ViewModel层的数据的时候,View层会相应的变动UI。

我们很难去说MVP和MVVM这两个MVC的变种孰优孰劣,还是要具体情况具体分析。

 

MVVM的基础:

  • ViewModel是基础

  • 状态储存在ViewModel里

  • 逻辑存储在ViewModel里

  • ViewModel代表一个UI的抽象视图

  • ViewModel不知道View

  • View知道ViewModel

  • View与Model完全隔离

  • 使用DataBinding

 

MVVM的优缺点

优点:

  • 提高可维护性。解决了MVP大量的手动View和Model同步的问题,提供双向绑定机制。提高了代码的可维护性。

  • 简化测试。因为同步逻辑是交由Binder做的,View跟着Model同时变更,所以只需要保证Model的正确性,View就正确。大大减少了对View同步更新的测试。

缺点:

  • ViewModel引用了View,从而导致ViewModel无法重用于其他View

  • 过于简单的图形界面不适用

  • 对于大型的图形应用程序,视图状态较多,ViewModel的构建和维护的成本都会比较高。

  • 数据绑定的声明是指令式地写在View的模版当中的,这些内容是没办法去打断点debug的。

  • 并没有解决View层过重的问题,仅仅去掉了数据绑定,尤其对一些复杂业务逻辑的页面。

 

MVVM的进化:MVP-VM模式

 

在MVVM模式之后,微软在MVP的基础上,提出了一种新的模式MVP-VM,具体内容可参考微软官网文章"MVPVM Design Pattern - The Model-View-Presenter-ViewModel Design Pattern for WPF"。把MVPVM这种模式,拆分成为Model-View-Presenter-ViewModel,这种模式将MVP和MVVM两者的特点结合了起来,并且将ViewModel进行拆分,提升可拔插化以提高可复用性,松耦合和尽量小的接口可以给予最大的可复用性,使得组件能重组使用。

(注:后面会提到Model分领域模型和视图模型,如无特殊说明,下文的Model均属于领域模型,MVP-VM的ViewModel和MVVM的ViewModel概念不尽相同。)

 

以Android为例,在MVP-VM作者的介绍中:

  • Model层,和MVP中的Model是类似的。即PO或者DO

  • View层,依然是由Activity/Fragment来担当,不同的是需要实现ViewModel的观察者接口,来实现View的动态更新

  • Presenter层,如上图所示,Presenter作为核心,连接着M、V、VM

  • VM层,和MVVM中的VM是类似的,只是为了让VM可以重用。不再和特定的View绑定,而且不再直接对Model进行操作

 

因此,Android DataBinding的出现,让MVP-VM这种模式在Android上出现了新的思路。

 

MVP-VM模式处理数据、界面的流程如下图:

从图中可以发现,MVP-VM中的Model包含了领域模型(Domain Model)和视图模型(View Model);领域模型是一个对象层,是对现实世界逻辑、数据和你应用程序所处理的问题的抽象。视图模型通常只包含领域模型的一个子集,而且只包含界面上所需要的属性。此外Domain Model是数据加上行为的组合体,是由复杂的变量类型组成的并且具有层次。业务的处理主要由Presenter来进行承载。因此,该模式将业务、视图、领域模型和视图模型进行分离,更有层次感。当然缺点也显而易见,对于逻辑功能较为简单的页面来说,将其进行拆分会增加整体结构的复杂性,没有使用MVP或者MVVM来的更加简单轻便。

 

MVP-VM的基础

按照微软的定义,严谨的MVP-VM模式应该遵循以下定义

  • Presenter是基础(MVP)

  • 状态储存在ViewModel里(MVVM)或者Presenter中(MVP)

  • 逻辑存储在Presenter里(MVP)

  • ViewModel代表一个UI的抽象视图(MVVM)

  • ViewModel不知道View(MVVM)

  • View知道ViewModel(MVVM)

  • View不知道Presenter(MVP) ViewModel不知道Presenter(MVP-VM)

  • View与Domain Model完全隔离(MVVM)

  • Presenter知道Domain Model(MVP)

  • Presenter知道View(MVP-VM)

  • Presenter负责处理ViewModel以及额外的数据同步任务(MVP-VM)

  • ViewModel中不存在任何逻辑处理(MVP-VM)

 

各表现模式下状态、逻辑和同步关系

选取了目前最常用的集中表现模式,各模式下,状态、逻辑和同步的处理如下表所示:

结语

综上所述,MVC、MVP、MVVM、MVP-VM本身就是一种循序渐进的过程,后者解决了前者的问题,将前者的缺点变成了自己自己的优点。但最终都是由技术选择驱动的,每一种模式并无孰好孰坏之分,都拥有不同适用的场景。

 

参考文档

《MVVM for .NET Winforms – MVP-VM (Model View Presenter - View Model) Introduction》

《MVC vs. MVP vs. MVVM》

《MVC,MVP 和 MVVM 模式如何选择?》

《MVC,MVP,MVVM之异曲同工》

《MVP的PV模式与SC模式》

《UI的設計模式MVP模式–Supervising Controller》

《MVP(SC),MVP(PV),PM,MVVM 和 MVC 表现模式架构对比》

《展示模式架构比较MVP(SC),MVP(PV),PM,MVVM和MVC》

《MVC、MVP、MVVM三种区别及适用场合》

《MVPVM in Action, 谁告诉你MVP和MVVM是互斥的》

《浅谈Android架构之MVP,MVVM》

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值