Скажімо, у нас є список суб'єктів Завдання та ProjectTask
підтип. Завдання можуть бути закриті в будь-який час, за винятком випадків, ProjectTasks
коли вони не можуть бути закриті, коли вони мають статус Почато. Користувальницький інтерфейс повинен гарантувати, що можливість закрити розпочатий доступ ProjectTask
ніколи не доступна, однак у домені є деякі гарантії:
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();
}
}
Тепер при виклику Close()
Завдання є ймовірність, що виклик не вдасться, якщо це статус ProjectTask
із запущеним статусом, коли він не був би базовим завданням. Але це ділові вимоги. Це повинно провалитися. Чи можна це вважати порушенням принципу заміни Ліскова ?
public Status Status { get; private set; }
:; інакше Close()
метод можна обійти.
Task
не вносять химерних несумісностей у поліморфний код, про який відомо Task
лише велика справа. LSP не примха, але введено саме для того, щоб допомогти у підтримці ремонту у великих системах.
TaskCloser
процес, який closesAllTasks(tasks)
. Цей процес очевидно не намагається знайти винятки; зрештою, це не є частиною явного договору Task.Close()
. Тепер ви запроваджуєте ProjectTask
і раптом TaskCloser
починаєте викидати (можливо, без обробки) винятки. Це велика справа!