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)?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With