Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composition over Inheritance - where do extra properties go?

Take this following code from an example HR system. The user has the ability to log an absence and can be of various types including holiday and sickness. This would be a domain model over an ORM such as 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()
    { ... }
}

This is an example - please don't question why location would be required, assume it is a specification.

The user wants to change the type - he thought the employee was off sick but then remembered it was a holiday. Again, you may think this is a bad design but treat it like a requirement - this represents a problem that has come up many times for me.

The problem is that you cannot change the type of an object from Sickness to Absence. Generally, the advice would be to Favour Composition Over Inheritance (Gang of Four) and do this:

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();
    }
}

But when I do this, when do the properties specific to Holiday and Sickness go (Location and DoctorsNoteProvided respectively)?

like image 855
Paul T Davies Avatar asked Jul 13 '11 16:07

Paul T Davies


2 Answers

Why do you need to change the type of an object?

You will have some kind of collection of Absences, just replace the item in question.

Conceivably rather than replacing you even keep the original request and mark it as superceded, that might be important for audit trail purposes.

like image 130
djna Avatar answered Nov 03 '22 01:11

djna


It's not the right place for Composition over Inheritance. Here the inheritance is appropriate. And if you need to change the type of absence just create a new one and delete old.

like image 25
Mike Mozhaev Avatar answered Nov 03 '22 01:11

Mike Mozhaev