跳到主要内容

mvc_mvp_mvvm

*译者按:*MV*设计模式对MVC比较熟悉,听说iOS那边用了其他的。我觉得这些东西都是会者不难的,要静下心来深入了解一次。

原文: http://www.albertzuurbier.com/index.php/programming/84-mvc-vs-mvp-vs-mvvm


这是关于 MVC MVP MVVM 的研究。还有更多?对,我浏览了大量的网站、阅读了大量的博客但是没有找到一个满意的解释。比如说,有一个网站告诉我MVP和MVVM是微软版本的MVC。可能吧,但是它有不解释清楚其概念,也不说明什么情况下该用哪个。而且讨论大多数围绕的是.NET,因为.NET平台有很多这个模式框架,但是如果我们使用其他的框架的话我们又能学到什么呢?还有,这个和 Martin Fowler 的呈现模式(Presentation Pattern)有什么关系呢?我在研究这个模式,这篇文章是正在进行的工作。

现有问题

我是开发图像应用的。我要创建的图像不包含其他图像:流程图,这个最基本的图表类型。我甚至不打算实现 ECMA Flowchart,我的流程图非常的简单。 这个图并不难,我们只是用来编程和学习。我的学习方式是:先设置一个目标然后创建一个带解决的问题。我想要我的呈现模型和对象模型有所不同。我的对象模型没有关联(带有箭头的线),但是呈现模型有关联。呈现模型中的关联代表着引用。对有大多数人来说这个并不难,但是我想知道最佳的实践。当然,我们使用的是MVC模式。但是你可能更想知道MVC的变种,MVP和MVVM。这些模式是如何帮助我的呢?在阅读了大量的博客之后我让人不明白,反而问题更多了。

MVC

MVC模式和面包一样平常易见。但是首先得有人提出,然后有些人写出来,再然后就是每个人都可以使用它。MVC在设计模式中讨论观察者模式时被提到,但是MVC模式并不在设计模式这本书中。通常将 Thing-View-Editor(Trygve Reenskaug, May 1979)这篇论文当做MVC模式的起源。这篇论文没有提到控制器(controller),但是描述了编辑器(editor)。几个月后在文章 Models-Views-Controllers (Trygve Reenskaug, December 1979) 控制器被提了出来。这篇文章也明晰了模型(model)的概念。

模型:在计算机系统数据的抽象形式。

视图:在屏幕上呈现一到多个模型的表象的能力。

编辑器:用户和一到多个视图组件的接口。

在后面那篇文章中控制器取代了编辑器,编辑器重新进行了定义:

编辑器:一个特殊的控制器,允许用户修改被视图呈现的信息。

就我的理解:控制器控制整个视图;编辑器控制视图的一部分。控制器协调菜单,控制面板和其他像鼠标移动、手势这样的携带命令和数据的对象。编辑器只控制其中特定的任务,比如编辑器中的输入框,或者选择器中的下拉框。这篇论文对控制器也就没有清晰的定义。

在2003年, Martin Fowler 在 《Patterns of Enterprise Application Architecture》 这本书中写到:模型 视图 控制器(MVC)是被(误)引用的模式。他随后定义控制器的功能:

控制器接收用户的输入,操纵模型并将视图进行适当的更新。

这个是MVC模式的最通常的定义。

所以,MVC模式的流程是:

  1. 用户输入
  2. 控制器转换输入为变化给模型
  3. 当改变完成,控制器调用视图更新并呈现模型的最新状态

MVC1|600*

我们对比观察者模式:

  1. 用户输入
  2. 控制器转换输入为变化给模型
  3. 模型的任何改变将通过事件或者消息传递给视图(观察者),导致视图更新自己来呈现模型的最新状态

MVC with Observer|600*

Martin Fowler 在他的书里面提到了这个模式的各种各样的变种,每次都是控制器适应特定的目的或观点。我们信息视图和模型在特定的应用中可能更简单,但是控制器确要额外的研究。

MVP

维基百科 将 MVP 称为 MVC模式的衍生物。了解这个模式的历史有助于理解。微软也想对这个模式的讨论是最清楚的,Martin Fowler 也有重要的推动作用。

在表单控制的框架比如 Visual-XXX编程语言家族和Java Swing 应用中随处可见。ASP.NET web页面和JFaces也提到它。

在 MVP 模式中,用户和视图交互。视图自动如何和用户的输入交互,也知道如何呈现模型中的数据。事件在呈现者(Presenter)方向上激发,它在视图和模型组件。呈现者协调改变到模型并返回模型的新的状态给视图。这个是MVP的积极的视图版本。第二个MVP的版本是协调控制器。

积极视图的 MVP 的工作流程是:

  1. 用户进行输入
  2. 视图转换输入成事件发送给呈现者
  3. 呈现者将改变测定给模式
  4. 模型改变并将值返回给呈现者
  5. 呈现者将值返回给视图

积极视图 MVP|center|600*

协调控制器MVP稍微有点不同。这种类型的MVP中,呈现者只在需要其协调是才被使用。视图直接和模型联系进行模式的呈现。

积极视图 MVP|center|600*

MVVM

Model View View-Model 模式最晚被提出来。微软开发,Martin Fowler大力鼓吹。MVVM派生自Martin Fowler 的 呈现模型(Presentation Model)

呈现模型的关键是将所有的行为从视图中移除。行为和状态放到呈现模型中。这意味着视图不会保存任何状态。视图模型包含状态。举个贴切的例子:当按钮被点击时,状态会从呈现模型保存到模型。如果有什么逻辑需要协调表单上看起来的不同,它发生在呈现模型中,而不是视图中。在MVP模式中视图逻辑可能会在视图中,但是PM 模式一定不会。

MVVM通过技术将步子迈得比PM还远:视图不存储任何状态或保存任何逻辑。在WPF中,UI的创建通过XAML这个xml医院,XAML文档不保存任何的状态,只允许和相关的类绑定。渲染引擎将XAML声明的视图渲染成UI并管理视图和视图模型的关系。

微软指出UI定义包括页面背后的代码让事情有点含糊不清。然而,页面后的代码理论上只包含不容易在XAML中定义的初始化逻辑和呈现。

当视图模型保存状态并绑定到模型,微软以外这个模式也叫 模型 视图 绑定者(Model View Binder MVB)。

MVVM的流程是:

  1. 用户输入
  2. 视图转换这个为数据然后发送给 视图模型,视图模型处理数据
  3. 视图模型被调命令调用,视图模型将这个发送给模型
  4. 模型更新后返回自身的状态的通知给视图模型
  5. 视图模型将通知返回给视图
  6. 视图调用 视图模型来实现将改变出现处理

MVVM|center|600*

总结

MVC模式是一个伟大的实现,它将呈现,控制和数据分离。但是实现细节让其变得不好理解。比如,当一个用户和控制器交互,如果鼠标点击的信息都在视图中,控制器如何得到被修改的信息?这导致最初的文章包含迷你控制器的介绍:编辑器。在非常底层的操作系统中,MVC模式是可实现的,但是在图形界面中,每件事情都是一个编辑器就不可控了。于是MVC演变到MVP。我敢说MVP模式是三种模式中使用最广的。

MVP模式在可视化表单设计中被应用得最多,表单中所有的东西都叫做控件或者组件。这种模式将逻辑放到视图变得可能。许多图像程序都在视图中有大量逻辑。视图只有在图形化测试程序中才可测试。图形化测试很繁琐,而单元测试要轻松很多。越多的逻辑放到视图,测试就越麻烦。MVVM模式,虽然可能有将逻辑放到视图中,但是因为XML的使用,这种行为不被鼓励。

我不是说MVVM模式不能通过XAML之外的方式实现。如果MVP的视图功能很少而才能走处理状态,这种MVP的使用方式实际上就是 MVVM。

选择

选择哪个模式和创建应用时使用的框架强关联。在我例子中我使用 可视化IDE Pascal 环境。所以默认就选择了MVP模式。为了更容易测试,我将使用PM模式。

在 .NET 环境中,选择更加的清晰。技术的选择的结果在游泳模式的选择。或者说,模式解释了技术的选择。你需要理解模式的实现来连接逻辑是如何进行的。讨论应用的设计,设计模式和语言形成对比。

MVC, MVP还有MVVM因此更多的是框架模式而不是设计模式。它们不支持框架的讨论,他们支持框架的介绍。比如,在WPF框架中使用XAML来定义视图,视图类从控制器或者用户控制类推导出来,视图模型类不想上线观察者设计模式来和视图交流,而模型也需要实现观察者模式来和视图模型交流。

你必须理解MVC模式和它的派生模式,这样你才可以理解你使用的框架的解释。