为什么要使用MVVM?

Mic*_*han 70 c# wpf mvvm

好的,我一直在研究MVVM模式,每次我以前尝试过调查它时,我放弃了很多原因:

  1. 不必要的超长编码
  2. 编码员没有明显的优势(我办公室没有设计师.目前只有我自己很快成为另一个编码员)
  3. 没有很多资源/文档的良好实践!(或者至少很难找到)
  4. 想不出这个有利的单一场景.

我即将再次放弃它,并认为我会问是否有人回答上述原因.

老实说,我无法看到将其用于单个/合作伙伴编码的优势.即使在具有10个窗口的复杂项目中也是如此.对我来说,DataSet是一个足够好的看法和在回答样结合布伦特以下问题

有人可以展示一个示例,与XAML DataBinding相比,使用MVVM模式可以节省时间.

我的100%绑定目前都是在XAML中完成的.因此,我不认为VM的重点是它需要编写和依赖的额外代码.

编辑:
在下午研究MVVM之后,我终于找到了一些让我从这个答案中认识到它的真正好处的东西.

Pet*_*ter 94

摘要

  • 所有模式的使用都是情境性的,并且好处(如果有的话)总是在于降低复杂性.
  • MVVM指导我们如何在GUI应用程序中的类之间分配职责.
  • ViewModel将模型中的数据投影为适合View的格式.
  • 对于琐碎的项目,MVVM是不必要的.仅使用View就足够了.
  • 对于简单的项目,可能不需要ViewModel/Model拆分,只需使用Model和View就足够了.
  • Model和ViewModel不需要从一开始就存在,并且可以在需要时引入.

何时使用模式以及何时避免使用模式

对于足够简单的应用,每种设计模式都是过度的.假设你编写了一个显示单个按钮的GUI应用程序,按下该按钮会显示"Hello world".在这种情况下,像MVC,MVP,MVVM这样的设计模式都会增加很多复杂性,而不会增加任何价值.

一般来说,引入设计模式总是一个错误的决定,因为它有点适合.应该使用设计模式来降低复杂性,或者通过直接降低总体复杂性,或者通过用熟悉的复杂性替换不熟悉的复杂性.如果设计模式无法通过这两种方式降低复杂性,请不要使用它.

要解释熟悉和不熟悉的复杂性,请采用以下2个字符序列:

  • "D.€|?重新%DFA C"
  • "CorrectHorseBatteryStaple"

虽然第二个字符序列的长度是第一个序列的两倍,但它比第一个序列更容易阅读,写入更快,更容易记忆,因为它更熟悉.对于熟悉的代码模式也是如此.

请注意,将来要使用代码的所有开发人员可能都不熟悉某些模式.就前面的例子而言,以下序列可能比上述任一序列更容易记住,也可能不容易记住,这取决于记住它的人的经验和训练:"3.14159265358979323846264338327950".在某些涉及更高级设计模式的情况下,如果维护开发人员已经熟悉它,那么使用设计模式才有意义.

MVVM

也就是说,让我们通过一个例子深入探讨MVVM的主题.MVVM指导我们如何在GUI应用程序中的类之间(或层之间 - 后面会详细介绍)之间分配职责,目标是拥有少量类,同时保持每个类的职责数量小而且定义明确.

"正确的"MVVM至少假设一个中等复杂的应用程序,它处理从"某处"获得的数据.它可以从数据库,文件,Web服务或来自无数其他来源获取数据.

在我们的例子中,我们有2类ViewModel,但没有ViewModel.它Model包装了一个csv文件,它在启动时读取,并在应用程序关闭时保存,用户对数据进行了所有更改.这View是一个Window类,它显示表中的数据Model并允许用户编辑数据.csv内容可能看起来像这样:

ID, Name, Price
1, Stick, 5$
2, Big Box, 10$
3, Wheel, 20$
4, Bottle, 3$
Run Code Online (Sandbox Code Playgroud)

新要求:以欧元显示价格

现在我们被要求对我们的申请进行更改.数据由一个二维网格组成,该网格已经有一个"价格"列,其中包含一个美元价格.我们需要添加一个新列,根据预定义的汇率显示除欧元之外的欧元价格.csv文件的格式不得更改,因为其他应用程序使用相同的文件,而这些其他应用程序不受我们控制.

一种可能的解决方案是简单地将新列添加到Model类中.这不是最好的解决方案,因为它Model会将它暴露给csv的所有数据保存 - 而且我们不希望csv中有新的Euro price列.所以Model对它的改变将是非平凡的,并且描述Model类的作用也更难,这是代码气味.

我们也可以进行更改View,但是我们当前的应用程序使用数据绑定来直接显示我们Model类提供的数据.因为当表是绑定到数据源的数据时,我们的GUI框架不允许我们在表中引入额外的计算列,所以我们需要对其进行重大更改View以使其工作,使得View更复杂.

介绍ViewModel

ViewModel应用程序中没有,因为到目前为止,Model数据的呈现方式与Csv需要的方式完全相同,这也是View所需的方式.如果ViewModel没有目的,就会增加复杂性.但是现在Model不再以View需要的方式呈现数据,我们写了一个ViewModel.ViewModel项目的数据Model以这样的方式使得View可以很简单.以前View该类订阅了Model该类.现在,新ViewModel类订阅了Model该类,并将该Model数据暴露给View- 并使用一个显示欧元价格的额外列.将View不再知道了Model,现在只知道ViewModel,从的角度View看起来一样的Model前一样-除了暴露的数据包含一个新的只读列.

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

下一个客户请求是我们不应该将数据显示为表格中的行,而是将每个项目(也称为行)的信息显示为卡片/盒子,并在屏幕上以4x5网格显示20个框,显示20个一次一箱.因为我们保持View简单的逻辑,所以我们View完全用一个新的类来代替客户所需的类.当然还有另一个客户更喜欢旧的View,所以我们现在需要支持两者.因为所有常见的业务逻辑都恰好存在于这个ViewModel问题中.因此,我们可以通过将View类重命名为TableView,并编写一个CardView以卡片格式显示数据的新类来解决此问题.我们还必须编写一些粘合代码,这可能是启动函数中的oneliner.

新要求:动态汇率

下一个客户要求是我们从互联网上提取汇率,而不是使用预定义的汇率.这就是我们重新审视我之前关于"层"的陈述的观点.我们不会改变我们的Model班级来提供汇率.相反,我们编写(或找到)一个提供汇率的完全独立的附加类.这个新类成为模型层的一部分,我们ViewModel整合了csv-Model和exchange-rate-Model的信息,然后将其呈现给View.对于此更改,甚至不必触及旧的Model类和View类.好吧,我们需要重命名Model类,CsvModel然后调用新类ExchangeRateModel.

如果我们没有引进视图模型当我们做却都不是等到现在才这样做的,工作量引进视图模型现在会更高,因为我们需要从两者的去除显著数量的功能ViewModel与移动功能进入ViewModel.

关于单元测试的后记

MVVM的主要目的不是将Model和ViewModel中的代码放在Unit Test下.MVVM的主要目的是将代码分解为具有少量明确定义的职责的类.使代码由具有少量明确定义的职责的类组成的几个好处之一是,将代码放在单元测试下更容易.更大的好处是代码更容易理解,维护和修改.

  • 我喜欢这个答案 (2认同)
  • @Peter精彩的解释! (2认同)
  • 这是一篇非常非常好的文章!很有帮助! (2认同)

Pau*_*sik 31

实施模式和遵循最佳实践通常会感觉毫无意义的追求,但是当您的老板要求您添加或调整功能时,您将成为一名皈依者.使用MVVM(以及一般的模式),您实际上可以遵循自己的代码,并在最坏的情况下,而不是数周或数月内,在几小时或几天内满足要求.(这种变化可能只是几行代码,而不是花费数周的时间来试图弄清楚在尝试添加新功能之前你是如何做到的.

跟进:模式和最佳实践实际上会减慢初始开发速度,这对管理和工程设计来说往往很难.投资回报(商业投资回报率)来自于结构良好的代码,实际上是可维护的,可扩展的和可扩展的.

例如,如果您正确地遵循MVVM,您应该能够对显示逻辑进行非常大的更改,例如交换整个视图,而不会影响数据和业务逻辑.

关于为模型使用数据集的想法:(我实际上已经为此而堕落了.)数据集似乎是在应用程序中移动模型数据的完全有效的方法.问题在于如何识别数据项.由于您的数据存储在行和列中,因此您必须按列名称或索引执行查找,以及必须过滤特定行.这些逻辑意味着必须在应用程序的布线逻辑中使用魔术字符串和数字.使用类型化数据集可以缓解一些问题但不完全.使用类型化数据集,您将远离MVVM,并在UI和数据源之间实现更紧密的耦合.

  • 谢谢,我现在决定选择MVVM.Jason Dollinger做了最好的工作,任何人都可以完成解释和演示MVVM. (3认同)

gam*_*gul 14

它可以帮助您分离GUI和程序逻辑; 混合它们会导致很难维护应用程序,特别是当您的项目随着时间的推移而增长时.


Ken*_*art 6

这里:

作为开发人员,您为什么还要关心Model-View-ViewModel模式?这种模式为WPF和Silverlight开发带来了许多好处.在你继续之前,问问自己:

  • 您是否需要与设计师共享项目,并且具有设计工作和开发工作的灵活性,几乎同时发生?
  • 您是否需要对解决方案进行彻底的单元测试?
  • 在组织内部和项目之间拥有可重用的组件对您来说很重要吗?
  • 您是否希望更灵活地更改用户界面而无需在代码库中重构其他逻辑?

如果您对这些问题中的任何一个回答"是",那么这些只是使用MVVM模型可为您的项目带来的一些好处.


Vla*_*jic 5

  • 与设计师合作更容易(不是程序员,只是使用Blend的人)
  • 代码是可测试的(单元测试)
  • 在不弄乱其余代码的情况下更改视图要容易得多
  • 在开发UI时,您可以模拟模型并开发界面而无需运行实际服务(仅使用模型中的模拟数据).然后你只需翻转标志并连接到服务.