2

我经常看到人们告诉你不应该将实体传递给你的视图。他们说您应该改用 DTO/VO/ViewModel/AnyOtherThingYouWant,因为使用实体会增加耦合。忽略我确实需要一些额外逻辑(或者我不需要所有属性)的时刻,我看不到这样做的任何好处。例如,考虑以下类:

public class Contact {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
}

我看到很多创建另一个类的代码,如下所示:

public class ContactDTO {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
}

在视图中使用它,然后执行以下操作:

someMapper.Map(contactDto).To<Contact>();

我看不出这比简单地使用 Contact 类有多好,因为您的 View 将耦合到一个耦合到实体类的类。因此,一个中的每一个更改都应该复制到另一个中。从我的角度来看,“中间”对象只是为了增加复杂性,而不是真正的价值。我知道没有“一刀切”的解决方案(有时,使用中间对象会很有意义),但我们真的需要添加这样的代码吗?真正的好处是什么?

4

2 回答 2

4

可以这样想:视图是您的领域的投影。它是您的业务模型的特定表示。所以你需要使用一个视图模型来代表这个投影。它可以是域模型的一个子集,但如果视图需要,它也可以是多个域模型的聚合。您提供的示例只是一个特定情况,由于此特定视图的要求,域模型和视图模型之间存在 1:1 映射。但这只是一种具体的看法。我想您的应用程序有许多视图和您的域实体的不同表示。

有许多特定于视图的事物使您的域模型不合适,因此需要视图模型。例如验证。在某些视图中可能需要给定的域模型属性,而在另一个视图中不需要(想想创建/更新视图中的 Id 属性)。如果您不使用视图模型,而是让您的 Create 控制器操作直接采用域模型,那么如果您的域模型 Id 属性装饰有 Required 属性,那么您将遇到问题。

还有很多其他的例子。如果我在开发 ASP.NET MVC 应用程序时给您一个建议,那就是:始终为您的视图定义特定的视图模型,并且永远不要将域模型传递到视图/从视图传递/获取域模型,即使您有域模型和视图模型之间的 1:1 映射。

于 2011-10-23T20:06:58.727 回答
3

引用的方法是一种纯粹主义。如果您不需要转换(减少、合并等)您的域对象并且它们可以直接在您的视图中使用,请使用它们 - 您可以稍后在必要时通过重构引入 DTO

因此,您必须考虑 Darin Dimitrov 所说的内容,但请记住,DTO 和类似的东西可以让您的工作更轻松。我记得我从事的一个项目——超过 90% 的 DTO 是域对象的一对一副本——这完全没用,只会增加维护成本。

于 2011-10-24T10:15:12.713 回答