MVVM: 变更通知是否模糊了模型和视图模型之间的分离?

5
假设我有一个模型,它公开了一个对象集合,我将在GUI中显示和更改这些对象。
因此,我们有一个公开了ModelItem集合的Model。
View绑定到一个ViewModel,该ViewModel公开了一个ObservableCollection of ViewModelItem。ViewModelItem是ModelItem的ViewModel。
View包含一个ListBox和一个DataTemplate,DataTemplate用于ViewModelItem类型的项。View DataContext指向ViewModel实例。ListBox绑定到ObservableCollection。
我控制所有代码。
到目前为止都很简单。问题:
将Model上的集合公开为ObservableCollection是否可接受?进一步地,是否在Model和ModelItem上实现INotifyPropertyChanged可接受?
我的担忧是我正在混淆Model和ViewModel之间的分离,但常识告诉我,这是一种通知模型元素更改的机制,让我们使用它...
只是想从其他人那里得到一些看法。
谢谢

你想让用户在视图内操作数据,还是只想展示它? - Martin Hennings
我的个人经验是,MVVM 不应该被过度推广。保持务实,否则你会过度设计整个项目。 - Nicolas Repiquet
抱歉,是的,数据将可以通过视图进行编辑。 - Ian
4个回答

5
短回答:是的。 当你需要通知更改时,请使用模型上的通知接口。 不要担心混淆代码。务实一些。
长回答:我的哲学是这样的:在实现MVVM时,当没有其他事情要做时,直接绑定到模型对象。 当您需要新功能(视图将使用的属性,行为等)时,则在ViewModel对象中包装模型对象。仅代表数据从模型传递的ViewModel只是额外的代码。但是,当您需要对该数据进行超出模型对象提供的操作时,就会引入该层。
因此,为了进一步扩展我的想法(并直接回答您的问题),需要一种方法让模型告诉ViewModel发生了什么变化。通常,模型数据是不可变的,因此不需要此通知机制,因此它是不必要的。但是,通常情况下,模型确实会发生变化。发生这种情况时,模型有两个选择:使用自定义通知方法(事件,委托等)或使用INotifyPropertyChanged。
如果您查看INotifyPropertyChanged的命名空间,则在System.ComponentModel中,而不是在视图中,因此我喜欢在模型中使用它。它是一个众所周知的接口,您可以使用它直接从视图绑定到模型。无需实现任何不同的内容。
进一步将这种哲学带入,ObservableCollection是在System.Collections.ObjectModel中 - 也不是视图特定的 - 它实现了System.Collections.Specialized.INotifyCollectionChanged,这也不是视图特定的。换句话说,ObservableCollection旨在成为一个通知其观察者更改的集合。如果您有需要这样做的模型,则ObservableCollection是您的工具。恰好WPF和Silverlight使用这些接口进行数据绑定,这只是方便(虽然并非偶然)。
我想这是一种长篇大论的方式:“是的。 当您需要通知更改时,请使用模型上的通知接口。 不要担心混淆代码。务实一些。”

3

同时进行两者是完全可以接受的。我甚至会说,这是必须的。你的常识能力已经足够好了。:)

我只想补充一点,如果你的 ModelItem 不需要所有 MVVM 功能,那么你可以通过公开 ObservableCollection<ModelItem> 而不是 ObservableCollection<ViewModelItem> 来简化代码,再修改你的 DataTemplate 就可以了。这将为你节省相当多的 "准备" 代码,所以请权衡利弊。


知道这点很好。我不确定是什么原因导致了不安的感觉,可能是我预计某些地方会有半成品或需要可疑的解决方法。总之,肯定是有一些隐藏的要点。到目前为止,WPF一直非常顺畅且没有任何问题 :) - Ian

2
如果数据模型需要变更通知,那么在数据模型中使用变更通知是完全可以接受的。但是仅因为用户界面需要变更通知而在数据模型中使用变更通知则是值得怀疑的。
一般来说,我会将数据模型的设计看作没有用户界面,并将视图模型作为一个抽象层,用于从用户界面隐藏数据模型的实现细节。另一方面,在动态应用程序中,如果需要变更通知,则往往有足够普遍的需求将其放入数据模型中才更合理。

实际上,这个和DanDan的回答都很有趣。我没有提供太多细节,因为我想要一般性的指导,但我认为我在示意视图的工作是管理模型的表示和更新。编辑:哎呀,按了回车。所以在这种情况下,底层模型和视图之间存在紧密联系。我会反驳DanDan的观点,如果我的模型实现了一个提供Observerable集合的接口,那么实现该接口的任何模型都可以互换。这只是一个例子,而不是硬性规定。 - Ian
1
我正在开发的一个应用程序具有非常动态的数据模型,完全是为了支持UI而设计的。在这种情况下,我在模型中放置更改通知没有任何问题,因为向UI提供信息是模型的主要目的。在这种情况下,我的模型设计准则不是“如果UI不存在,我会设计得不同吗?”而是“如果UI是WinForms,我会设计得不同吗?” - Robert Rossney

1
不行。这太糟糕了。你的模型不应该知道它是如何被使用的。给它这种知识会违背MVVM的初衷。
模型永远不应该知道它是被WPF、WinForms、DOS控制台、服务或库使用的。如果你告诉它这个,那么你就错了。 它还应该是框架无关的,不管它是MVVM、MVC还是MXXX的一部分!

我完全不同意,因为将这些元素添加到数据模型中既实用又正常,它们不是UI特定的,也不是与UI相关的构造。 - Firoso

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接