Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nhibernate 组合重于继承-额外属性去哪里?_Nhibernate_Design Patterns_Architecture_Domain Driven Design - Fatal编程技术网

Nhibernate 组合重于继承-额外属性去哪里?

Nhibernate 组合重于继承-额外属性去哪里?,nhibernate,design-patterns,architecture,domain-driven-design,Nhibernate,Design Patterns,Architecture,Domain Driven Design,从一个示例HR系统中获取以下代码。用户可以记录缺勤情况,并且可以是各种类型,包括假期和疾病。这将是一个ORM(如NHibernate)上的域模型 public class Absence { public long Id {get;set;} public Employee Employee {get;set;} public DateTime StartDate {get;set;} public DateTime EndDate {get;se

从一个示例HR系统中获取以下代码。用户可以记录缺勤情况,并且可以是各种类型,包括假期和疾病。这将是一个ORM(如NHibernate)上的域模型

public class Absence
{
    public long Id {get;set;}
    public Employee Employee {get;set;}
    public DateTime StartDate {get;set;}        
    public DateTime EndDate {get;set;}

    public virtual void DoSomething()
    { ... }
}

public class Holiday : Absence
{ 
    public string Location {get;set;}

    public override void DoSomething()
    { ... }
}

public class Sickness : Absence
{
    public bool DoctorsNoteProvided {get;set;}

    public override void DoSomething()
    { ... }
}
这是一个例子-请不要质疑为什么需要位置,假设它是一个规范

用户希望更改类型-他以为员工因病休假,但后来想起这是一个假期。同样,你可能会认为这是一个糟糕的设计,但把它当作一个需求来对待——这代表了我多次遇到的一个问题

问题是您无法将对象的类型从生病更改为缺席。一般来说,建议是赞成组合而不是继承(四人帮),并这样做:

public class Absence
{
    public long Id {get;set;}
    public Employee Employee {get;set;}
    public DateTime StartDate {get;set;}        
    public DateTime EndDate {get;set;}

    public AbsenceType Type {get;set;}

    public void DoSomething()
    {
        Type.DoSomething();
    }
}

但是当我这样做的时候,假期和疾病的属性什么时候去(分别提供位置和医生注释)?

Hmmm,在不了解您的更多需求的情况下,我会说正确的设计是不将缺勤对象更改为疾病对象(反之亦然)但是要删除你不想要的,并创建一个你想要的新类型。你一定在某个地方收集了一些缺勤记录,对吧


你是对的,类不会改变

为什么需要更改对象的类型

你会有一些缺席的集合,只需替换有问题的项目


可以想象,这对于审计跟踪的目的可能很重要,而不是替换您甚至保留原始请求并将其标记为已替换

这不是合成而不是继承的好地方。在这里,继承是合适的。如果您需要更改缺勤类型,只需创建一个新的缺勤类型并删除旧的。

因此,请尝试将所有特定于类型的功能移动到
缺勤类型。如果他们需要来自父类
缺席
的内容,您可以将其引用传递给他们。虽然我会尽量避免


如果您通过基类接口操纵
缺席
对象,则不会发生任何更改,您可以保留旧代码。现在,如果你操纵了特定的导数,那么你将不得不从特定的
缺席
中抓取
缺席类型
对象,并对其执行所有相同的操作-仍然没有太大的变化。如果您有
holiday.DoSomething()
,那么现在您有了
holiday.Type.DoSomething()

我将通过为缺勤类型或缺勤原因建立类型层次结构来建模:

abstract class AbsenseReason {
}

class HolidayAbsenseReason : AbsenseReason {
    public string Name { get; }
}
我喜欢这个模型,因为现在缺勤原因是一个值对象,与员工缺勤无关,员工缺勤是一个实体对象。如您所述,这通过更改缺勤原因解决了问题。一般来说,我赞成删除记录,因为也有很多关联要考虑。

需要考虑的事项:

  • NHibernate不支持组件上的继承映射,因此必须提供IUserType的自定义实现
  • 考虑将不同缺勤原因子类型的所有数据与员工缺勤实体的记录一起存储。可能是XML,这样您就可以拥有集合等

我确实想到会有病假缺席类型,Holiday缺席类型继承自缺席类型。我应该在我的帖子中更好地解释这一点。然而,我认为它是一个实体,而不是一个价值。我不确定您建议我如何将特定于缺勤的信息存储在实际缺勤类型中?在我的概念中,它只包含关于假期/疾病的一般信息,而不是关于一个具体的例子。我想知道更多关于你的理论?我不确定你建议我在哪里存储假期/疾病的特定属性?所以是的,
缺勤类型
是一种值类型,没有标识,只属于单个
缺勤
对象,所有特定类型的行为都应该转移到它的派生类型:
疾病缺席类型
假日缺席类型
,…这是对eulerfx的类似回答。这似乎是人们使用的一种模式,我并不完全熟悉。我还是不太明白。你能给我举一个代码示例吗?三个答案都说了同样的话,很难在它们之间做出选择,但这一个只是有优势,因为它考虑了审计跟踪等。迈克·莫扎耶夫和雷·托尔获得了选票,但这一个获得了胜利!