Powiedzmy, że mamy listę encji Zadania i ProjectTask
podtyp. Zadania można zamknąć w dowolnym momencie, z wyjątkiem tych, ProjectTasks
których nie można zamknąć, gdy mają status Uruchomione. Interfejs użytkownika powinien upewnić się, że opcja zamknięcia uruchomionego ProjectTask
nigdy nie jest dostępna, ale w domenie istnieją pewne zabezpieczenia:
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();
}
}
Teraz podczas wywoływania Close()
Zadania istnieje szansa, że połączenie zakończy się niepowodzeniem, jeśli ma ProjectTask
status Rozpoczęty, a nie będzie, jeśli będzie to zadanie podstawowe. Ale to są wymagania biznesowe. To powinno zawieść. Czy można to uznać za naruszenie zasady substytucji Liskowa ?
public Status Status { get; private set; }
:; w przeciwnym razie Close()
można obejść tę metodę.
Task
nie wprowadzają dziwnych niezgodności w kodzie polimorficznym, o których tylko wie się, Task
to wielka sprawa. LSP nie jest kaprysem, ale został wprowadzony właśnie w celu ułatwienia konserwacji w dużych systemach.
TaskCloser
proces, który closesAllTasks(tasks)
. Ten proces oczywiście nie próbuje wychwycić wyjątków; w końcu nie jest to część wyraźnej umowy z Task.Close()
. Teraz wprowadzasz ProjectTask
i nagle zaczynasz TaskCloser
rzucać (prawdopodobnie nieobsługiwane) wyjątki. To wielka sprawa!