Digamos que temos uma lista de entidades de tarefas e um ProjectTasksubtipo. As tarefas podem ser fechadas a qualquer momento, exceto as ProjectTasksque não podem ser fechadas uma vez que tenham o status Iniciado. A interface do usuário deve garantir que a opção de fechar uma inicialização ProjectTasknunca esteja disponível, mas algumas salvaguardas estão presentes no domínio:
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();
}
}
Agora, ao chamar Close()uma tarefa, há uma chance de a chamada falhar se for ProjectTaskcom o status iniciado, quando não seria se fosse uma tarefa base. Mas esses são os requisitos de negócios. Deveria falhar. Isso pode ser considerado uma violação do princípio da substituição de Liskov ?
public Status Status { get; private set; }:; caso contrário, o Close()método pode ser contornado.
Tasknão introduzam incompatibilidades bizarras no código polimórfico, que apenas conhece, Taské importante. O LSP não é um capricho, mas foi introduzido precisamente para ajudar na manutenção de grandes sistemas.
TaskCloserprocesso que closesAllTasks(tasks). Obviamente, esse processo não tenta capturar exceções; afinal, não faz parte do contrato explícito de Task.Close(). Agora você apresenta ProjectTaske de repente TaskClosercomeça a lançar exceções (possivelmente não tratadas). Este é um grande negócio!