Принцип підстановки Лісков

Принцип заміщення Лісков (англ. Liskov Substitution Principle, LSP) в об'єктно-орієнтованому програмуванні — це спеціальне визначення підтипу, запропоноване Барбарою Лісков у 1987 році на конференції у доповіді під назвою "Абстракція даних та ієрархія"[1].

У своїй статті [2] Лісков сформулювала свій принцип так:

Нехай є властивістю правильною для об'єктів деякого типу . Тоді також має бути правильним для об'єктів типу , де  — підтип типу .

Таким чином ідея Лісков про «підтип» визначає поняття заміщення — якщо S підтип T, тоді об'єкти типу T в програмі можуть бути заміщені об'єктами типу S без будь-яких змін бажаних властивостей цієї програми (наприклад, коректність).

Цей принцип — найважливіший критерій для оцінки якості ухвалених рішень при побудові ієрархій успадкування. Сформулювати його можна у вигляді простого правила: тип S буде підтипом Т тоді і тільки тоді, коли кожному об'єктові o1 типу S відповідає певний об'єкт o2 типу T таким чином, що для всіх програм P, реалізованих в термінах T, поведінка P не зміниться, якщо o2 замінити на o1.

Принцип Лісков є суворішим за поняття підтипу в теорії типів, яка вимагає тільки:

  • коваріантність методів за типом результату;
  • контраваріантність методів за типами аргументів;
  • заборону в методах підтипу викиду винятків, які не є похідними від типів винятків, що викидаються методами базового типу.

Див. коваріантність і контраваріантність і типи даних.

Проектування за контрактом

Принцип заміщення Лісков близько стосується методології проектування за контрактом, і веде до деяких обмежень на те, як контракти можуть взаємодіяти з успадкуванням:

  • Передумови не можуть бути посилені в підтипі.
  • Післяумови не можуть бути послаблені в підтипі.
  • Інваріанти базового типу повинні виконуватись у підтипі.
  • «Історичне обмеження»: заборона модифікації стану об'єкта методами підтипу, які відсутні в базовому типі.

Функція, що обробляє ієрархію класів з порушеннями принципу Лісков, використовує посилання на базовий клас, але також вимушена мати інформацію про підклас. Така функція також порушує принцип відкритості/закритості оскільки її необхідно змінювати в разі появи нових похідних класів.

У цьому контексті принцип заміщення Лісков можна переформулювати так:

Функції, які використовують посилання на базові класи, повинні мати можливість використовувати об'єкти похідних класів, не знаючи про це.

Андрей Александреску та Герб Саттер в книзі «C++ Coding Standards» описують виконання цього принципу так:

«Підклас не повинен вимагати від коду, що його викликає, більше ніж вимагав базовий клас. І повинен надавати цьому коду не менше ніж надавав базовий клас».

На думку авторів, публічне успадкування можна використовувати тільки коли виконується принцип LSP. Приватне успадкування дозволене тільки для доступу до protected частини та заміщення віртуальних методів. Для всіх інших випадків, успадковування використовувати не бажано.

Примітки

  1. Liskov, Barbara (4 жовтня 1987). Data abstraction and hierarchy. Процитовано 23 березня 2008.
  2. Liskov, Barbara; Jeannette Wing (July 1999). Behavioral Subtyping Using Invariants and Constraints (PS). Архів оригіналу за 30 серпня 2012. Процитовано 5 жовтня 2006.

Джерела

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.