【问题标题】:(MVVM) View Model per View or per Model?(MVVM)每个视图或每个模型的视图模型?
【发布时间】:2019-10-03 10:04:30
【问题描述】:

:)

在过去的几周里,我观看并阅读了许多 MVVM 材料,似乎每个人都以一种或另一种方式做了一个重大差异,但没有详细说明。我们是为每个视图还是每个模型创建一个 ViewModel?

有一个问题,但我不认为它是answered。所以..

让我们以一个食谱应用为例,我们有三个不同的视图:RecipesViewController、RecipeViewController 和 RecipeCell。我认为实现 MVVM 的正确方法是为每个视图创建一个 ViewModel,而不是创建一个 RecipeModel 并在它们之间共享。

这个例子可能足够基本,我们可能更喜欢一个 ViewModel,但它不正确,是吗?如果两者都可以接受,有人可以解释它们的区别、缺点和好处吗?如果我们有一个网络层,那么只有 ViewModel 应该与之通信,对吧?

谢谢。

【问题讨论】:

    标签: ios design-patterns mvvm


    【解决方案1】:

    当人们确实以正确的方式来实现它们时,模式和架构可能很难理解。

    它们只是指导方针。它们为您提供职责分离,您作为开发人员根据您的问题决定如何应用它们。以一种方式做它们可能比以另一种方式做它们更难,仅此而已。

    模式无法解决您将遇到的所有问题。

    从实践中人们发现,在大多数情况下,View 与单个 ViewModel 通信会更好。我的经验证明,这确实使您的逻辑更清晰,因为更改几个ViewModel 可能会破坏单个View,并且调试和跟踪正在发生的事情可能会更加困难。如果您确实需要在属于单个ViewModelViews 之间共享某些状态和/或逻辑,请考虑如何拥有两个ViewModels 而不是一个并添加一个Model 来共享该状态和逻辑以及让ViewModels 共享该对象。

    一个ViewModel 可以与多个Views 通信(而每个视图都有一个视图模型)。大多数情况下,如果您可以创建一个 ViewModel 与单个 View 进行通信,他们就会这样做。它使事情变得更容易。

    对于复杂的相互关联的逻辑,有时每个View 都有一个ViewModel 可能更难做到。通常,您会将ViewModel 划分为层次结构,其中您将拥有一个ParentViewModel 和几个更​​细粒度的ChildViewModels。但是这些ChildViewModels 可能必须与它们的父级或彼此之间进行通信。通过将ViewModels 分解为层次结构,您可以为视图实现单个ViewModel,但如果您不能不强迫自己。有时不做会更简单。

    至少不要一开始就尝试为View 设置一个ViewModel。使用迭代方法和重构。制作一个更大的ViewModel 并将其连接到不同的Views。稍后重构您的方式,将MainViewModel 分解为更小的部分,并尝试让它们以更少的视图进行交流。

    ViewModels 之间共享一个Model 非常好。我认为Models 可能是未被充分利用的东西。人们确实尝试向 ViewModels 添加更多逻辑,从而在它们之间创建耦合,而他们应该改用 Models

    您需要考虑的一件重要事情是 PresentationModel 的划分。在您的模型上工作更多,您将看到巨大的好处。

    如果您的示例应该有一个Recipe 模型,因为Recipe 是您的DomainModel,并且应该具有与配方相关的数据和行为。然后您将拥有一个RecipeViewModel,并且是您的演示文稿 的一部分,并且拥有Recipe 的演示逻辑。然后,您的 RecipeView 将与 RecipeViewModel 挂钩,RecipeViewModel 负责拥有表示 Recipe 如何呈现的实际 GUI 小部件对用户做出反应并调整它的小部件/控件以适应RecipeViewModel中的变化。

    在 MVVM 中,Views 通常不与Models 通信。他们确实与ViewModels 通信,然后与Models 通信。

    我看到的一个大问题是人们将Models 视为他们存储到数据库中的东西,而将其他所有内容(ViewsViewModelsServices 等)视为应用程序。这是一个很大的缺陷。如果您还没有阅读Domain Driven Design,我强烈推荐它,因为它详细解释了拥有良好Models 的价值。

    这里有一些资源:

    【讨论】:

      猜你喜欢
      • 2012-03-13
      • 1970-01-01
      • 2014-10-24
      • 2013-05-27
      • 2022-07-13
      • 1970-01-01
      • 2012-07-31
      • 2010-12-07
      • 1970-01-01
      相关资源
      最近更新 更多