Принцип подстановки Лисков: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
м добавлена категория «Семантика языков программирования» с помощью HotCat
Пример нарушения принципа подстановки Лисков: Не корректное применение принципа. см обсуждение
Строка 25: Строка 25:
: ''Функции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.''
: ''Функции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.''


Принцип Лискоу заставляет задуматься о том, что такое «декларация типа» в терминах объектно-ориентированного языка программирования, который мы используем. Достаточно ли нам описать интерфейс объекта с помощью обычного абстрактного класса со списком методов, типами параметров и возвращаемого значения? Каким образом мы можем декларировать требования к значениям параметров метода и свойства, которыми будет обладать возвращаемое значение? Как нам описать исключения, которые может сгенерировать метод во время выполнения? Как нам описать изменение состояния объекта на разных этапах его жизненного цикла?
== Пример нарушения принципа подстановки Лисков ==

Классическим примером нарушения этого принципа является построение иерархий такого рода:

<source lang="java">
class Rectangle
{
public virtual int Width { get; set; }
public virtual int Height { get; set; }

public int CalculateRectangleArea()
{
return Width*Height;
}
}

class Square : Rectangle
{
public override int Height
{
get{ return base.Height; }
set
{
base.Height = value;
base.Width = value;
}
}
public override int Width
{
get{ return base.Width; }
set
{
base.Width = value;
base.Height = value;
}
}
}

class Program
{
private static Rectangle CreateRectangle()
{
return new Square();
}
static void Main()
{
Rectangle r = CreateRectangle();
r.Width = 3;
r.Height = 2;

Assert.AreEqual(6, r.CalculateRectangleArea());
}
}
</source>

Этот пример заставляет задуматься о том, что такое «декларация типа» в терминах объектно-ориентированного языка программирования, который мы используем. Достаточно ли нам описать интерфейс объекта с помощью обычного абстрактного класса со списком методов, типами параметров и возвращаемого значения? Каким образом мы можем декларировать требования к значениям параметров метода и свойства, которыми будет обладать возвращаемое значение? Как нам описать исключения, которые может сгенерировать метод во время выполнения? Как нам описать изменение состояния объекта на разных этапах его жизненного цикла?


Задавая себе эти вопросы и находя ответы, можно спроектировать систему, которая действительно будет удовлетворять принципу замещения Лисков.
Задавая себе эти вопросы и находя ответы, можно спроектировать систему, которая действительно будет удовлетворять принципу замещения Лисков.

Версия от 21:52, 30 октября 2009

В объектно-ориентированном программировании, Принцип подстановки Лисков (LSP) является специфичным определением подтипа предложенным Барбарой Лисков в 1987 году на конференции в основном докладе под названием Абстракция данных и иерархия [1].

В последующей статье[2] Лисков кратко сформулировала свой принцип следующим образом:

Пусть является свойством верным относительно объектов некоторого типа . Тогда также должно быть верным для объектов типа , где является подтипом типа .

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

Этот принцип является важнейшим критерием для оценки качества принимаемых решений при построении иерархий наследования. Сформулировать его можно в виде простого правила: тип S будет подтипом Т тогда и только тогда, когда каждому объекту oS типа S соответствует некий объект oT типа T таким образом, что для всех программ P, реализованных в терминах T, поведение P не будет меняться, если oT заменить на oS.

Проектирование по контракту

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

Также, принцип LSP подразумевает, что методы субкласса не могут выбрасывать никаких дополнительных исключений кроме тех, которые сами являются субклассами исключений выбрасываемых методами суперкласса. См. ковариантность и контрвариантность и типы данных.

Функция использующая иерархию классов с нарушениями принципа Лисков помимо оперирования ссылкой на базовый класс оказывается также вынуждена знать и о субклассе. Подобная функция нарушает принцип открытия/закрытия поскольку она требует модификации в случае появления в системе новых производных классов.

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

Функции, которые используют ссылки на базовые классы, должны иметь возможность использовать объекты производных классов, не зная об этом.

Принцип Лискоу заставляет задуматься о том, что такое «декларация типа» в терминах объектно-ориентированного языка программирования, который мы используем. Достаточно ли нам описать интерфейс объекта с помощью обычного абстрактного класса со списком методов, типами параметров и возвращаемого значения? Каким образом мы можем декларировать требования к значениям параметров метода и свойства, которыми будет обладать возвращаемое значение? Как нам описать исключения, которые может сгенерировать метод во время выполнения? Как нам описать изменение состояния объекта на разных этапах его жизненного цикла?

Задавая себе эти вопросы и находя ответы, можно спроектировать систему, которая действительно будет удовлетворять принципу замещения Лисков.

Примечания

  1. Liskov, Barbara Data abstraction and hierarchy (4 октября 1987). Дата обращения: 23 марта 2008.
  2. Liskov, Barbara; Wing, Jeannette.: Behavioral Subtyping Using Invariants and Constraints (PS) (июль 1999). Дата обращения: 5 октября 2006.

Ссылки