Скажем, я пишу веб-приложение с классом Form
, а класс Form
может иметь несколько классов Fields
.
Field
сам по себе является абстрактным классом. Он содержит абстрактное свойство validators
, представляющее собой список методов, которые будут вызываться для определения того, является ли содержимое поля допустимым. Эти валидаторы вызываются вызовом метода экземпляра Field.run_validators(value)
CharField
— это подкласс Field
, допускающий произвольный текст. Это поле всегда допустимо, пока ему задана некоторая строка ненулевой длины.
EmailField
— это подкласс CharField
с дополнительными требованиями. Это поле допустимо только тогда, когда value
проходит ряд тестов. (например, '@' in value
).
У меня вопрос: нарушает ли EmailField
LSP по отношению к CharField
? Должен ли это быть родственный класс? Хотя Field
определяет изменчивость, позволяя подклассам предоставлять свои собственные validators
, TextField
явно не расширяет эту изменчивость.
Я продолжаю пытаться найти больше объяснений LSP, но все они повторно используют один и тот же пример Rectangle/Square.
Дано:
def transmogulate(field):
"""field must be a TextField instance."""
assert isinstance(field, TextField)
instance.run_validators("hello")
При использовании CharField
transmogulate(my_text_field)
будет работать без проблем. Но если my_text_field
вместо этого является экземпляром EmailField
, он всегда будет вызывать ValidationError
. Является ли это нарушением LSP? Или мои рассуждения полностью назад? (что случается достаточно часто)
Также вы можете так же счастливо представить, что run_validators()
возвращает False
вместо возбуждения исключения, если это каким-то образом меняет анализ; Я просто хотел, чтобы мой пример был как можно ближе к исходному материалу.