Take this following code from an example HR system. The user has the ability to register an absence and can be of various types, including holiday and illness. This will be the domain model over ORM, for example 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 - don't ask why location is required, suppose it's a specification.
The user wants to change the type - he thought that the employee was sick, but then remembered that it was a holiday. Again, you might think that this is a bad design, but treat it like a requirement - this is a problem that has come up to me many times.
The problem is that you cannot change the type of an object from Sickness to Absence. Typically, the advice will be to maintain composition over the 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 are the properties characteristic of the holiday and illness (Location and DoctorsNoteProvided, respectively)?
Paul T Davies
source share