关于WPF中MVVM的思考:OnPropertyChanged到底写在哪里

您所在的位置:网站首页 mvvm的意思 关于WPF中MVVM的思考:OnPropertyChanged到底写在哪里

关于WPF中MVVM的思考:OnPropertyChanged到底写在哪里

2024-01-20 04:04| 来源: 网络整理| 查看: 265

关于WPF中MVVM的思考:OnPropertyChanged到底写在哪里,业务逻辑写在哪里 通常的MVVM模式是如何设计的

首先根据网上很多的博客、教程以及MSDN官方的描述,我理解的MVVM的理念将程序代码分成了几个部分:

View层:即对应.xaml文件ViewModel层:与xaml文件这个窗体/Page/UserControl对应的一个类Model层:纯数据类

网上大多数教程中(比如这篇和这篇),都是根据View(也可能根据Model)来设计ViewModel,即根据View有哪些控件、展示哪些数据,然后给ViewModel这个类增加对应的属性,在属性访问器中控制Model层,最后在View中写绑定,将View控件的属性绑定到ViewModel的属性:

在set访问器中更新对应的Model类对象的属性,同时调用OnPropertyChanged通知View在get访问器中返回Model类对象的属性在View中将View元素的依赖属性绑定到ViewModel的属性,并设置绑定模式为双向/单向绑定在View中(xaml中或者View的构造函数中)让ViewModel的实例作为View的DataContext

通过上述这种方式,就能实现修改ViewModwl实例的属性时,即可修改View的属性实现界面的更新;同时,如果是双向绑定,还可以在界面更新值后自动地更新到Model的属性。以上的MVVM的设计模式,OnPropertyChanged是写在ViewModel类的属性的set方法中的。

业务逻辑写在哪里

以上的MVVM设计描述,看起来没有什么问题,看到的网上的示例大多也是这样写的,View和Model实现了分离,ViewModel又类似胶水一样,把View和Model粘连了起来。然而,实际的项目中都有复杂的业务逻辑,绝不可能仅仅至少View和Model的数据交互,还有其他很多的业务逻辑,比如Model要进行持久化处理,Model的属性要有各种逻辑处理等等。

那么问题来了,业务逻辑写在哪里呢?

我在网上看到包括微软官方的看法是,业务逻辑的功能代码写在Model里面(例如微软官方文档),还有少部分的看法是业务逻辑的代码写在ViewModel里面,还有一种看法是保留MVC思想中的C,写在C里面。

这就很有意思了,先说一下这种情况——业务逻辑的这部分代码要修改Model的属性(如修改Model的是一个float属性)然后做持久化,然后还要在界面展示修改后的结果(展示这个修改后的float属性),面对这种情况的时候,如何实现?归纳一下这种情况可能的解决办法和面临的问题:

业务逻辑代码块BLogic,在修改View显示和Model时,通过修改ViewModel属性的方式实现,可能的设计方式是: Blogic聚合了ViewModel:即ViewModel作为Blogic的一个属性/字段,那么在哪里实例化ViewModel并同时使其作为Blogic的一个属性和View的DataContext?而且通常业务逻辑都是操作Model的,这里平白无故变成了操作ViewModel,同时还将业务逻辑和界面逻辑的代码耦合起来了,这并不合理。ViewModel聚合了Blogic:即Blogic作为ViewModel的一个属性/字段,其实这种方式仍然不合理,明显将ViewModel和业务逻辑耦合起来了,且Blogic在这种模式下并不好处理ViewModel的属性,至少不能直接访问。ViewModel直接包含业务逻辑的代码,然后在ViewModel类内部直接修改ViewModel类本身的属性。这会面临一个问题,那就是业务逻辑代码量特别大的时候,ViewModel非常臃肿,并且业务逻辑这部分的代码不利于重用,不利于程序分层。 业务逻辑代码块BLogic,在修改View显示和Model时,不通过修改ViewModel属性的方式实现——如果不通过修改ViewModel属性的方式实现,那么如何实现呢Model和View显示的同步呢? OnPropertyChange写在哪里

实际上,上述的问题更具体一点的表述是——OnPropertyChanged这个事件在哪里调用?OnPropertyChanged写在哪里?

基本上网上的例子都是写在了ViewModel类的属性set方法中,这就限制了对于Model的数据更新和界面显示的更新只能通过修改ViewModel的方式实现——否则无法实现自动地通知界面和Model。但如前面的讨论可知,很多业务逻辑对Model进行修改时,不宜通过修改ViewModel的属性的方式来进行。

那么OnPropertyChange写在Model的属性里面行不行?是的,我就是这么干了。

其实我个人还没有实质性地体会到MVVM带来的这种设计模式上的优势,比如说的View和后台代码的强分离的优势,可能和我目前开发的项目有关系。不仅如此,实际上在强套MVVM的时候,我还遇到到很多的让人不舒服的地方——以WPF的开发为例。xaml中写的绑定路径是字符串,和后台的类的属性对应,但并没有强相关,如果我修改了后台ViewModel类的属性名称时,绑定路径还得去修改——没法自动修改;然后就是代码阅读上没有那么方便,以命令绑定为例,加入需要查看一个按钮的Click事件的代码时,我得去ViewModel中找到对应的命令属性,然后再找它对应的方法——而没有使用命令绑定的方式时,而不适用命令绑定的方式时我在xaml中直接选中按钮的Click事件这个Attribute的值按F12即可跳转到那个事件的处理代码,而使用命令绑定时还得自己找。还有一个问题就是,ViewModel的存在,实际上增加了不少的代码量,并且xaml中也要写很多的绑定代码,事件绑定时还得写很多的传递参数,其实挺头疼的。

可能是因为目前的理解有限,我确实无法解决前述的那业务逻辑和M、V、VM的关系的问题,所以我倾向于——不要强行套MVVM的模式。我选择在Model层中调用OnPropertyChange通知界面更新,然后在ViewModel中组合Model作为对象属性,在View层中写绑定路径时,写成ViewModel的属性的属性的形式。这种方式实际上大大削弱了ViewModel的胶水的作用,似乎也不符合MVVM的设计思想,也把Model搞得很复杂,或者说Model不再纯粹了——但这种写法保证了ViewModel和业务逻辑的代码的分离。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3