C# MVVM 优于 MVC

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1593976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:08:29  来源:igfitidea点击:

Benefits of MVVM over MVC

c#silverlight

提问by JD.

Finally getting to do some Silverlight development and I came across MVVM. I am familiar with MVC and the article I was reading said because of XAML, MVC would not work out. Not having too much experience in XAML clearly is the reason I did not get this point.

终于开始做一些 Silverlight 开发,我遇到了 MVVM。我熟悉 MVC,我正在阅读的文章说,由于 XAML,MVC 行不通。没有太多的 XAML 经验显然是我没有明白这一点的原因。

Can someone explain why MVC is not suited and why MVVM is better for Silverlight development?

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

Thanks JD

谢谢京东

采纳答案by JD.

Its a very slim distinction, which I can explain best by comparing MVC in ASP.NET and MVVM in WPF.

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

In ASP.NET MVC the request comes in from the web server and is handled directly by the Controller. The Controller determines the appropriate View and populates it with Models. The Controller then releases these instances to the underlying system which renders a result to the client. You can see that the Controller is first and last to act.

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

In MVVM, the UI (the View), faces the user and takes user input directly. Within the View, Commands within the ViewModel (which is the DataContext of the View) are triggered by this activity. Control flows to the ViewModel which interprets what the View has sent it and prepares its Models. After control flows back to the View it updates itself according to changes in the Models. If a new View is required, the ViewModel communicates this with the NavigationService (or whatever method of navigation your application uses), which is the purview of the Window or Frame--UI components. You can see that the ViewModel isn't first and last to act; the View plays a much greater role than in MVC.

在 MVVM 中,UI(视图)面向用户并直接接受用户输入。在视图中,视图模型(即视图的 DataContext)中的命令由此活动触发。控制流向 ViewModel,它解释 V​​iew 发送的内容并准备其模型。控制流回视图后,它会根据模型中的变化更新自身。如果需要一个新的 View,ViewModel 会与 NavigationService(或您的应用程序使用的任何导航方法)进行通信,这是 Window 或 Frame--UI 组件的权限。你可以看到 ViewModel 不是第一个也是最后一个动作;视图比在 MVC 中扮演的角色要大得多。

The architecture of WPF/Silverlight is the reason why things are done this way. The command, binding and navigation infrastructures can't be controlled/replaced by the Controller; they are tightly integrated with the UI. So the Controller must sit below the View and take a more passive role.

WPF/Silverlight 的架构是这样做的原因。控制器无法控制/替换命令、绑定和导航基础设施;它们与 UI 紧密集成。所以控制器必须坐在视图下面并扮演更被动的角色。

回答by Henk Holterman

I think the idea is that MVVM is bettersuited to XAML than MVC. Saying MVC 'is not suited' is a bit exaggerated.

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

And why is MVVM better? Mainly because of the superb data-binding and command-binding in XAML. See this article.

为什么 MVVM 更好?主要是因为 XAML 中出色的数据绑定和命令绑定。请参阅这篇文章

回答by Gergely Orosz

MVVM was designed mainly because of XAML and to make data binding even simpler, it's very similar to MVP. The main benefits are simpler way of manipulating the user interface (the ViewModel or Presenter takes care of that task rather than the Model having to fire events to the View after it's been manipulated by the Controller).

MVVM 的设计主要是因为 XAML 并且为了使数据绑定更加简单,它与 MVP 非常相似。主要的好处是操作用户界面的方式更简单(ViewModel 或 Presenter 负责该任务,而不是 Model 在被 Controller 操作后必须向 View 触发事件)。

The best two articles I've come across that helped me understand the principles are MVC vs MVP vs MVVMand MVVM for Tarded Folks Like Me orMVVM and What it Means to Me

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

回答by Neha Khanna

I think the other benefit is learning curve. As most of the developers in frontend technologies have used MVVM kind of coding style it is easier for them to adopt the same than going with a controller model where they need to pass every request from view to controller and have it communicate with Model.

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

回答by Drew Beaupre

Decoupling Components

解耦组件

In MVC, you have a triangular relationship between the components. That is: The Controller owns the View and the Model. The View relies on the definition of the Model. The Model needs to fulfill the requirements of the View. Think of a Hub (controller) and spoke architecture (view and model)

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

In MVVM, think of that triangle flattening out with each component only knowing about one other in the chain. That is: View->ViewModel->Model

在 MVVM 中,想想那个三角形变平,每个组件只知道链中的另一个。即:View->ViewModel->Model

The Model is unaware of anything up the stack. The ViewModel is only aware of the Model The View is only aware of the View Model - it is unaware of the Model.

模型不知道堆栈中的任何内容。ViewModel 只知道 Model View 只知道 View Model - 它不知道 Model。

Why is this important?

为什么这很重要?

This is the core of the original question.

这是原始问题的核心。

The main purpose is further abstraction of your architecture. This will typically lead to a bit more code, but fewer points of contact between objects. Fewer points of contact are important because this leads to more agile code. The more coupling/contact Class A has with Class B, the more impact a change in Class A will have. Reducing the impact of change is one of the key benefits of good architecture.

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

To fully understand this, it's helpful to ponder about what the components really represent. What is a View, a Controller, a ViewModel, or a Model? Are they literal definitions, or more of an abstract concept?

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

In my experience, it has been more beneficial to consider the Model to be a cluster of classes/objects which deal with the construction and persistence of data. It's not just a plain-old-object with properties. It's a class which performs data fetches, data saves, a factory which constructs plain-old-objects. It's a facade layer which provides a clear API into the data. Should this facade layer be referenced directly from the View?

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

In my opinion, it should not. In MVC, that answer is also "no". The Controller fetches data from the Model. In that regard, MVC and MVVM achieve the same goal. Where the two architectures differ is how the data and the view are linked.

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

Like the Model, the View can be a collection of classes which in coordination with one another, render a presentation view. This could consist of a View Controller + View in the case of mobile platforms (View Controller on iOS, Activity on Android). In a lot of cases, you need a class to load a view document into memory and update view properties. There's a lot of work to do here. In MVC, the Controller quickly becomes a 'kitchen sink' class - a sort of dumping grounds for anything related to the current user context.

与模型一样,视图可以是一组类,这些类相互协调,呈现呈现视图。在移动平台的情况下,这可能包括一个视图控制器 + 视图(iOS 上的视图控制器,Android 上的活动)。在很多情况下,您需要一个类来将视图文档加载到内存中并更新视图属性。这里有很多工作要做。在 MVC 中,Controller 很快就变成了一个“厨房水槽”类——一种与当前用户上下文相关的任何东西的倾倒场。

When you multiply this over dozens of potential views within your application, you end up with a lot of deep dependancies between your back-end Model code and your front-end View code. With large Controller classes, these dependencies aren't immediately apparent.

当您将其与应用程序中的数十个潜在视图相乘时,您最终会在后端模型代码和前端视图代码之间产生许多深度依赖。对于大型 Controller 类,这些依赖项不会立即显现。

Flattening out your dependencies

扁平化你的依赖

MVVM flattens out the dependencies. This creates focus. What is focus? The ability to work on a single piece of functionality without the distraction of all other dependencies. Now you can start writing unit tests on code that was previously deemed untestable.

MVVM 压平了依赖关系。这创造了焦点。什么是焦点?在不干扰所有其他依赖项的情况下处理单个功能的能力。现在,您可以开始对以前认为不可测试的代码编写单元测试。

The View Model acts as a facade between the View and the Model. The View Model caters to the needs of the View - technically the View should own the View Model. If the View requires data from multiple sources, the View Model encapsulates the composition of separate data sources into a single, unified, de-normalized object. If the view needs to call back into the Model or other destinations, the View Model provides hooks and routes the appropriate call.

视图模型充当视图和模型之间的外观。视图模型迎合了视图的需要——从技术上讲,视图应该拥有视图模型。如果 View 需要来自多个源的数据,则 View Model 会将不同数据源的组合封装到一个单一的、统一的、非规范化的对象中。如果视图需要回调到模型或其他目的地,视图模型提供钩子并路由适当的调用。

Consider how a networking patch-panel works. At first glance, this seems redundant - why not simply wire your ethernet from point A to point B. But with experience, you'll understand that a patch panel provides you with a key piece of abstraction which allows you to alter the routes of Point B without affecting Point A. This is what your View Model is doing.

考虑网络接线板的工作原理。乍一看,这似乎是多余的 - 为什么不简单地将以太网从 A 点连接到 B 点。但是根据经验,您会明白配线架为您提供了一个关键的抽象部分,允许您更改 Point 的路由B 不影响 A 点。这就是您的视图模型正在做的事情。

Now that you have a clean abstraction between your View and Model, the consequence should be that your View/Controller is only concerned with presentation. This means it shouldn't be dealing with localization or formatting - it gets data and presents data. Your View Model is an ideal place to put these sort of pre-view data massaging. Let's say you need to filter data based on a criteria. Again, the View Model is knowledgable about the Model data (your View is not) and is a great place to put this sort of code.

现在您的视图和模型之间有了清晰的抽象,结果应该是您的视图/控制器只关心表示。这意味着它不应该处理本地化或格式化——它获取数据并呈现数据。您的视图模型是放置此类预览数据按摩的理想场所。假设您需要根据标准过滤数据。同样,视图模型了解模型数据(您的视图不是)并且是放置此类代码的好地方。

Once you start organizing your application requirements in this fashion, your View/Controller code becomes cleaner, and when something needs to change, the implications are more obvious, which leads to fewer bugs.

一旦您开始以这种方式组织您的应用程序需求,您的视图/控制器代码就会变得更清晰,并且当需要更改某些内容时,其影响更加明显,从而导致更少的错误。

Testability

可测试性

One final note on testability: By flattening out dependencies, it makes it easier to inject mock dependencies into your tests. It makes testing easier and more concise. Your View Model becomes something that you can define clear test cases against.

关于可测试性的最后一个注意事项:通过扁平化依赖项,可以更轻松地将模拟依赖项注入到您的测试中。它使测试更容易和更简洁。你的视图模型变成了你可以定义明确测试用例的东西。