2009-06-16 102 views
13

在我的应用程序中(如许多其他应用程序中),此实例名称为Contact,它代表任何人。在最基本的层面上,这是用来代表业务联系人。但它也可以用来代表公司的员工。还有一些特殊类型的员工(假设有一个叫Manager是否有效将对象从基类转换为子类

我试图将此模型作为一种继承关系进行建模,这是有道理的。员工的姓名和地址就像联系人一样,还有一些与就业相关的属性。经理也有一些经理特定的属性。

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

NHibernate支持这种行为呢?就像获得员工,从员工创建经理,然后保存经理一样简单?

回答

5

只要您的商业模式与您的域名匹配,您就可以做正确的事情。

然而,这听起来像你对我应该是这样的:

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

某种形式的一些工作流程中。

关于NHibernate,这听起来像是你的ORM逻辑与你的业务领域混合在一起。将员工晋升为经理是一个业务领域构造,因此属于您的业务模型。但是,除了如何映射它们外,NHibernate如何将您的员工和管理人员映射到数据库中与您的业务模型无关。不过,这绝对与如何向员工推销员工毫无关系。

+0

NHibernate的问题只是为了找出NHibernate是否会抱怨将对象作为基类保存为子类。 – 2009-06-16 15:19:19

2

我个人会拥有一个包含所有基本事物和角色列表的基类。
每个角色都有自己的属性和功能。
优点是双重的:

  • 可以很容易地给予或采取从一个人一个角色/
  • 它将使你的人拥有多个角色,而您不必做“组合类”

如果你去单inherritance与inherritance会很快使你喜欢“ManagerProgrammer”类,“ProgrammerStockManager”,“ProgrammerSupport”

16

我会跟组成投奔inheri在这种情况下。如果你坚持继承,你将会在每次晋升或降级时改变课程,并且每次你雇用一名联系人或一名雇员离开并成为常规联系人。

只说联系人具有角色就更简单了。您可以向联系人添加管理员角色以将其提升并删除角色以将其启动。

+1

这应该被标记为正确的答案 – Pierreten 2010-04-23 05:51:18

0

天儿真好,

如果你发现你有一个派生类中从一种类型转变成另一种派生类型然后就是,最初的设计有问题的气味。

我的直觉就是你不正确地表示一个Manager对象。

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

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

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

我现在看到的唯一区别是Manager对象现在有一个Employee对象的集合,它们是它们自己的directReports。这应该可以实现为一个指向Employee对象的容器的指针。

我不能想到需要从Manager对象中分离出Employee对象的行为中的任何专业化。

嗯,也许使基类包含联系人详细信息的人。

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

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

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

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

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

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

HTH

欢呼声,

+0

对不起,这并没有真正的帮助。你说我不正确地代表一个经理,然后继续准确地描述我的建议。 – 2009-06-16 15:21:30

+0

对不起。你仍然在描述我已经拥有的东西。来自Contact - > Employee - > Manager的继承。一个人和一个联系人之间的语义差异是相互关联的。问题在于这种继承,可以将员工转换为员工的子类(经理)。 – 2009-06-22 09:20:20

2

是的,它是有效的。在关于实施,你可以使用:对经理

  • 静态方法:对经理public static Manager Promote(Employee employee) { ... }
  • 专门构造
  • 厂或服务类

我认为,任何这些方法将是一个不错的解。就我个人而言,我喜欢专业的构造器解决方案,因为它代表了现实世界:您正在从现有的员工创建一个新的管理器。

0

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

所以你正在改变角色。