Про принцип підстановки Лісков (Liskov Substitution Principle - LSP)

Принцип підстановки Лісков (Liskov Substitution Principle - LSP) є одним із принципів SOLID і формулюється так: об’єкти базового класу повинні можна замінювати своїми похідними без зміни коректності програми. Принцип отримав свою назву від імені Барбари Лісков, яка вперше сформулювала цей принцип.

Основні ідеї LSP.

Замінюваність об’єктів - якщо клас S є підкласом класу T, то об’єкти типу T можна замінити об’єктами типу S без зміни коректності програми.
Підтримка інтерфейсу базового класу - об’єкти підкласу повинні підтримувати інтерфейс базового класу. Це означає, що вони повинні реалізовувати ті ж методи, що і їх батьківський клас, а також повинні поводитися відповідно до очікувань, які можна мати щодо базового класу.
Безпека заміщення методів - методи, що заміщаються в похідному класі, повинні виконувати ті ж самі умови контракту, що і методи базового класу. Це важливо для того, щоб користувачі класу не отримували неочікуваних результатів від виклику методів.

В Ruby принцип підстановки Лісков можна продемонструвати на прикладі класів, що успадковують один від одного та використовують поліморфізм. Давайте розглянемо приклад з геометричними фігурами:

class Shape
  def area
    raise NotImplementedError, 'Subclasses must implement the area method'
  end
end

class Square < Shape
  def initialize(side_length)
    @side_length = side_length
  end

  def area
    @side_length**2
  end
end

class Circle < Shape
  def initialize(radius)
    @radius = radius
  end

  def area
    Math::PI * @radius**2
  end
end

# Функція, яка очікує об'єкт типу Shape
def print_area(shape)
  puts "Area: #{shape.area}"
end

# Використання принципу підстановки Лісков
square = Square.new(5)
circle = Circle.new(3)

print_area(square)  # Очікується "Area: 25"
print_area(circle)  # Очікується "Area: 28.274333882308138"

У цьому прикладі клас Shape є базовим класом, який визначає метод area . Похідні класи, такі як Square і Circle , успадковують від Shape і реалізують власний метод area . Функція print_area очікує об’єкт типу Shape і використовує його метод area . Ми можемо передати як Square , так і Circle в цю функцію, що відповідає принципу підстановки Лісков.