Это не является очевидным или типичным нарушением LSP, и можно утверждать, что это вообще не нарушение LSP, но вот моя интерпретация:
Ожидается, что Shape
описывается его полем type
. Когда DrawShape
получает объект Shape
, может произойти одна из нескольких вещей. В зависимости от значения поля type
он может попытаться преобразовать объект в Square
и вызвать его функцию Draw
или попытаться преобразовать его в Circle
с тем же концом. Однако не гарантируется, что это будет работать должным образом для произвольного Shape
. В частности, это будет работать только в том случае, если динамический тип объекта действительно соответствует семантическому значению его поля type
. Если поле type
не соответствует своему динамическому типу, при попытке выполнить динамическое приведение возникнет исключение. Это поведение DrawShape
при наличии объекта Shape
.
Однако, учитывая Square
или Circle
, есть другое ожидание. В частности, ожидается, что функция всегда будет выполнять тот или иной путь без исключения, поскольку семантическое значение поля type
всегда будет соответствовать динамическому типу объекта.
Другими словами, вы можете рассматривать функцию DrawShape
как имеющую четыре интересных пути выполнения для объекта Shape
: исключение, возникающее при динамическом приведении Circle
, исключение, возникающее при динамическом приведении Square
, или успешное выполнение Square
или Circle
. функции рисования.
При замене дочернего элемента первые два упомянутых пути больше невозможны, а для данного дочернего элемента возможен только один путь.
В качестве альтернативы можно утверждать, что нарушения LSP нет; функция по-прежнему «действует» для дочерней замены так же, как и для родителя. Squares
и Circles
просто имеют дополнительное значение, заключающееся в том, что поле type
определенно будет соответствовать динамическому типу объекта, ограничивая результаты выполнения функции во время выполнения. Хотя это можно рассматривать как изменение ожиданий функции, это также можно рассматривать просто как наложение предварительного условия.
Изменить
Я полагаю, я забыл ответить на часть вопроса: причина, по которой это предполагаемое нарушение LSP «вызывает» нарушение OCP, заключается в том, что логика функции, которая заставляет поведение Shapes
отличаться от Squares
и Circles
, являясь динамическим приведением к дочерним элементам, это та же самая логика, которая заставляет класс Shape
зависеть от своих дочерних элементов. Таким образом, нарушая LSP с помощью условной логики о подклассах, он, в свою очередь, нарушает OCP.
Я не знаю, действительно ли я сам назвал бы этот конкретный случай ситуацией «причинности» столько же, сколько простым пересечением событий, но, возможно, это было намерением автора.
person
Alexander Guyer
schedule
05.07.2019