Содержание
Принцип подстановки Лисков (LSP) один из пяти принципов SOLID, сформулированный следующим образом: объект производного класса должен иметь возможность заменять объект базового класса, не вызывая ошибок в системе и не изменяя поведение базового класса. Что означает LSP и как он реализуется в C# — рассмотрим в этой части.
Принцип подстановки Лисков (LSP) в C#
Ключевая идея LSP: если код работает с базовым типом, он должен так же хорошо работать с любым его наследником. Принцип был введён Барбарой Лисков.
Пример из жизни, когда LSP не работает: отец — учитель, а его сын — врач. Так что в этом случае сын не может просто заменить отца, даже если они из одной семьи.
Пример использования принципа подстановки Лисков в C#
Пример без использования принципа подстановки Лисков в C#
Давайте сначала разберём один пример без использования принципа подстановки Лисков в C#. Мы увидим проблему, если не будем следовать принципу подстановки Лисков, а затем посмотрим, как можно решить эту проблему с помощью LSP. В следующем примере сначала мы создаём класс Apple
с методом GetColor
. Затем мы создаём класс Orange
, который наследует класс Apple
и переопределяет метод GetColor
класса Apple
. Дело в том, что «апельсин» нельзя заменить на «яблоко», поэтому цвет яблока будет отображаться как «оранжевый», как показано в примере ниже.
Apple apple = new Orange(); Console.WriteLine(apple.GetColor()); public class Apple { public virtual string GetColor() { return "Red"; } } public class Orange : Apple { public override string GetColor() { return "Orange"; } }
Как вы можете видеть в приведённом выше примере, Apple
— это базовый класс, а Orange
— дочерний класс, то есть между ними существует связь «родитель-потомок». Таким образом, мы можем сохранить объект дочернего класса в переменной родительского класса, то есть Apple apple = new Orange();
и когда мы вызываем метод GetColor()
, то есть apple.GetColor()
, мы получаем цвет Orange
, а не цвет Red
. Это означает, что поведение меняется после замены дочернего объекта, то есть Apple
сохраняет объект Orange
. Это противоречит принципу LSP. Принцип подстановки Лисков гласит, что даже если дочерний объект заменяется родительским, поведение не должно меняться. Таким образом, в данном случае, если мы сможем каким-либо образом получить цвет Red
вместо Orange
, это будет соответствовать принципу подстановки Лисков.
Пример с использованием LSP C#
Давайте изменим предыдущий пример, чтобы он соответствовал принципу подстановки Лисков, используя язык C#. Во-первых, нам нужен универсальный базовый интерфейс, то есть IFruit
, который будет базовым для Apple
и Orange
. Теперь вы можете заменить переменную IFruit
на её подтипы — Apple
или Orange
и она будет работать правильно. В приведённом ниже коде мы создали интерфейс IFruit
с методом GetColor
. Затем классы Apple
и Orange
реализовали метод GetColor()
.
IFruit apple = new Orange(); Console.WriteLine(apple.GetColor()); public interface IFruit { string GetColor(); } public class Apple : IFruit { public string GetColor() { return "Red"; } } public class Orange : IFruit { public string GetColor() { return "Orange"; } }
Итак, теперь фрукт может быть любого вида и любого цвета, но апельсин не может быть красного цвета. Яблоко не может быть оранжевого цвета, то есть мы не можем заменить апельсин яблоком, но фрукт можно заменить апельсином или яблоком, потому что они оба являются фруктами.
Преимущества принципа подстановки Лисков (LSP) в C#
- Код становится более предсказуемым (если работает с родителем, будет работать и с потомком)
- Упрощается тестирование
- Повышенная возможность повторного использования кода