Я прошу об этом больше из любопытства, чем о том, что он действительно беспокоится о нем, но мне было интересно, нарушает ли система событий JavaScript Принцип подстановки Лискова (LSP) или нет.
Вызывая EventTarget.dispatchEvent
, мы можем отправить Event
произвольного типа, который может обрабатываться зарегистрированным EventListener
.
interface EventListener {
void handleEvent(in Event evt);
}
Если я правильно понял LSP, это означало бы, что anyEventListener.handleEvent(anyEvent)
не должен терпеть неудачу. Однако, как правило, это не так, поскольку слушатели событий часто используют свойства специализированных подтипов Event
.
В типизированном языке, который не поддерживает generics, этот проект будет в основном требовать downcasting объекта Event
к ожидаемому подтипу в EventListener
.
С моей точки зрения, вышеупомянутый дизайн, как это можно считать нарушением LSP. Правильно ли я или просто факт предоставления type
при регистрации слушателя через EventTarget.addEventListener
предотвращает нарушение LSP?
EDIT:
В то время как все, кажется, сосредотачиваются на том факте, что подклассы Event
не нарушают LSP, меня действительно беспокоил тот факт, что разработчики EventListener
нарушили LSP, наложив предварительные условия EventListener
интерфейс. Ничто в контракте void handleEvent(in Event evt)
не говорит о том, что что-то может сломаться, передав неправильный подтип Event
.
В строго типизированном языке с generics этот интерфейс может быть выражен как EventListener<T extends Event>
, так что разработчик может сделать контракт явным, например. SomeHandler implements EventListener<SomeEvent>
.
В JS, очевидно, нет реальных интерфейсов, но обработчики событий по-прежнему должны соответствовать спецификации, и в этой спецификации нет ничего, что позволяет обработчику определить, может ли он обрабатывать определенный тип события.
Это не проблема, потому что слушатели не должны вызываться сами по себе, а скорее вызываются EventTarget
, на которых он был зарегистрирован, и , связанным с определенным типом.
Мне просто интересно, нарушен ли LSP в соответствии с теорией. Интересно, следует ли избежать нарушения (если это теоретически считается таковым), контракт должен был быть чем-то вроде следующее (хотя, возможно, это было хуже, чем пользы с точки зрения прагматизма):
interface EventListener {
bool handleEvent(in Event evt); //returns wheter or not the event could be handled
}