c# - MVVM:ViewModel 和业务逻辑连接

标签 c# wpf design-patterns mvvm

在使用 MVVM 模式完成了几个项目之后,我仍在为 ViewModel 的角色而苦苦挣扎:

我过去做过的事情: 仅将模型用作数据容器。 放置逻辑来操作 ViewModel 中的数据。 (这就是业务逻辑吗?) 缺点:逻辑不可重用。

我现在正在尝试的是: 保持 ViewModel 尽可能薄。 将所有逻辑移至模型层。 仅在 ViewModel 中保留表示逻辑。 缺点:如果在模型层内更改数据,UI 通知会非常痛苦。

所以我会给你一个例子,让它更清楚:

场景: 重命名文件的工具。 类(class): File : 代表每一个File; 规则:包含如何重命名文件的逻辑;

如果我遵循方法 1: 为文件、规则和 View 创建 ViewModel -> RenamerViewModel。 将所有逻辑放在 RenamerViewModel 中: 包含 FileViewModel 和 RuleViewModel 的列表以及处理逻辑。 简单快捷,但不可重复使用。

如果我遵循方法 2: 创建一个新的模型类 -> 重命名器,其中包含一个文件列表、规则和处理每个文件并应用每个规则的逻辑。 为文件、规则和重命名器创建 View 模型。 现在 RenamerViewModel 只包含 Renamer Model 的一个实例,加上两个 ObservableCollections 来包装 Renamer 的文件和规则列表。 但是整个逻辑都在重命名模型中。因此,如果重命名模型被触发以通过方法调用操作某些数据,则 ViewModel 不知道操作了哪些数据。 因为模型不包含任何 PropertyChange 通知,所以我会避免这种情况。 因此,业务逻辑和表示逻辑是分离的,但这使得通知 UI 变得困难。

最佳答案

将业务逻辑放在 View 模型中是一种非常糟糕的做事方式,所以我会很快说永远不要那样做,然后继续讨论第二个选项。

将逻辑放在模型中要合理得多,这是一个很好的开始方法。有什么缺点?你的问题是

So if the Renamer Model is triggered to manipulate some Data by Method Calls, the ViewModel has no Clue which Data is manipulated. Because the Model doesnt Contain any PropertyChange Notification and I will avoid that.

好吧,让您的模型实现 INotifyPropertyChanged 肯定会让您继续做更好的事情。然而,确实有时无法做到这一点——例如,模型可能是一个部分类,其中属性由工具自动生成并且不会引发更改通知。这是不幸的,但不是世界末日。

如果你想买东西,那么有人必须付钱;如果不是提供此类通知的模型,那么您只有两个选择:

  1. viewmodel 知道模型上的哪些操作(可能)会导致更改,并在每次此类操作后更新其状态。
  2. 其他人知道哪些操作会导致更改,并且他们会通知 View 模型在其包装的模型发生更改后更新其状态。

第一个选项又是一个坏主意,因为实际上它又回到了将“业务逻辑”放入 View 模型中。不如将所有业务逻辑放在 View 模型中那么糟糕,但仍然如此。

第二个选项更有希望(不幸的是需要更多的工作来实现):

  • 将您的部分业务逻辑放在单独的类(“服务”)中。该服务将通过适本地使用模型实例来实现您希望执行的所有业务操作。
  • 这意味着服务知道模型属性何时可能发生变化(这没关系:模型 + 服务 == 业务逻辑)。
  • 该服务将向所有相关方提供有关更改模型的通知;您的 View 模型将依赖于该服务并接收这些通知(这样他们就会知道“他们的”模型何时更新)。
  • 由于业务操作也是由服务实现的,这仍然很自然(例如,当在 View 模型上调用命令时, react 是在服务上调用适当的方法;请记住, View 模型本身并不知道业务逻辑)。

有关此类实现的更多信息,另请参阅我的回答 herehere .

关于c# - MVVM:ViewModel 和业务逻辑连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16338536/

相关文章:

wpf - 如何在WPF应用程序中绘制色轮?

c# - 单击按钮更新 wpf 数据网格

ruby-on-rails - Ruby on Rails Active Record 验证 "Draft"状态最佳实践

language-agnostic - 适用于其他对象集合的类的设计模式?

c# - 替换静态 AutoMapper API;替换 Profile 中的 Map 方法

c# - 如果值存在;不要输入值。 if 语句

c# - 如何使用 ASP.NET 显示来自 SQL Server 的图像?

c# - TDD——你测试了多少?

wpf - 如何监听 Co​​llectionChanged 事件并执行某些方法

javascript - JavaScript "Factory Design Pattern"中的性能优化