Supponiamo di avere un elenco di entità Task e un ProjectTasksottotipo. Le attività possono essere chiuse in qualsiasi momento, tranne ProjectTasksche non possono essere chiuse una volta che hanno lo stato Avviato. L'interfaccia utente dovrebbe garantire che l'opzione per chiudere un avvio ProjectTasknon sia mai disponibile, ma nel dominio sono presenti alcune garanzie:
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();
}
}
Ora quando si chiama Close()un'attività, è possibile che la chiamata fallisca se è ProjectTaskcon lo stato avviato, quando non sarebbe se fosse un'attività base. Ma questi sono i requisiti aziendali. Dovrebbe fallire. Questo può essere considerato una violazione del principio di sostituzione di Liskov ?
public Status Status { get; private set; }:; altrimenti il Close()metodo può essere aggirato.
Tasknon introducano bizzarre incompatibilità nel codice polimorfico di cui è a conoscenza Taskè un grosso problema. LSP non è un capriccio, ma è stato introdotto proprio per aiutare la manutenibilità nei sistemi di grandi dimensioni.
TaskCloserprocesso che closesAllTasks(tasks). Questo processo ovviamente non tenta di catturare eccezioni; dopo tutto, non fa parte del contratto esplicito di Task.Close(). Ora introduci ProjectTaske improvvisamente TaskCloserinizi a lanciare (forse non gestite) eccezioni. Questo è un grosso problema!