Принцип подстановки Лисков (Liskov substitution principle)

Подстановочность - это принцип в объектно-ориентированном программировании, утверждающий, что в компьютерной программе, если S является подтипом T, объекты типа T могут быть заменены объектами типа S (то есть объект типа T может быть заменен любым объектом подтипа S) без изменения каких-либо желательных свойств программы (корректность, выполненная задача и т. д.). Более формально, принцип подстановки Лисков (LSP) - это конкретное определение отношения подтипов, называемого (сильным) поведенческим подтипом, которое было впервые введено Барбарой Лисков в основном выступлении на конференции в 1987 году под названием "Абстракция и иерархия данных". Это семантическое, а не просто синтаксическое отношение, поскольку оно призвано гарантировать семантическую совместимость типов в иерархии, в частности, типов объектов. Барбара Лисков и Джаннет Винг вкратце описали этот принцип в статье 1994 года:

Требование к подтипу: Пусть ϕ(x) - свойство, доказываемое для объектов x типа T. Тогда ϕ(y) должен быть истинным для объектов y типа S, где S является подтипом T.

В той же статье Лисков и Винг подробно изложили свое представление о поведенческих подтипах в расширении логики Хоара, который имеет определенное сходство с дизайном Бертрана Мейера по контракту, поскольку рассматривает взаимодействие подтипов с предусловиями, постусловиями и инвариантами.

Принцип

Понятие Лисков о поведенческом подтипе определяет понятие замещаемости для объектов; то есть, если S является подтипом T, тогда объекты типа T в программе могут быть заменены объектами типа S без изменения каких-либо желательных свойств этой программы (например, правильности).

Поведенческий подтип является более сильным понятием, чем типичный подтип функций, определенных в теории типов, который основан только на контравариантности типов аргументов и ковариантности возвращаемого типа. Поведенческий подтип в общем случае неразрешим: если q является свойством "метод для x всегда завершается", то для программы (например, для компилятора) невозможно проверить, что оно верно для некоторого подтипа S в T, даже если q имеет место для Т. Тем не менее, этот принцип полезен в рассуждениях о дизайне иерархий классов.

Принцип Лисков предъявляет некоторые стандартные требования к сигнатурам, принятым в более новых объектно-ориентированных языках программирования (обычно на уровне классов, а не типов):

  • Контравариантность аргументов метода в подтипе.
  • Ковариантность возвращаемых типов в подтипе.
  • Никакие новые исключения не должны создаваться методами подтипа, за исключением тех случаев, когда сами эти исключения являются подтипами исключений, создаваемых методами супертипа.

В дополнение к требованиям сигнатуры подтип должен соответствовать ряду поведенческих условий. Они подробно изложены в терминологии, напоминающей терминологию проектирования по методологии контракта, что приводит к некоторым ограничениям того, как контракты могут взаимодействовать с наследованием:

  • Предпосылки не могут быть усилены в подтипе.
  • Постусловия не могут быть ослаблены в подтипе.
  • Инварианты супертипа должны быть сохранены в подтипе.
  • Ограничение истории ("правило истории"). Объекты считаются изменяемыми только через их методы (инкапсуляция). Поскольку подтипы могут вводить методы, которых нет в супертипе, введение этих методов может разрешить изменения состояния в подтипе, которые недопустимы в супертипе. Ограничение истории запрещает это. Это был новый элемент, представленный Лисков и Винг. Нарушение этого ограничения может быть проиллюстрировано определением изменяемой точки как подтипа неизменной точки. Это нарушение ограничения истории, потому что в истории неизменяемой точки состояние всегда одинаково после создания, поэтому оно не может включать историю изменяемой точки в целом. Поля, добавленные к подтипу, могут, однако, быть безопасно изменены, потому что они не наблюдаются с помощью методов супертипа. Таким образом, из неизменной точки можно вывести окружность с фиксированным центром, но изменяемым радиусом, не нарушая LSP.

Происхождение

Правила для предусловий и постусловий идентичны тем, которые были введены Бертраном Мейером в его книге "Построение объектно-ориентированного программного обеспечения" 1988 года. И Мейер, и позже Пьер Америка, который первым использовал термин поведенческий подтип, дали подтверждающие-теорию определения некоторых понятий поведенческого подтипа, но в их определениях не учитывался псевдоним, который может встречаться в языках программирования, которые поддерживают ссылки или указатели. Принятие во внимание псевдонимов было главным улучшением, сделанным Лисков и Винг (1994), и ключевым компонентом является ограничение истории. Согласно определениям Мейера и Америки, MutablePoint будет поведенческим подтипом ImmutablePoint, тогда как LSP запрещает это.


Читайте также:

Комментарии

Популярные сообщения из этого блога

Язык поисковых запросов в Graylog

Нормальные формы, пример нормализации в базе данных

Хэш-таблица: разрешение коллизий