将对象从基类转换为子类是否有效

时间:2009-06-16 14:33:16

标签: nhibernate inheritance

在我的应用程序中,我(如在许多其他应用程序中)一个名为Contact的实体,代表任何人。在最基本的层面上,这用于表示业务联系人。但是,它也可以用来代表公司的员工。并且还有一些特殊类型的员工(假设有一个名为Manager

我试图将其建模为一种有意义的继承关系。员工的姓名和地址就像联系人一样,以及一些与就业相关的属性。经理还有许多经理特定的属性。

当员工晋升为经理时,困难就出现了。可以将基类Employee转换为继承类Manager吗?感觉不对。我想我会在Manager上使用专门的构造函数来完成它。

除此之外NHibernate是否支持这种行为?是这样简单到获得员工,从员工创建经理,然后保存经理?

6 个答案:

答案 0 :(得分:16)

在这种情况下,我会继续使用组合而不是继承。如果您坚持继承,那么每次晋升或降级都会改变课程,每次雇用联系人或员工离开并成为常规联系人时。

只是说联系人有角色更容易。您可以将管理员角色添加到联系人以进行升级,并删除角色以将其激活。

答案 1 :(得分:5)

只要您的商业模式与您的域匹配,您就做得对了。

然而,听起来你应该喜欢这样的东西:

Manager Promote(Employee employee)
{
   var manager = new Manager();
   //promote your employee to a manager here
   return manager;
}

在某种工作流程中。

关于NHibernate,听起来好像是在将ORM逻辑与业务领域混合在一起。将Employee提升为Manager是一种业务域构造,因此属于您的业务模型。但是,NHibernate如何将您的员工和经理映射到您的数据库与您的业务模型无关,除了如何映射它们。但这绝对与如何将员工提升为经理无关。

答案 2 :(得分:2)

我个人会有一个基础课,其中包含所有基本内容和一系列角色 每个角色都有自己的属性和功能 优点有两个:

  • 向一个人提供或从中扮演角色很容易
  • 它将允许您的员工拥有多个角色,而无需您进行“组合课程”

如果你继续使用单一的继承性,那么很快就会使用“ManagerProgrammer”,“ProgrammerStockManager”,“ProgrammerSupport”等类来呈现你。

答案 3 :(得分:2)

是的,这是有效的。关于实施,您可以使用:

  • Manager上的静态方法:public static Manager Promote(Employee employee) { ... }
  • Manager上的专业构造函数
  • 工厂或服务类

我认为任何这些方法都是一个很好的解决方案。我个人喜欢专门的构造函数解决方案,因为它代表了现实世界:您正在从现有的Employee创建一个新的Manager。

答案 4 :(得分:0)

天儿真好,

如果您发现必须将派生类从一种类型转换为另一种派生类型,那么这就是初始设计存在问题的气味。

我的直觉是您正在错误地表示Manager对象。

回到基础,并以OO术语思考您的基类(Contact)包含Employee和Manager对象的公共元素。任何派生对象都只是基类的特化。

在这种情况下,管理员不是员工的实例吗?

Manager和Employee类都应该有一个reportsTo数据成员,它也是Employee类型。

目前唯一的区别是,Manager对象现在有一组Employee对象,这些对象是他们自己的directReports。这应该可以实现为指向Employee对象容器的指针。

我想不出任何需要将Employee对象与Manager对象分离的行为专门化。

嗯,也许在其中包含包含联系人详细信息的基类Person。

编辑抱歉,您的评论我猜我不够清楚。我所描述的并没有导致两个单独的类都直接从您的Contact类派生,因此您必须在运行时将Employee的实例更改为Manager,这是您的原始问题。

也就是说,我认为您不应该有两个派生类,即Employee和Manager,直接从您的Contact类继承。

这些公司雇用的人员类型都不是这两种情况吗?为什么要区分经理和员工?如果员工成为经理,他们不再是员工吗?

有两个派生类,一个经理和一个员工,是完全错误的恕我直言。您是否尝试过根据“isa”和“有”关系来解决问题。然后你可以看到你的基本结构是错误的。

说一个员工“isa”联系只是没有意义。更可能是员工“isa”人员和人员“有”一组联系人详细信息。

也许将Manager类派生为Employee的专业化?员工“isa”人。经理“isa”员工“是”人。

HTH

欢呼声,

答案 5 :(得分:0)

联系人是Employee的一个属性。工人(您的员工)是一个角色,经理是一个角色。工人和经理都是员工,但有角色。角色是IS IN关系,Employee是AM A关系,Contact是HAS A关系。 员工有联系人(1-1关系)每个员工一个联系人(如果他们有两部电话等,我会离题1-M) 员工是角色(M-M关系)许多员工角色很多 员工是A(M-1关系) - 许多员工,所有员工类型。

所以你正在改变角色。