MVVM优于MVC的好处

JD.*_*JD. 44 c# silverlight

最后开始做一些Silverlight开发,我遇到了MVVM.我熟悉MVC和我正在阅读的文章说因为XAML,MVC无法解决.没有太多的XAML经验是我没有明白这一点的原因.

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

谢谢JD

小智 60

它是一个非常细微的区别,我可以通过比较ASP.NET中的MVC和WPF中的MVVM来解释.

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

在MVVM中,UI(视图)面向用户并直接获取用户输入.在View中,ViewModel中的命令(View的DataContext)由此活动触发.控制流向ViewModel,ViewModel解释View发送的内容并准备其模型.控制流回View后,它会根据模型中的更改自行更新.如果需要新的View,ViewModel会将此与NavigationService(或您的应用程序使用的任何导航方法)进行通信,这是Window或Frame-UI组件的范围.您可以看到ViewModel不是第一个也是最后一个行为; View比MVC扮演更重要的角色.

WPF/Silverlight的体系结构是事情以这种方式完成的原因.控制器无法控制/替换命令,绑定和导航基础结构; 它们与UI紧密集成.因此,Controller必须位于View下方,并采取更为被动的角色.


Ger*_*osz 13

MVVM的设计主要是因为XAML并且使数据绑定更简单,它与MVP非常相似.主要的好处是操作用户界面的简单方法(ViewModel或Presenter处理该任务,而不是模型必须在Controller操纵后向View发送事件).

我遇到的最好的两篇文章帮助我理解了原则是MVC vs MVP vs MVVMMVVM for Tarded Folks Like Me MVVM及其对我意味着什么


Dre*_*pre 13

去耦组件

在MVC中,组件之间存在三角关系.即:Controller拥有View和Model.View依赖于Model的定义.模型需要满足View的要求.想想Hub(控制器)和辐条架构(视图和模型)

在MVVM中,考虑到每个组件的三角形变平,只知道链中的另一个.那就是:View-> ViewModel-> Model

模型不知道堆栈中的任何东西.ViewModel只知道模型View只知道View模型 - 它不知道Model.

为什么这很重要?

这是原始问题的核心.

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

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

根据我的经验,将模型视为一个处理数据构造和持久性的类/对象集群更为有益.它不仅仅是一个具有属性的普通旧对象.它是一个执行数据提取,数据保存,构建普通旧对象的工厂的类.它是一个Facade层,为数据提供了清晰的API.该外观层是否应直接从View引用?

在我看来,它不应该.在MVC中,答案也是"不".Controller从模型中获取数据.在这方面,MVC和MVVM实现了相同的目标.两种体系结构不同的地方是数据和视图的链接方式.

与模型一样,View可以是一个类的集合,它们彼此协调,呈现一个表示视图.对于移动平台(iOS上的View Controller,Android上的Activity),这可能包含View Controller + View.在很多情况下,您需要一个类将视图文档加载到内存中并更新视图属性.这里有很多工作要做.在MVC中,Controller很快就变成了"厨房接收器"类 - 一种与当前用户环境相关的任何倾销场.

当您在应用程序中将数十个潜在视图相乘时,您最终会在后端模型代码和前端View代码之间产生很多深度依赖.对于大型Controller类,这些依赖关系并不是很明显.

展平您的依赖项

MVVM消除了依赖关系.这创造了焦点.什么是焦点?能够处理单个功能而不会分散所有其他依赖项.现在,您可以开始在以前认为不可测试的代码上编写单元测试.

视图模型充当视图和模型之间的外观.View Model满足View的需求 - 从技术上讲,View应该拥有View Model.如果View需要来自多个源的数据,则View Model会将单独数据源的组合封装到单个统一的非规范化对象中.如果视图需要回调到模型或其他目标,则视图模型提供挂钩并路由相应的调用.

考虑一下网络配线架的工作原理.乍一看,这似乎是多余的 - 为什么不简单地将您的以太网从A点连接到B点.但是根据经验,您将了解补丁面板为您提供了一个关键的抽象,允许您更改Point的路径B不影响A点.这是您的View Model正在执行的操作.

现在您在View和Model之间有一个干净的抽象,结果应该是您的View/Controller只关注表示.这意味着它不应该处理本地化或格式化 - 它获取数据并呈现数据.您的视图模型是进行这类预览数据按摩的理想场所.假设您需要根据条件过滤数据.同样,视图模型可以了解模型数据(您的视图不是),并且是放置此类代码的好地方.

一旦以这种方式开始组织应用程序需求,您的View/Controller代码就会变得更清晰,当需要更改某些内容时,其含义会更明显,从而导致更少的错误.

可测性

关于可测试性的最后一点注意事项:通过展平依赖关系,可以更轻松地将模拟依赖项注入到测试中.它使测试更容易,更简洁.您的视图模型将成为可以定义明确测试用例的内容.