MVVM 中模型的职责是什么? [英] What are the responsibilities of a model in MVVM?

查看:47
本文介绍了MVVM 中模型的职责是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于模型"应该或不应该包含什么,我一直有点困惑 - 教程和示例经常相互矛盾.到目前为止,我一直在谨慎行事,我的模型只暴露了UI 内容",例如绑定到视图的属性,以及验证逻辑.但是在模型中包含其他业务逻辑是否可以接受?

I've always been a little confused as to what a "model" should or shouldn't contain - tutorials and examples often contradict each other. So far I've been playing it safe, with my models exposing nothing more than "UI stuff", e.g. properties for binding to the view, plus validation logic. But is it acceptable to have other business logic in a model?

假设我想通过 Web 服务控制机械泵,该服务提供了以给定速度打开泵和再次关闭泵的方法.我的 UI 视图可能包括开"&关闭"按钮,加上一个文本框来设置速度.考虑到这一点,我的模型可能是这样开始的:-

Let's say I want to control a mechanical pump via a web service, which provides methods to turn the pump on at a given speed, and to turn it off again. My UI view might include "on" & "off" buttons, plus a textbox to set the speed. With this in mind, my model might start out like this:-

public class Pump
{
    public int Speed { get; set; }
}

// The real thing would implement INotifyPropertyChanged, validation, etc.

这是模型应该做的所有事情吗,或者公开打开和关闭泵的业务逻辑是否可以接受 - 作为视图模型调用的方法,或者甚至作为可以直接绑定的 ICommands到视图的按钮?或者所有这些都应该在视图模型中?

Is this all the model should be doing, or is it acceptable to expose the business logic for turning the pump on and off - either as methods for the view-model to call, or maybe even as ICommands that can be bound directly to the view's buttons? Or should all this be in the view-model?

编辑不知道为什么投反对票,因为我认为这是一个完全合理的问题.虽然网络上有许多 MVVM 教程和示例,但它们通常会提供关于什么去哪里的相互矛盾的建议,就像下面提供的答案一样.我什至最终阅读了 WPF 专家 Josh Smith 的Advanced MVVM"电子书——这本书根本没有提到模型!

Edit Not sure why the downvotes, as I think this was a perfectly reasonable question. While there are many MVVM tutorials and examples on the web, they often provide conflicting advice as to what goes where, much like the answers provided below. I even ended up reading the "Advanced MVVM" e-book by WPF expert Josh Smith - the book didn't mention models whatsoever!

无论如何,我在这里找到了一个很好的资源 对于任何想要了解 MVVM 结构的人.虽然该链接将带您进入 Microsoft 的 Prism 框架的文档,但这个特定页面都是关于 MVVM 结构的,几乎没有或没有 Prism 特定内容.我发现该页面信息量很大,至少让我放心,确认我在过去几年中所做的一切都是完全有效的——也就是说,拥有实现 INPC 和验证 (IDataErrorInfo) 的模型,并通过 VM 属性将这些模型直接绑定到视图(而不是在 VM 中复制模型属性,正如下面的一些答案所主张的那样).

Anyway, I found a good resource here for anyone who wants to undersatnd the structure of MVVM. While the link takes you into documentation for Microsoft's Prism framework, this particular page is all about MVVM structure, with little or no Prism-specifics. I found the page to be very informative and has at least put my mind at ease, confirming that what I've been doing over the last couple of years to be perfectly valid - that is, having models that implement INPC and validation (IDataErrorInfo), and binding these models directly to the view via VM properties (rather than duplicate model properties in the VM, as some answers below advocate).

推荐答案

模型的目的是建模你的领域.实体、业务逻辑、服务——这些都属于模型.与 UI 绑定的是视图模型.

Purpose of model is to model your domain. Entities, business logic, services - this all belongs to model. What binds it with UI is view model.

在您的泵示例中,Pump 类不应实现 INotifyPropertyChanged 以便在 UI 中使用它,因为它不应在 UI 中使用.这就是视图模型的作用.更合适的设计是

In your pump example, the Pump class should not implement INotifyPropertyChanged in order to utilize it in UI, because it should not be used in UI. That's the role of view model. More appropriate design would be

public class PumpService
{
   public void Start() { ... };
   public void Stop() { ... };
}

public class PumpControllerViewModel : INotifyPropertyChanged
{
    public PumpControllerViewModel(PumpService service)
    {
        StartPump = new Command(() => service.Start());
        // ...
    }
    public ICommand StartPump { get; private set; }
    public ICommand StopPump { get; private set; }
}

模型在大多数情况下几乎对 UI 不可见.视图模型经常暴露模型属性,但很少直接这样做.如果您的应用程序需要显示泵速度,则视图模型必须将其公开为可观察属性.

Model is in most cases almost invisible to UI. View model often exposes model properties, but seldom does so directly. If your application would require to display pump speed view model would have to expose it as observable property.

针对 OP 问题进行更新

(...) 如果我有一个具有许多属性的更复杂的模型,例如一个客户?(...) 您建议通过 VM 上的 observable 属性公开每个模型属性 - 这是否涉及大量重复的属性、映射代码等?

(...) what if I had a more complex model with many properties, e.g. a Customer? (...) You suggest exposing each model property via an observable property on the VM - doesn't this involve a lot of duplication of properties, mapping code, etc?

模型复杂性在这里无关紧要,是的,这种方法涉及一些代码重复(尽管在某种程度上).

Model complexity is irrelevant here and yes, such approach involes some code duplication (to some extent though).

如果您保持模型简单(DTO/POCO-simple),那么你需要做的就是重写POCO-modelINPC-查看模型.模型类的代码很少,而 VM 将处理to-the-view 通知(就其角色而言).

If you keep your model simple (DTO/POCO-simple), then all you need to do is to rewrite POCO-model to INPC-view model. Model classes would have very little code while VM would handle to-the-view notifications (as to its role).

假设最复杂的模型是通过工厂方法/构建器/服务创建的(例如,不是直接),那么视图模型也可能如此.然后你可以使用自动映射器、序列化器或任何你需要的东西来简化复制过程.

Assuming that most complex models are created via factory method/builder/service (as in, not directly), so could be the view models. And then you can utilize automappers, serializers or whatever that is you need to ease the duplication process.

您将不得不维护两个相似的类,但对于 MVVM 提供的干净分离而言,这是一个有价值的权衡.

You will have to maintain two similar classes but this is a worthy tradeoff for a clean separation MVVM offers.

这篇关于MVVM 中模型的职责是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆