【问题标题】:Mapping Decorator Pattern in NHibernate在 NHibernate 中映射装饰器模式
【发布时间】:2011-07-17 11:13:05
【问题描述】:

关于这个问题:

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(四人组)。这将是理想的,但在这个假设的示例中,持久性是使用 NHibernate。我到处寻找如何在 NHibernate 中映射装饰器模式的示例,但没有找到任何东西。我的实验有一点,利用了子类映射、联合子类映射、联合子类映射、鉴别器、隐式多态性和多对任意映射的各种组合,但到目前为止还没有令人满意的结果。有人破解过这个吗? Employee 实体将具有任何类型的缺勤集合,因此需要多态行为。

【问题讨论】:

    标签: nhibernate design-patterns architecture domain-driven-design decorator


    【解决方案1】:

    在对这种特殊类型的应用程序进行建模时,我会尽量避免根据部门对缺勤进行子分类。相反,我会尝试使缺勤处理系统能够支持任何部门。如果有必要,您可以设计一个模型,允许在缺席时添加自定义属性。这可以使用通用注释字段或字典来完成。然后可以通过给定的上下文(例如销售和生产)进一步构建这些数据。

    考虑这一点的一种方式是,销售部门的缺席与生产部门的缺席非常相似,因此实体的“类型”不会改变。可能会改变的是关于缺席的特定细节,这反过来又保证了组合优于继承的方法。

    【讨论】:

    • 如果不是这个特定的应用程序呢?我认为其他人也尝试用 NHibernate 做装饰器。有任何想法吗? 10 倍。
    • 感谢 eulerfx,但我的问题不是针对这种情况提出解决方案。问题是关于在 NHibernate 中实现装饰器模式,这个场景就是一个例子。在很多情况下,装饰器会是一个完美的解决方案,但 NHibernate 映射会导致问题。此外,您在字典中存储属性的建议也不是一个好的建议。过去我曾受此诱惑,它只会带来麻烦。这肯定是经典的反模式吗?感谢您抽出宝贵时间来回答,但我不确定为什么会收到这么多赞?
    • @Paul T Davies:我想我没有看到装饰器模式将如何应用在这里。一般来说,我认为装饰器模式可以通过像往常一样映射装饰组件来映射到 NH,然后让存储库创建将组件传递给它的装饰器。相反,存储库会在需要时提取修饰的组件。
    【解决方案2】:

    我终于回答了我自己的问题。联合子类是前进的方向,就像在这个披萨示例中一样:

    <?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

    【讨论】:

      猜你喜欢
      • 2019-05-07
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-30
      • 1970-01-01
      • 2013-05-07
      相关资源
      最近更新 更多