SOLID Принцип подстановки Барбары Лисков

SOLID Принцип подстановки Барбары Лисков

sergey shishkin

"Liskov Substitution Principle (LSP)":

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

Данный принцип ограничивает использование реализации базы, закрепляя что каждая реализация базового интерфейса должна обеспечивать исполнение всех алгоритмов с участием базового интерфейса. При этом базовый интерфейс однозначно сопоставляется с поведением, ожидаемым в местах его использования. И наличие в поведении реализации отличия от ожидаемого поведения, закрепляемого базовым интерфейсом, приведет к возможности нарушения инварианта <1.2>\left<1.2\right>⟨1.2⟩.

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

Целью для этого принципа является устранение неявно вносимых ошибок, получаемых из-за того, что в разработке существуют следующие инварианты:

  • ⟨1.1⟩, ⟨1.2⟩, ⟨1.3⟩
  • база алгоритмического блока связана с алгоритмами, использование которых является полезным в большом количестве ситуаций, и эти алгоритмы задают ограничения, требуемые для применения этой базы,
  • разработанный алгоритмический блок реализации базы должен выполнять все ограничения этой базы, включая тяжело отслеживаемые подразумеваемые (предоставленные не алгоритмами базового интерфейса, а алгоритмами, использующими эту базу).

Очень часто для описания этого принципа приводят пример с Прямоугольником (базой) и Квадратом (реализацией). Ситуация class CSquare : public CRectangle. В базе вводят операции работы с шириной и высотой (Set(Get)Width, Set(Get)Height). В реализации CSquare эти Set-операции вынуждены менять оба размера объекта. Мне всегда не хватало пояснения, что "неформально" в базе задается следующее ограничение: "возможность независимого использования Width, Height". В реализации CSquare оно нарушается, и в местах использования простая последовательность действий, основанная на использовании этой независимости: r.set_width(r.get_width()*2); r.set_height(r.get_height()*2) - для реализации CSquare увеличит оба размера в 4 раза, вместо 2 раз предполагаемых для CRectangle.

Данный принцип указывает на сложность отслеживания подобных неформальных ограничений, что при огромной полезности и большой частоте использования подхода разработки "база-реализация" требует особого внимания.

https://telegra.ph/Obshchaya-teoriya-algoritmov-01-20

Report Page