Supposons que nous ayons une liste d'entités de tâche et un ProjectTask
sous-type. Les tâches peuvent être fermées à tout moment, à l'exception des tâches ProjectTasks
qui ne peuvent pas être fermées une fois qu'elles ont le statut Lancé. L’interface utilisateur doit s’assurer que l’option de fermeture d’un espace ouvert ProjectTask
n’est jamais disponible, mais certaines garanties sont présentes dans le domaine:
public class Task
{
public Status Status { get; set; }
public virtual void Close()
{
Status = Status.Closed;
}
}
public class ProjectTask : Task
{
public override void Close()
{
if (Status == Status.Started)
throw new Exception("Cannot close a started Project Task");
base.Close();
}
}
Désormais, lors de l'appel Close()
d'une tâche, il est possible que l'appel échoue s'il s'agit d'un ProjectTask
état démarré, alors que ce ne serait pas le cas s'il s'agissait d'une tâche de base. Mais ce sont les exigences commerciales. Cela devrait échouer. Cela peut-il être considéré comme une violation du principe de substitution de Liskov ?
public Status Status { get; private set; }
; sinon, la Close()
méthode peut être contournée.
Task
n’introduisent pas d’incompatibilités bizarres dans le code polymorphe Task
. Le LSP n'est pas un caprice, mais a été introduit précisément pour faciliter la maintenance dans les grands systèmes.
TaskCloser
processus qui closesAllTasks(tasks)
. Ce processus ne tente évidemment pas d'attraper les exceptions; après tout, cela ne fait pas partie du contrat explicite de Task.Close()
. Maintenant, vous introduisez ProjectTask
et, tout à coup, TaskCloser
commence à lancer des exceptions (éventuellement non gérées). Ceci est une grosse affaire!