Возьмите этот следующий код из примера системы 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();
}
}
Но когда я делаю это, когда переходят свойства, относящиеся к Holiday и Sickness (соответственно Location и DoctorsNoteProvided)?