负责保存数据的是ViewModel还是View

Is the ViewModel or the View responsible for saving data

我不认为这些是重复的:

我正在创建本地应用程序。用户输入的数据要么存储在本地文件中,要么存储在本地托管的数据库中。我想弄清楚我应该如何构造数据的保存。如果相关,我希望数据仅在用户请求保存时保存(即我不想每次存储在模型中的数据发生更改时都写入 DB/file)。

[旁注建议V、VM、M都保持同步,是吗?您不想只是偶尔更新模型,对吗?]

按照 this article and this question 中的定义,模型包含 business/application 逻辑和数据,而 ViewModel 包含表示逻辑并将模型中的数据转换为可表示的形式。管理(例如储蓄)似乎不太适合这两​​个类别。

问题一 如果保存功能(以及在应用程序启动时加载数据)只是在 ViewModel、Model 或其他实体中,则称其为 Controller,因为找不到更好的词。

问题二 我了解 WPF 和 MVVM,并且对(/不确定)应用程序非常感兴趣 structure/architecture。 View 应如何通知 ViewModel/Model/Controller 用户已请求保存?命令是正确的工具吗(我不熟悉命令,或者我刚刚阅读了一些关于它们的内容)。 如果 Controller 是一个不错的选择,它将具有什么结构,它需要了解哪些 MVVM 组件(或者它是否对所有组件视而不见)。它将在哪里构建(可能在 App.xaml.cs 中?)还是静态对象?

在我看来,您对不同模式的术语有点困惑。

如果我们考虑 APPLICATIONS(MVC、MVP、MVVM)的 OOP 模式,那么其中 View 是 GUI,而 Model 是处理实际数据、处理数据并包含业务逻辑的层。
该层是通用的,与所使用的 GUI 类型无关,甚至与它的存在与否无关。
从这些模式的角度来看,任何对真实数据的操作(包括保存数据)都是模型的功能。
但是Model本身并不是一个特定的类型,而是一个完整的Application层,甚至可以在另一个Application中单独实现(例如后台服务运行,没有任何GUI)。
因此,模型本身可以以许多附加类型的形式实现:一个带有业务逻辑的核心(在它下面,它们最常指的是狭义的模型)、存储库、服务等

在某些模式(ADO、EF 等)中,术语模型也用于表示某些实体,这一事实引入了一些混淆。
假设这通常用于表示反映数据库中记录的类型 EF table。
从MVC/MVP/MVVM模式来看,这些不是模型,而是实体:Database Entity、EF Entity、Business Entity等

该模型为消费者提供的不是真实数据(即不是业务实体),而是它们的某种反映(通常这些是 immutable DTO)。

因此,您的问题的答案是:保存数据是必须仅在模型中实现的功能。 “在自身内部”,模型可以将其委托给它的一些独立部分,例如存储库。

ViewModel 也是一种模型。但它被设计为与某种类型的视图一起工作,因此它必须考虑到这种类型的视图的特殊性,它的要求。
例如,WPF 的 ViewModel(几乎总是如此)必须在其属性中提供视图所需的数据,使用 INotifyPropertyChanged、INotifyCollectionChanged、Icommand、IDataErrorInfo 接口和其他要求通知其状态的变化。
在这种情况下,“真实”模型充当 ViewModel 的数据提供者。 因此,ViewModel 不处理真实​​数据,而是处理其抽象反射。
ViewModel 无法获得有关真实数据的“知识”(包括存储方式和存储位置)。

由于您需要在 GUI 中为用户提供一种显式保存数据的方式,因此必须在 ViewModel 中将其实现为命令,在其执行方法中调用所需的 Model 方法。
在这种情况下,模型意味着整个对应层。
也就是说,它不一定是业务逻辑模型的主要部分。
例如,它可以是模型层中的某种服务。

应该理解,在实践中经常会偏离理想的 MVVM 实现。因此,在实践中,您经常可以从视图端和模型端看到非特定功能的 ViewModel 泄漏。
即使你不得不这样做来简化实现,那么你也必须清楚地认识到这是对MVVM的一种背离,虽然你在ViewModel中实现了一些特定的功能,但实际上它是Model(或View)的一个功能。

关于你的第二个问题。
MVVM模式是分层的:顶层是View,下面是ViewModel,最底层是Model。
在这样的层次结构中,上层只拥有底层的知识。
也就是说,View 只“熟悉”ViewModel,而 ViewModel 只“熟悉”Model。
通常,模型不“认识”任何人。
应用程序本身(App class)不是 MVVM 模式的一部分。 它位于所有层之上,因此“了解每个人”。
通常,在应用程序中(可能不在 App class,但在这个级别),初始化层,创建和注入依赖项,以及其他任务对于整个应用程序是通用的。

.Net 中的“通知”是指事件。
要接收某人的通知,您需要订阅此对象的事件。
为此,您需要对其“熟悉”,即对它有一个link。
但是下层不熟悉上层。
因此,无论是ViewModel,更不用说Model,都无法订阅View事件。

但是View不需要这样的通知。
在对象想要提供有关其更改的信息但不知道谁需要它的地方需要通知。
想要接收此类信息的人自己订阅对象的事件。

但是视图“知道”它想通知谁 - 这就是 ViewModel。
因此,View 只需调用所需的 ViewModel 方法并将所需的参数传递给它即可。
这在 WPF 中最常见,方法是绑定到 ViewModel 中的命令-属性。

P.S. 这篇文章 "The Model-View-ViewModel Pattern" 提出的观点与我在这里陈述的观点非常接近,但更详细.
阅读它可能会对您有所帮助。

引用这篇文章:

Model
Model classes are non-visual classes that encapsulate the app's data. Therefore, the model can be thought of as representing the app's domain model, which usually includes a data model along with business and validation logic. Examples of model objects include data transfer objects (DTOs), Plain Old CLR Objects (POCOs), and generated entity and proxy objects.
Model classes are typically used in conjunction with services or repositories that encapsulate data access and caching.