不传递实体进行查看的好处
我经常看到人们告诉你不应该将实体传递给你的视图。他们说你应该使用 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 类作为视图更好将耦合到一个类,该类又耦合到实体的类。因此,一个方面的每一项变化都应该复制到另一个方面。从我的角度来看,“中间”对象只是为了增加复杂性,而不是真正的价值。 我知道没有“一刀切”的解决方案(有时,使用中间对象是有意义的),但我们真的需要添加这样的代码吗?真正的好处是什么?
I usually see people telling that you should not pass entities to your View. They say you should use a DTO/VO/ViewModel/AnyOtherThingYouWant instead, as using an entity would increase the coupling.
Ignoring the moments where I do need some extra logic (or I don't need all the properties), I fail to see any benefits in doing this. For example, consider the following class:
public class Contact {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
I see lots of code that creates another class, like this:
public class ContactDTO {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
use it in the View and then do this:
someMapper.Map(contactDto).To<Contact>();
I can't see how better this is than simply using the Contact class, as your View would be coupled to a class that is coupled to the entity's class. So, every change in one should be replicated into the other. From my point of view, the 'middle' object is there just to add complexity, but not real value.
I know that there's no 'one size fits all' solution (as sometimes, using the middle object would make sense), but do we really need adding code like this? What are the real benefits?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
可以这样想:视图是域的投影。它是您的商业模式的具体表示。因此,您需要使用一个视图模型来表示该投影。它可以是域模型的子集,但如果视图需要,它也可以是多个域模型的聚合。您提供的示例只是一个特定情况,由于该特定视图的要求,域模型和视图模型之间存在 1:1 映射。但这只是一种具体观点。我认为您的应用程序有许多视图和域实体的不同表示。
有许多特定于视图的事物使您的领域模型不适合,因此需要视图模型。例如验证。给定的域模型属性可能在某些视图中需要,而在另一个视图中不需要(想想创建/更新视图中的 Id 属性)。如果您不使用视图模型,但让您的“创建控制器”操作直接采用域模型,那么当您的域模型 Id 属性用“Required”属性修饰时,您将会遇到问题。
还有很多其他的例子。如果我在开发 ASP.NET MVC 应用程序时给您一个建议,那就是:始终为您的视图定义特定的视图模型,并且永远不要将域模型传递给视图或从视图中获取域模型,即使您有以下情况,这一点也是正确的:域模型和视图模型之间的 1:1 映射。
Think of it this way: a view is a projection of your domain. It's a specific representation of your business model. So you need to use a view model which will represent this projection. It could be a subset of the domain model but it could also be an aggregation of multiple domain models if the view requires it. The example you provided is just a specific case where there is a 1:1 mapping between the domain model and the view model because of the requirements of this specific view. But that's only one specific view. I suppose that your application has many views and different representations of your domain entities.
There are many view specific things that make your domain models unsuitable and thus the need of view models. For example validation. A given domain model property could be required in some view and not required on another view (think of Id property in Create/Update views). If you don't use a view model but have your Create controller action directly take the domain model you will have a problem if your domain model Id property is decorated with the Required attribute.
There are many other examples. If I had one advice to give you when developing an ASP.NET MVC application it would be this: always define specific view models for your views and never pass/take domain models to/from views and this stands true even in cases where you have a 1:1 mapping between your domain model and the view model.
所引用的方法是一种纯粹主义。如果您不需要转换(减少、合并等)您的域对象,并且它们可以在您的视图中直接使用,请使用它们 - 您可以稍后在必要时通过重构引入 DTO。
因此,您必须考虑 Darin Dimitrov 所说的内容,但请记住,DTO 和类似的工具可以让您的工作变得更轻松。我记得我参与过的一个项目 - 超过 90% 的 DTO 都是域对象的一对一副本 - 这完全没有用,只会增加维护成本。
The cited approach is a kind of purism. If you do not need to transform (reduce, merge, whatever) your domain objects and they are directly usable in your view as they are, use them - you can introduce DTO via refactoring later, when necessary.
So you have to take into consideration what Darin Dimitrov said but keep in mind that DTOs and similar are here to make your work easier. I recall one project I worked on - more than 90% of DTOs were ono-to-one copies of the domain objects - this is totally useless and only adds to the maintenance cost.