PersonViewModel继承自Person - 聪明或代码味道?

dev*_*xer 2 c# asp.net-mvc design-patterns

在我的ASP.NET应用程序中,我有一个Person和一个PersonViewModel.

Person是由...生成的LinqToSql.它具有将保留在数据库中的属性.

PersonViewModel已经拥有了一切Person,加上一对"选择列表",它们将用于填充组合框,以及一个FormattedPhoneNumber(基本上是PhoneNumber添加了破折号和括号).

我最初只是在我身上制作Person了一个属性PersonViewModel,但我认为这意味着页面必须"知道"某些东西是Person属性还是PersonViewModel属性.例如,对于name,视图将请求pvm.Person.Name,但对于电话号码,视图将请求pvm.FormattedPhoneNumber.如果我使用继承,那么视图所需的所有内容将始终是视图模型的直接属性pvm.Name.

这听起来不错,但是,这里没有真正的"是一种"关系(也就是说,我认为说"a PersonViewModel a "并不是真的有意义Person,而且它似乎面对"偏爱作文"但仍然,我很难想到一个场景,我需要能够换掉Person其他东西.如果我这样做,它将不再是一个PersonViewModel.

怎么说你?继承Person或保留Person为属性(或完全不同的东西)?为什么?

更新

感谢所有的答案.

看起来遗传的想法几乎被普遍拒绝,并且出于某些合理的原因:

  1. 解耦类允许ViewModel包含所需的域模型的属性,以及任何其他属性.通过继承,您可以自然地从域模型中公开所有公共属性,这可能不是一个好主意.

  2. ViewModel不会自动需要改变,只是因为域模型改变.

  3. 正如Jay提到的那样,解耦ViewModel便于查看特定的验证.

  4. 正如Kieth所提到的,使用Mapper(例如AutoMapper)可以消除在映射类之间的公共属性时的大量繁琐工作.

Gre*_*ech 8

从对象派生意味着"是一种"关系.所以在这种情况下你会有效地说a PersonViewModel是a Person.看起来这不太可能是你真正想传达的语义,所以在这里使用组合而不是继承.

实际上它可能并没有真正影响应用程序的可维护性(除了在这里和那里有更多的点),但使用组合对我来说当然感觉更清洁.另外,如果它是a,PersonViewModel那么大概该视图应该知道它正在处理的类型.


Jay*_*Jay 6

创建Person一个私有成员,并公开您的视图所需的属性PersonViewModel,即使这些属性只是通过相应的属性Person.

pvm.Person.Name 这是代码味道.


编辑:

您还限制自己在域模型中进行客户端验证和/或验证,后者意味着如果您为Person创建第二个或后续ViewModel,则无法更改Person成员的验证.(嗯,你可以,但这违反了开放封闭原则,你将视图问题引入域中.)通过从视图中隐藏域对象,你可以给自己一个干净的空间来执行用例 - 在对域对象进行更改之前进行特定验证.域对象可能有自己的一组验证器,但它们可以严格适用于域,而不会出现特定于视图的问题.