MVVM架构中数据保存逻辑归属与用户保存请求触发方式咨询
问题1解答
数据持久化(保存/加载)逻辑不要放在Model或ViewModel中,单独抽一层独立的持久化服务是最优方案。
- Model的职责是承载业务数据和核心业务逻辑,和存储逻辑耦合之后,后续更换存储方案(比如从本地Json文件换成SQLite数据库)还要修改Model代码,违反单一职责原则。
- ViewModel的职责是处理展示逻辑,把存储代码塞进去会导致代码复用性极差,其他页面需要相同存储能力时只能复制粘贴,还会让VM代码变得臃肿难维护。
- 独立的持久化服务只需要定义好通用的
Save()、Load()接口,具体实现全部封装在服务内部,和MVVM三层完全解耦,替换存储方案时只需要改服务实现,上层代码完全不用动。
关于你补充的疑问:必须始终保持V、VM、M三层的数据同步。你要搞清楚两个概念的区别:「不实时持久化到磁盘」和「不更新Model数据」完全是两码事。正常流程就是用户在View输入的内容通过绑定实时更新VM属性,VM同步更新关联的Model数据,Model永远保存最新的业务状态,只是你不触发保存操作时,不会把Model里的内容写到磁盘而已。如果攒着修改不更新Model,中途有其他业务逻辑读取Model数据的时候拿到的就是旧值,反而会产生莫名其妙的bug。
问题2解答
View通知触发保存操作,用ICommand是WPF MVVM体系下最标准的实现方式,完全没问题。你只需要在ViewModel中定义一个SaveCommand,把它绑定到View的保存按钮的Command属性即可,用户点击按钮时会自动触发Command对应的执行逻辑。
不需要额外做什么独立的Controller,你只需要把前面提到的持久化服务实例,通过依赖注入的方式传入ViewModel即可:
- 在App.xaml.cs中注册持久化服务和各个ViewModel的依赖关系,创建ViewModel实例的时候自动把持久化服务注入进去
- SaveCommand触发时,直接调用持久化服务的Save方法,把当前ViewModel关联的最新Model实例传进去即可。
持久化服务本身不需要感知任何MVVM组件,它只负责接收业务对象做存储、或者返回读取到的业务对象,和三层完全解耦,不需要做静态类,用依赖注入管理生命周期即可,后续做单元测试的时候也可以很方便的Mock这个服务。
内容的提问来源于stack exchange,提问作者Commonaught
相关产品推荐
相关产品推荐

