为什么要使用MVVM? [英] Why use MVVM?

查看:158
本文介绍了为什么要使用MVVM?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我一直在寻找到MVVM模式,每一次我有previously试图寻找到它,我放弃了一些原因:


  1. 不必要的额外长篇大论编码

  2. 为codeRS没有明显的优势(没有设计者在我的办公室,目前只有我自己很快就被另一个codeR)

  3. 没有很多资源的良好做法/文档! (或者至少很难找到)

  4. 想不出一个单一的场景,这是有利的。

我要放弃它再次,我想我会问,看看是否有人回答上述原因。

老实说,我无法看到使用此一单/合伙编码的优势。即使是在与Windows 10的复杂项目。对我来说,DataSet是一个足够好的观点,并喜欢在回答由布伦特下面结合<一个href=\"http://stackoverflow.com/questions/2652166/best-method-for-binding-combobox/2652700#2652700\">question

相比于XAML DataBinding当

有人能证明,其中使用将节省的时间MVVM模式的一个例子。

我结合在XAML目前完成100%。因此,我没有看到虚拟机的点作为背后它只是额外的code我需要写和依靠。

编辑:结果
下午约研发支出MVVM后,我终于找到的东西,让我意识到从这个真正的好处<一个href=\"http://stackoverflow.com/questions/1644453/why-mvvm-and-what-are-its-core-benefits/1644955#1644955\">answer.


解决方案

摘要


  • 所有模式的用法态势,效益(如果有的话)始终在于降低复杂性。

  • MVVM指导我们如何在一个GUI应用程序分发类之间​​的责任。

  • 视图模型,从模型的数据项目成适合查看的格式。

  • 对于琐碎的项目MVVM是不必要的。仅使用视图就足够了。

  • 对于简单的项目,视图模型/型号拆分可能是不必要的,并且只使用一个模型和一个视图是不够好。

  • 在需要时
  • 模型和视图模型不需要从开始存在,可以引入。

当使用模式时,以避免他们

有关一个足够简单的应用程序每一个设计模式是矫枉过正。假设你写一个显示一个按钮,当pressed显示Hello World的一个GUI应用程序。在这种情况下,设计模式,如MVC,MVP,MVVM都加了很多的复杂性,同时不加入任何任何价值。

在一般情况下,它始终是一个错误的决定引进只是因为它有点适合的设计模式。设计模式应该被用来降低复杂性,通过直接降低整体复杂性,或通过用熟悉的复杂性取代陌生的复杂性。 如果设计模式不能降低复杂性通过下列2种方式,不使用它。

要解释熟悉又陌生的复杂性,采取下列字符2个序列:


  • D.€|?重新%DFA C

  • CorrectHorseBatteryStaple

而第二个字符的顺序是先序列长度的两倍,它更容易阅读,更快地写,更容易记住比第一序列,都是因为它更熟悉。这同样适用于在code熟悉的模式如此。

要意识到的事实:一些模式可能不熟悉的人谁将会在未来的code工作的所有开发人员。在previous实例而言,下面的序列可以或可以不容易记住比任上述序列的,根据人的记住它的经验和训练3.14159265358979323846264338327950。在某些情况下更先进的设计图案都参与其中,它才有意义,如果维护开发人员已经熟悉它使用的设计模式。

MVVM

这是说,让我们潜入MVVM的话题通过一个例子来。 MVVM指导我们如何在一个GUI应用程序分发类之间​​的责任(或层间 - 更多关于这个版本),用具有少量的几个类的目标,同时保持每个班级的责任小,良好定义的数量

'适当'MVVM假设至少一个中等复杂的应用程序,这与从地方获取数据的交易。它可从一个数据库中获取所述数据,文件,web服务,或者从其他来源的无数。

示例

在我们的例子中,我们有2班查看模式,但没有视图模型。在模式包装了一个CSV文件,它在启动时读取,当应用程序关闭扑救,所有对数据的更改取得了用户。在查看是一个窗口类,从表中的模式显示数据,并允许用户编辑数据。该CSV内容可能看起来有点像这样:

  ID,名称,价钱
1,棒,5 $
2,大箱子,$ 10
3,轮毂,20 $
4,瓶,3 $

新要求:查看价格以欧元

现在我们被要求做出改变,以我们的应用程序。该数据包括已经有一个价格一栏,包含美元价格的2维网格。我们需要添加一个新列,显示价格在欧洲除了那些在美元基础上predefined汇率。该CSV文件的格式必须不能改变,因为其他应用程序使用相同的文件工作,而这些其他应用程序不在我们的控制之下。

一个可能的解决方案是简单地将新列添加到模式类。这是不是最好的解决方案,因为模式保存所有它暴露到CSV数据 - 我们不希望在CSV新欧元的价格列。因此,更改为模式将是不平凡的,这也将是很难描述模型类做什么,这是一个的$c$c闻

我们也可以让在查看的变化,但我们目前的应用程序使用数据绑定,直接显示的数据由我们的模型提供类。因为我们的GUI框架不允许当表数据绑定到数据源我们在表中引入额外的计算列,我们需要做的查看,使这项工作,使查看复杂得多。

介绍视图模型

有没有视图模型,因为到现在为止模式 presents在完全数据中的应用这样该CSV需要它,这也是查看需要它的方式。有没有目的的视图模型之间会一直增加了复杂性。但现在,模式不再presents在查看需要它的方式中的数据,我们写一个视图模型视图模型项目的模式的数据以这样的方式使查看可以是简单的。 previously订阅查看类模型类。现在,新的视图模型类预订了模式类,并公开了模式的数据到查看 - 与显示在欧元的价格一个额外的列。在查看不再知道模式,它现在只知道视图模型,它从查看点看起来一样的模式以前那样 - 除了暴露数据包含一个新的只读列。

新的要求:不同的方式对数据进行格式化

接下来的客户的要求就是我们不应该在一个4X5的网格中显示的数据表中的行,而是显示每个项目(又名行)作为卡/盒的信息,并显示20盒在屏幕上,表示在一个时间20盒。因为我们保持了查看逻辑简单,我们只需更换查看完全用新的类,它作为客户的欲望。当然,还有另一种谁$ P $客户pferred老查看,所以我们现在需要同时支持。因为所有的通用业务逻辑已经恰好是在视图模型这不是大问题。因此,我们可以通过重命名视图类到的TableView ,并写入新 CardView 类,显示在数据解决这个问题一卡格式。我们还必须写一些胶水code,这可能是在启动功能的oneliner。

新的要求:动态汇率

接下来的客户的要求就是我们拉的汇率从互联网上,而不是使用predefined汇率。这是我们重新审视有关层我先前说的地步。我们不改变我们的模式类提供的汇率。相反,我们写(或查找)一个完全独立的额外的类,它提供的汇率。新课改成为模型层的一部分,我们的视图模型巩固了CSV-模型和汇率-型号的信息,它则presents到在查看。对于这一变化的旧模式类和View类甚至没有被感动。好了,我们确实需要重新命名模型类 CsvModel 我们称之为新类 ExchangeRateModel

如果我们没有推出的视图模型当我们做却都不是等到现在才这样做的,工作量引进视图模型现在会更高,因为我们需要从两个删除显著数量的功能查看模式和移动功能到视图模型

后记在单元测试

MVVM的主要目的不在于在模型和视图模型的code可以在单元测试付诸表决。 MVVM的主要目的是,code被分成的类的小数目的明确定义的职责。一个具有code组成的班级,少数明确责任若干好处是,它更容易把code下的单元测试。一个更大的好处是,code是比较容易理解,维护和修改。

Okay, I have been looking into MVVM pattern, and each time I have previously tried looking into it, I gave up for a number of reasons:

  1. Unnecessary Extra Long Winded Coding
  2. No apparent advantages for coders (no designers in my office. Currently only myself soon to be another coder)
  3. Not a lot of resources/documentation of good practices! (Or at least hard to find)
  4. Cannot think of a single scenario where this is advantageous.

I'm about to give up on it yet again, and thought I'd ask to see if someone answer the reasons above.

I honestly can't see an advantage of using this for a single/partner coding. Even in complex projects with 10's of windows. To me the DataSet is a good enough view and binding like in the answer by Brent following question

Could someone show an example of where using MVVM pattern would of saved time when compared to XAML DataBinding.

100% of my binding is done in XAML at the moment. And therefore I don't see the point of the VM as its just extra code behind that I need to write and depend on.

EDIT:
After spending the afternoon researching about MVVM I have finally found something that made me realise the true benefits of it from this answer.

解决方案

Summary

  • The usage of all patterns is situational, and the benefit (if there is any) always lies in reduced complexity.
  • MVVM guides us how to distribute responsibilities between classes in a GUI application.
  • ViewModel projects the data from the Model into a format that fits the View.
  • For trivial projects MVVM is unnecessary. Using only the View is sufficient.
  • For simple projects, the ViewModel/Model split may be unnecessary, and just using a Model and a View is good enough.
  • Model and ViewModel do not need to exist from the start and can be introduced when they are needed.

When to use patterns and when to avoid them

For a sufficiently simple application every design pattern is overkill. Assume you write a GUI application that displays a single button which when pressed shows "Hello world". In this case, design patterns like MVC, MVP, MVVM all add a lot of complexity, while not adding any value whatsoever.

In general, it is always a bad decision to introduce a design pattern just because it somewhat fits. Design patterns should be used to reduce complexity, either by directly reducing overall complexity, or by replacing unfamiliar complexity with familiar complexity. If the design pattern cannot reduce complexity in either of these 2 ways, do not use it.

To explain familiar and unfamiliar complexity, take the following 2 sequences of characters:

  • "D.€|Ré%dfà?c"
  • "CorrectHorseBatteryStaple"

While the second character sequence is twice the length of the first sequence, it's easier to read, faster to write, and easier to remember than the first sequence, all because it's more familiar. The same holds true for familiar patterns in code.

Be conscious of the fact that some patterns may not be familiar to all developers who are going to work with the code in the future. In terms of the previous example, the following sequence may or may not be easier to remember than either of the sequences above, depending on the experience and training of the person remembering it: "3.14159265358979323846264338327950". In some cases where more advanced design patterns are involved, it only makes sense to use a design pattern if the maintenance developers are already familiar with it.

MVVM

That said, let's dive into the topic of MVVM by means of an example. MVVM guides us how to distribute responsibilities between classes in a GUI application (or between layers - more about this later), with the goal of having a small number of classes, while keeping the number of responsibilities per class small and well defined.

'Proper' MVVM assumes at least a moderately complex application, which deals with data it gets from "somewhere". It may get the data from a database, a file, a web service, or from a myriad of other sources.

Example

In our example, we have 2 classes View and Model, but no ViewModel. The Model wraps a csv-file which it reads on startup and saves when the application shuts down, with all changes the user made to the data. The View is a Window class that displays the data from the Model in a table and lets the user edit the data. The csv content might look somewhat like this:

ID, Name, Price
1, Stick, 5$
2, Big Box, 10$
3, Wheel, 20$
4, Bottle, 3$

New Requirements: Show price in Euro

Now we are asked to make a change to our application. The data consists of a 2-dimensional grid which already has a "price" column, containing a price in USD. We need to add a new column which shows prices in Euro in addition to those in USD, based on a predefined exchange rate. The format of the csv-file must not change because other applications work with the same file, and these other applications are not under our control.

A possible solution is to simply add the new column to the Model class. This isn't the best solution, because the Model saves all the data it exposes to the csv - and we do not want a new Euro price column in the csv. So the change to the Model would be non-trivial, and it would also be harder to describe what the Model class does, which is a code smell.

We could also make the change in the View, but our current application uses data binding to display the data directly as provided by our Model class. Because our GUI framework doesn't allow us to introduce an additional calculated column in a table when the table is data bound to a data source, we would need to make a significant change to the View to make this work, making the View a lot more complex.

Introducing the ViewModel

There is no ViewModel in the application because until now the Model presents the data in exactly the way the Csv needs it, which is also the way the View needed it. Having a ViewModel between would have been added complexity without purpose. But now that the Model no longer presents the data in the way the View needs it, we write a ViewModel. The ViewModel projects the data of the Model in such a way that the View can be simple. Previously the View class subscribed to the Model class. Now the new ViewModel class subscribes to the Model class, and exposes the Model's data to the View - with an extra column displaying the price in Euros. The View no longer knows the Model, it now only knows the ViewModel, which from the point of the View looks the same as the Model did before - except that the exposed data contains a new read only column.

New requirements: different way to format the data

The next customer request is that we should not display the data as rows in a table, but instead display the information of each item (a.k.a. row) as a card/box, and display 20 boxes on the screen in a 4x5 grid, showing 20 boxes at a time. Because we kept the logic of the View simple, we simply replace the View entirely with a new class that does as the customer desires. Of course there is another customer who preferred the old View, so we now need to support both. Because all of the common business logic already happens to be in the ViewModel that is not much of an issue. So we can solve this by renaming the View class into TableView, and writing a new CardView class that shows the data in a card format. We will also have to write some glue code, which might be a oneliner in the startup function.

New requirements: dynamic exchange rate

The next customer request is that we pull the exchange rate from the internet, rather than using a predefined exchange rate. This is the point where we revisit my earlier statement about "layers". We don't change our Model class to provide an exchange rate. Instead we write (or find) a completely independent additional class that provides the exchange rate. That new class becomes part of the model layer, and our ViewModel consolidates the information of the csv-Model and the exchange-rate-Model, which it then presents to the View. For this change the old Model class and the View class do not even have to be touched. Well, we do need to rename the Model class to CsvModel and we call the new class ExchangeRateModel.

If we hadn't introduced the ViewModel when we did but had instead waited until now to do so, the amount of work to introduce the ViewModel now would be higher because we need to remove significant amounts of functionality from both of the View and the Model and move the functionality into the ViewModel.

Afterword on Unit Tests

The primary purpose of MVVM is not that the code in the Model and the ViewModel can be put under Unit Test. The primary purpose of MVVM is that the code is broken up into classes with a small number of well defined responsibilities. One of several benefits of having code consisting of classes with a small number of well defined responsibilities is that it is easier to put the code under Unit Test. A much larger benefit is that the code is easier to understand, maintain, and modify.

这篇关于为什么要使用MVVM?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆