Да кажем, че пиша webapp с Form
клас, а Form
клас може да има няколко Fields
.
Самият Field
е абстрактен клас. То съдържа абстрактно свойство validators
, което е списък от методи, които ще извика, за да определи дали съдържанието на полето е валидно или не. Тези валидатори се извикват чрез извикване на метода на екземпляра Field.run_validators(value)
CharField
е Field
подклас, който позволява произволен текст. Това поле е винаги валидно, стига да му бъде даден низ с ненулева дължина.
EmailField
е подклас CharField
с допълнителни изисквания. Това поле е валидно само когато value
премине набор от тестове от някакъв вид. (напр. '@' in value
).
Моят въпрос тук е: EmailField
нарушава ли LSP по отношение на CharField
? Трябва ли вместо това да е клас за брат или сестра? Въпреки че Field
дефинира променливостта, като позволява на подкласовете да предоставят свои собствени validators
, TextField
не разширява изрично тази променливост.
Продължавам да се опитвам да намеря повече обяснения на LSP, но всички те използват повторно един и същ пример за правоъгълник/квадрат.
дадени:
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
. Това нарушение на ЗУД ли е? Или разсъжденията ми са напълно назад? (което се случва достатъчно често)
Също така можете също толкова щастливо да си представите run_validators()
да връща False
вместо да предизвика изключение, ако това промени анализа по някакъв начин; Просто исках да запазя примера си възможно най-близо до изходния материал.