Supposons que nous ayons une liste d'entités de tâche et un ProjectTasksous-type. Les tâches peuvent être fermées à tout moment, à l'exception des tâches ProjectTasksqui 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 ProjectTaskn’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.
Taskn’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.
TaskCloserprocessus 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 ProjectTasket, tout à coup, TaskClosercommence à lancer des exceptions (éventuellement non gérées). Ceci est une grosse affaire!