标准的“模型视图控制器”模式和微软的模型/视图/视图模型模式之间有区别吗?


当前回答

MVVM

视图➡视图模型➡模型

视图有对ViewModel的引用,反之则没有。 ViewModel有对模型的引用,反之则没有。 视图没有对模型的引用,反之亦然。

如果你正在使用一个控制器,它可以有一个视图和视图模型的引用,尽管控制器并不总是必要的,就像在SwiftUI中演示的那样。 数据绑定:我们为ViewModel属性创建侦听器,这样数据就可以通过视图模型从视图流向模型。虽然这些引用是单向的:View↔ViewModel↔Model,但数据需要流动:View↔ViewModel。视图如何通过读取自己的属性从模型中获取数据是很清楚的。数据绑定是如何在视图中检测事件并将它们反馈给模型。

class CustomView: UIView {
  var viewModel = MyViewModel {
    didSet {
      self.color = viewModel.viewColor
    }
  }

  convenience init(viewModel: MyViewModel) {
    self.viewModel = viewModel
  }
}


struct MyViewModel {
   var viewColor: UIColor {
      didSet {
         colorChanged?() // This is where the binding magic happens.
      }
   }
   
   var colorChanged: ((UIColor) -> Void)?
}


class MyViewController: UIViewController {

   let myViewModel = MyViewModel(viewColor: .green)
   let customView: CustomView!

   override func viewDidLoad() {
      super.viewDidLoad()

      // This is where the binder is assigned.
      myViewModel.colorChanged = { [weak self] color in 
        print("wow the color changed")
      }
      customView = CustomView(viewModel: myViewModel)
      self.view = customView
   }
}

设置的差异

业务逻辑保存在MVC的控制器中,MVVM的ViewModels中。 在MVC中,事件直接从视图传递到控制器,而在MVVM中,事件从视图传递到ViewModel再到控制器(如果有的话)。

共同的特征

MVVM和MVC都不允许视图直接向模型发送消息。 两者都有自己的模型。 两人都有自己的观点。

MVVM的优点

因为viewmodel包含业务逻辑,所以它们是更小的具体对象,便于进行单元测试。另一方面,在MVC中,业务逻辑在ViewController中。如果不同时测试所有的方法和侦听器,你怎么能相信视图控制器的单元测试是全面安全的呢?您不能完全相信单元测试结果。 在MVVM中,由于业务逻辑从控制器中被抽取到原子ViewModel单元中,ViewController的大小缩小了,这使得ViewController代码更加清晰。

MVC的优点

在控制器中提供业务逻辑减少了对分支的需求,因此语句更有可能在缓存上运行,这比将业务逻辑封装到ViewModels中性能更好。 在一个地方提供业务逻辑可以加速不需要测试的简单应用程序的开发过程。我不知道什么时候不需要检查。 对于新开发人员来说,在ViewController中提供业务逻辑更容易考虑。

其他回答

在MVVM中,控制器不会被ViewModel取代,因为ViewModel的功能与控制器完全不同。你仍然需要一个控制器,因为如果没有控制器,你的模型、视图模型和视图就做不了什么…在MVVM中你也有一个控制器,MVVM这个名字是错误的。

在我看来,MVVMC是正确的名字。

正如你所看到的,ViewModel只是MVC模式的一个附加。它将转换逻辑(例如将对象转换为字符串)从控制器移动到ViewModel。

MVVM模型-视图视图模型类似于MVC,模型-视图控制器

控制器被替换为ViewModel。ViewModel位于UI层下面。ViewModel公开视图所需的数据和命令对象。你可以把它想象成一个容器对象视图从它那里获取数据和动作。ViewModel从模型中提取数据。

Russel East写了一篇博客,详细讨论了为什么MVVM不同于MVC

让我惊讶的是,这是一个投票很高的答案,却没有提到MVVM的起源。MVVM是微软社区常用的术语,它起源于Martin Fowler的表示模型。所以要了解这个模式的动机以及与他人的不同之处,首先要阅读关于这个模式的原文。

首先,MVVM是使用XAML处理显示的MVC模式的发展。本文概述了这两者的一些方面。

模型/视图/视图模型架构的主要目的似乎是在数据(“模型”)之上,还有另一层非可视组件(“视图模型”),它将数据的概念更紧密地映射到数据的视图(“视图”)的概念。视图绑定的是ViewModel,而不是直接绑定模型。

MVVM

视图➡视图模型➡模型

视图有对ViewModel的引用,反之则没有。 ViewModel有对模型的引用,反之则没有。 视图没有对模型的引用,反之亦然。

如果你正在使用一个控制器,它可以有一个视图和视图模型的引用,尽管控制器并不总是必要的,就像在SwiftUI中演示的那样。 数据绑定:我们为ViewModel属性创建侦听器,这样数据就可以通过视图模型从视图流向模型。虽然这些引用是单向的:View↔ViewModel↔Model,但数据需要流动:View↔ViewModel。视图如何通过读取自己的属性从模型中获取数据是很清楚的。数据绑定是如何在视图中检测事件并将它们反馈给模型。

class CustomView: UIView {
  var viewModel = MyViewModel {
    didSet {
      self.color = viewModel.viewColor
    }
  }

  convenience init(viewModel: MyViewModel) {
    self.viewModel = viewModel
  }
}


struct MyViewModel {
   var viewColor: UIColor {
      didSet {
         colorChanged?() // This is where the binding magic happens.
      }
   }
   
   var colorChanged: ((UIColor) -> Void)?
}


class MyViewController: UIViewController {

   let myViewModel = MyViewModel(viewColor: .green)
   let customView: CustomView!

   override func viewDidLoad() {
      super.viewDidLoad()

      // This is where the binder is assigned.
      myViewModel.colorChanged = { [weak self] color in 
        print("wow the color changed")
      }
      customView = CustomView(viewModel: myViewModel)
      self.view = customView
   }
}

设置的差异

业务逻辑保存在MVC的控制器中,MVVM的ViewModels中。 在MVC中,事件直接从视图传递到控制器,而在MVVM中,事件从视图传递到ViewModel再到控制器(如果有的话)。

共同的特征

MVVM和MVC都不允许视图直接向模型发送消息。 两者都有自己的模型。 两人都有自己的观点。

MVVM的优点

因为viewmodel包含业务逻辑,所以它们是更小的具体对象,便于进行单元测试。另一方面,在MVC中,业务逻辑在ViewController中。如果不同时测试所有的方法和侦听器,你怎么能相信视图控制器的单元测试是全面安全的呢?您不能完全相信单元测试结果。 在MVVM中,由于业务逻辑从控制器中被抽取到原子ViewModel单元中,ViewController的大小缩小了,这使得ViewController代码更加清晰。

MVC的优点

在控制器中提供业务逻辑减少了对分支的需求,因此语句更有可能在缓存上运行,这比将业务逻辑封装到ViewModels中性能更好。 在一个地方提供业务逻辑可以加速不需要测试的简单应用程序的开发过程。我不知道什么时候不需要检查。 对于新开发人员来说,在ViewController中提供业务逻辑更容易考虑。