组合超过继承 - 额外属性在哪里?

Pau*_*ies 7 architecture nhibernate design-patterns 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;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()
    { ... }
}
Run Code Online (Sandbox Code Playgroud)

这是一个例子 - 请不要质疑为什么需要位置,假设它是一个规范.

用户想要改变类型 - 他认为员工病了,但后来记得这是假期.同样,您可能认为这是一个糟糕的设计,但将其视为一个要求 - 这代表了一个问题,这个问题已经出现过很多次了.

问题是您无法将对象的类型从"疾病"更改为"缺勤".一般来说,建议是赞成组合而不是继承(Gang of Four)并且这样做:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我这样做的时候,Holiday and Sickness特有的属性是什么时候(分别是Location和DoctorsNote)?

djn*_*jna 4

为什么需要改变对象的类型?

您将拥有某种缺勤集合,只需替换有问题的项目即可。

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