MVVM – 面试问题

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

模型 − 它仅保存数据,与任何业务逻辑无关。

视图模型 − 它充当模型和视图模型之间的链接/连接,并使内容看起来很漂亮。

视图 −它只是保存格式化的日期,并将所有内容委托给模型。

主要好处是允许视图和模型之间实现真正的分离,而不仅仅是实现分离以及由此获得的效率。实际上,这意味着当您的模型需要更改时,可以轻松更改它而无需更改视图,反之亦然。

应用 MVVM 有三个关键点 −

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

一般来说,model 是最容易理解的。它是支持应用程序中的视图的客户端数据模型。

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

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

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

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

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

  • 静态部分是定义视图所包含的控件和控件布局的 XAML 层次结构。

  • 动态部分类似于定义为视图一部分的动画或状态更改。

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

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

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

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

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

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

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

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

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

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

  • XAML 中的视图首次构造
  • 代码隐藏中的视图首次构造

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

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

另一种方法是,您可以通过在视图的代码隐藏中自行构建视图模型,并使用实例在那里设置 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 的主要原因是视图模型构造函数接受参数,但 XAML 解析只能构造在默认构造函数中定义的元素。

ViewModelLocator 提供了一种标准、一致、声明性和松散耦合的方式来进行视图首次构造,从而自动完成将 ViewModel 连接到视图的过程。以下是 ViewModelLocator 的高级流程。

ViewModelLocator
  • 确定正在构建哪种 View 类型。
  • 识别该特定 View 类型的 ViewModel。
  • 构建该 ViewModel。
  • 将 Views DataContext 设置为 ViewModel。

数据绑定是 MVVM 与其他 UI 分离模式(如 MVC 和 MVP)之间的主要区别。

数据绑定可以是 OneWay 或 TwoWay,以便在 View 和 ViewModel 之间来回流动数据。

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

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

调用者

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

接收者

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

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

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

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

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

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

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

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