MVVM – 面试问题



模型、视图、ViewModel(MVVM 模式)都是关于指导你如何组织和构建代码以编写可维护、可测试和可扩展的应用程序。

模型 - 它仅仅持有数据,与任何业务逻辑无关。

ViewModel - 它充当模型和 ViewModel 之间的链接/连接,并使事物看起来很漂亮。

视图 - 它只保存格式化的日期,并且基本上将所有内容委托给模型。

主要好处是允许视图和模型之间真正的分离,超越实现分离以及从拥有该分离获得的效率。在现实中,这意味着当您的模型需要更改时,它可以轻松更改,而无需视图更改,反之亦然。

应用 MVVM 会产生三个关键要素 -

  • 可维护性
  • 可测试性
  • 可扩展性
  • 有些人认为,对于简单的 UI,MVVM 可能有点过头了。
  • 同样,在更大的情况下,设计 ViewModel 可能很困难。
  • 当我们有复杂的数据绑定时,调试会有点困难。

通常,模型是最容易理解的。它是客户端数据模型,支持应用程序中的视图。

  • 它由具有属性和一些变量的对象组成,用于在内存中保存数据。

  • 其中一些属性可能引用其他模型对象并创建对象图,作为一个整体,这些对象是模型对象。

  • 模型对象应该引发属性更改通知,在 WPF 中意味着数据绑定。

  • 最后一个职责是验证,这是可选的,但您可以通过使用 WPF 数据绑定验证功能(通过 INotifyDataErrorInfo/IDataErrorInfo 等接口)将验证信息嵌入到模型对象中。

视图的主要目的和职责是定义用户在屏幕上看到的内容的结构。该结构包含静态和动态部分。

  • 静态部分是 XAML 层次结构,定义了视图由其组成的控件和控件布局。

  • 动态部分就像动画或状态更改,这些更改被定义为视图的一部分。

  • MVVM 的主要目标是在视图中不应该有代码隐藏。

  • 在视图中,您至少需要构造函数和对初始化组件的调用。

  • 事件处理、操作和数据操作逻辑代码不应该在视图的代码隐藏中。

  • 还有一些其他类型的代码必须进入代码隐藏中,任何需要引用 UI 元素的代码。它本质上是视图代码。

  • ViewModel 是 MVVM 应用程序的主要点。ViewModel 的主要职责是向视图提供数据,以便视图可以将该数据放在屏幕上。

  • 它还允许用户与数据交互并更改数据。

  • ViewModel 的另一个关键职责是封装视图的交互逻辑,但这并不意味着应用程序的所有逻辑都应该进入 ViewModel。

  • 它应该能够处理适当的调用顺序,以便根据用户或视图上的任何更改做出正确的操作。

  • ViewModel 还应该管理任何导航逻辑,例如决定何时导航到不同的视图。

有两种方法可以构造视图。您可以使用其中任何一种。

  • XAML 中的视图优先构造
  • 代码隐藏中的视图优先构造

一种方法是简单地将您的 ViewModel 作为嵌套元素添加到 DataContext 属性的 setter 中,如下面的代码所示。

<UserControl.DataContext> 
   <viewModel:StudentViewModel/> 
</UserControl.DataContext>

另一种方法是,您可以通过在视图的代码隐藏中自行构造 ViewModel 来执行视图优先构造,通过使用该实例设置 DataContext 属性。

通常,DataContext 属性是在视图的构造函数方法中设置的,但您也可以将构造延迟到视图的 Load 事件触发。

using System.Windows.Controls;

namespace MVVMDemo.Views { 
   /// <summary> 
      /// Interaction logic for StudentView.xaml 
   /// </summary> 
	
   public partial class StudentView : UserControl { 
      public StudentView() { 
         InitializeComponent(); 
         this.DataContext = new MVVMDemo.ViewModel.StudentViewModel(); 
      } 
   } 
}

在代码隐藏而不是 XAML 中构造 ViewModel 的主要原因是 ViewModel 构造函数需要参数,但 XAML 解析只能在默认构造函数中定义的情况下构造元素。

ViewModelLocator 提供了一种标准、一致、声明式和松散耦合的方式来执行视图优先构造,该构造自动化了将 ViewModel 连接到视图的过程。以下是 ViewModelLocator 的高级流程。

ViewModelLocator
  • 确定正在构造哪个视图类型。
  • 识别该特定视图类型的 ViewModel。
  • 构造该 ViewModel。
  • 将视图的 DataContext 设置为 ViewModel。

数据绑定是将 MVVM 与其他 UI 分离模式(如 MVC 和 MVP)区分开来的关键特性。

数据绑定可以是单向或双向的,以便在视图和 ViewModel 之间来回传递数据。

隐式数据模板可以根据使用数据绑定呈现的数据对象的类型,自动从当前资源字典中为使用数据绑定的元素选择合适的模板。首先,您需要有一些元素绑定到数据对象。

命令模式中有两个主要参与者,调用者和接收者。

调用者

调用者是一段可以执行一些命令式逻辑的代码。通常,它是在 UI 框架上下文中用户交互的 UI 元素。但它可能只是应用程序其他地方的另一段逻辑代码。

接收者

接收者是调用者触发时要执行的逻辑。在 MVVM 的上下文中,接收者通常是您需要调用的 ViewModel 中的方法。

在调用者和接收者之间,您有一个阻碍层,它不允许调用者和接收者明确地了解彼此。这通常表示为公开给调用者的接口抽象,并且该接口的具体实现能够调用接收者。

不,如果内容块只是提供渲染某些内容到屏幕上的结构,并且不支持用户对该内容的任何输入或操作。它可能不需要单独的 ViewModel,但它可能只是一个根据父 ViewModel 公开的属性进行渲染的 XAML 块。

当您的应用程序开始接受来自最终用户的输入数据时,您需要考虑验证该输入。以确保它符合您的整体要求。

您可以使用以下 WPF 数据绑定支持的验证表达方式 -

  • 在设置属性时引发异常。
  • 实现 IDataErrorInfo 接口。
  • 实现 INotifyDataErrorInfo。
  • 使用 WPF 验证规则。

控制反转 (IoC) 和依赖注入是两种紧密相关的设计模式,容器基本上是基础设施代码的一部分,它为您执行这两种模式。IoC 模式是关于委托构造的责任,而依赖注入模式是关于向已构造的对象提供依赖项。

事件是一种编程结构,它对状态更改做出反应,通知任何已注册通知的端点。主要地,事件用于通过鼠标和键盘通知用户输入,但它们的用途并不局限于此。每当检测到状态更改时,也许是在对象加载或初始化时,可以触发事件以提醒任何感兴趣的第三方。

广告