继续这个问题:
Composition over Inheritance - where do extra properties go?
接受的答案和类似答案很好地回答了这个问题。但要进一步说明,如果销售部门和生产部门希望记录有关疾病和假期缺勤的不同信息,该怎么办?这可能是一个解决方案:
public class Holiday : Absence
{
//Extra fields go here.
}
public class Sickness : Absence
{
//Extra fields go here.
}
public class SalesHoliday : Holiday
{
//Extra fields go here.
}
public class SalesSickness : Sickness
{
//Extra fields go here.
}
public class ProductionHoliday : Sickness
{
//Extra fields go here.
}
public class ProductionSickness : Sickness
{
//Extra fields go here.
}
显然,这是阶级爆炸的开始,只会变得更糟,因此应该避免。
一种可能的解决方案是使用Decorator Pattern(Gang of Four)。这将是理想的,但在这个假设的例子中,持久性是使用NHibernate。我已经到处寻找一个如何在NHibernate中映射Decorator模式而没有找到任何东西的例子。我的实验有一点,利用了子类映射,连接子类映射,并集子类映射,鉴别符,隐式多态和多对映射的各种组合,但到目前为止还没有令人满意的结果。有没有人破解过这个? Employee实体将拥有任何类型的缺席集合,因此需要多态行为。
答案 0 :(得分:3)
在对这种特定类型的应用程序进行建模时,我会尝试远离基于部门的缺勤分类。相反,我会尝试使缺席处理系统能够支持任何部门。您可以设计一个模型,允许在必要时向缺席添加自定义属性。这可以使用通用注释字段或字典来完成。然后,这些数据可以通过给定的上下文进一步构建,例如销售和生产。
考虑到这一点的一种方法是,销售部门的缺席很像生产部门的缺席,因此实体的“类型”不会改变。可能改变的是关于缺席的特定细节,这反过来又保证了构成优于继承方法。
答案 1 :(得分:0)
我终于回答了我自己的问题。 Union-subclass是前进的方式,就像在这个披萨示例中一样:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="Decorator.Domain.Entities"
assembly="Decorator.Domain">
<class name="IPizza" abstract="true">
<id name="Id" column="Id" type="guid">
<generator class="assigned"/>
</id>
<many-to-one name="Order" class="Order" column="`OrderId`" cascade="save-update" />
<union-subclass name="Pizza" table ="`Pizza`" >
<property name="Size" column="`Size`" />
<property name="Cheese" />
<property name="Tomato" />
</union-subclass>
<union-subclass name="PepperoniDecorator" table ="`PepperoniDecorator`" >
<many-to-one name="BasePizza" class="IPizza" column="`BasePizzaId`" cascade="all" />
<property name="ExtraSpicy" column="`ExtraSpicy`" />
</union-subclass>
<union-subclass name="OliveDecorator" table ="`OliveDecorator`" >
<many-to-one name="BasePizza" class="IPizza" column="`BasePizzaId`" cascade="all" />
<property name="Colour" column="`Colour`" />
</union-subclass>
</class>
</hibernate-mapping>
我在博客上详细介绍了这一点:
http://lucidcoding.blogspot.co.uk/2013/07/mapping-decorator-pattern-in-nhibernate.html