MVVM比MVC的好处

最后做一些Silverlight开发,我碰到MVVM。 我熟悉MVC和我正在阅读的文章,因为XAML,MVC不会奏效。 没有太多的XAML经验显然是我没有得到这一点的原因。

有人可以解释为什么MVC不适合,为什么MVVM更适合Silverlight开发?

谢谢JD

它是一个非常苗条的区别,我可以通过比较ASP.NET MVC和WPF中的MVVM来最好地解释。

在ASP.NET MVC中,请求来自Web服务器,由Controller直接处理。 控制器确定适当的视图并用模型填充它。 然后,Controller将这些实例释放到将结果呈现给客户端的底层系统。 你可以看到控制器是第一个和最后一个行动。

在MVVM中,用户界面(视图)面向用户并直接进行用户input。 在View中,ViewModel中的命令(View的DataContext)由这个活动触发。 控制stream向ViewModel,ViewModel解释View发送的内容并准备其模型。 控制stream回到视图后,根据模型中的更改自行更新。 如果需要一个新的视图,ViewModel将与NavigationService(或者你的应用使用的任何导航方法)进行通信,这是Window或者Frame – UI组件的范围。 你可以看到ViewModel不是第一个也不是最后一个。 View在MVC中扮演着更为重要的angular色。

WPF / Silverlight的体系结构就是为什么这样做的原因。 控制器不能控制/取代命令,绑定和导航基础设施; 它们与UI紧密集成。 因此,财务主任必须坐在视野之下,并采取更为被动的angular色。

MVVM的devise主要是因为XAML,使数据绑定更加简单,与MVP非常相似。 主要好处是操作用户界面的简单方法(ViewModel或Presenter负责处理这个任务,而不是在Controller被Controller操作之后,必须将事件发送到View)。

我遇到的最好的两篇文章帮助我理解MVC和MVP,MVVM和MVVM,像我 MVVM这样的Tarded Folks,以及它对我意味着什么

解耦组件

在MVC中,组件之间有一个三angular关系。 那就是:Controller拥有View和Model。 视图依赖于模型的定义。 该模型需要满足视图的要求。 考虑一个集线器(控制器)和辐条架构(视图和模型)

在MVVM中,想象这个三angular形与每个组件都只有一个,而且只知道链中的另一个。 那就是:View-> ViewModel-> Model

模型没有意识到堆栈中的任何东西。 ViewModel只知道模型视图只知道视图模型 – 它不知道模型。

为什么这很重要?

这是原始问题的核心。

主要目的是进一步抽象你的架构。 这通常会导致更多的代码,但更less的对象之间的联系点。 更less的联络点是重要的,因为这会导致更敏捷的代码。 A类与B类的耦合/接触越多,A类变化的影响就越大。 减less变化的影响是良好的体系结构的关键好处之一。

要充分理解这一点,思考组件真正代表什么是有帮助的。 什么是视图,控制器,视图模型或模型? 他们是字面的定义,还是更抽象的概念?

根据我的经验,将模型看作是处理数据构造和持久性的类/对象集合,会更有好处。 它不只是一个具有属性的普通旧对象。 它是一个执行数据提取,数据存储的类,一个构造普通对象的工厂。 这是一个为数据提供清晰API的外观层。 这个外观层应该直接从视图中引用吗?

在我看来,它不应该。 在MVC中,答案也是“否”。 控制器从模型中获取数据。 在这方面,MVC和MVVM实现相同的目标。 两种架构不同的是数据和视图如何链接。

与模型一样,视图可以是一个相互协调的类的集合,呈现一个表示视图。 对于移动平台(iOS上的View Controller,Android上的Activity),这可能包含View Controller + View。 在很多情况下,您需要一个类将视图文档加载到内存中并更新视图属性。 这里有很多工作要做。 在MVC中,控制器很快成为“厨房水槽”类 – 一种与当前用户环境有关的倾倒场。

当您在应用程序中将数十个潜在的视图相乘时,最终会在后端Model代码和前端View代码之间产生深刻的依赖关系。 对于大型控制器类,这些依赖关系不是立即显现的。

展平你的依赖

MVVM展平了依赖关系。 这创造了焦点。 什么是重点? 能够在不影响所有其他依赖关系的情况下处理单个function。 现在您可以开始编写以前被认为不可testing的代码的unit testing。

视图模型充当视图和模型之间的立面。 视图模型迎合视图的需求 – 从技术上讲,视图应该拥有视图模型。 如果视图需要来自多个来源的数据,则视图模型将单独数据源的组合封装成单个统一的去归一化对象。 如果视图需要callback到模型或其他目标中,则视图模型将提供挂钩并路由相应的呼叫。

考虑networking配线架如何工作。 乍一看,这似乎是多余的 – 为什么不简单地将以太网从A点连接到B点。但是凭借经验,您将会明白,配线架为您提供了一个关键的抽象部分,允许您更改Point B而不影响A点。这就是您的View Model正在做的事情。

既然在视图和模型之间有一个简洁的抽象,那么结果应该是你的视图/控制器只关心表示。 这意味着它不应该处理本地化或格式化 – 它获取数据并呈现数据。 您的视图模型是进行这种预览数据按摩的理想场所。 假设您需要根据条件过滤数据。 同样,视图模型是关于模型数据(你的视图不是)的知识,是放置这种types的代码的好地方。

一旦你开始以这种方式组织你的应用程序需求,你的视图/控制器代码将变得更加清晰,并且当需要改变的时候,其影响会更加明显,从而导致更less的bug。

可测性

关于可testing性的最后一个注记:通过展开依赖关系,可以更容易地将模拟dependency injection到testing中。 它使testing更简单,更简洁。 您的视图模型成为您可以定义明确的testing用例的东西。

我认为这个想法是MVVM比MVC 适合XAML。 说MVC“不适合”有点夸张。

为什么MVVM更好? 主要是因为XAML中的数据绑定和命令绑定。 看到这篇文章 。

我认为另一个好处是学习曲线。 由于前端技术中的大多数开发人员都使用了MVVMtypes的编码风格,因此他们比使用控制器模型更容易采用MVVM,他们需要将每个请求从视图传递到控制器,并与模型进行通信。