En mi búsqueda por escribir un código mejor y más limpio, estoy aprendiendo acerca de los principios SOLID. En esto, LSP está demostrando ser poco difícil de entender adecuadamente.
Mi duda es ¿qué pasa si tengo algunos métodos adicionales en mi subtipo, S, que no estaban allí en tipo, T, esto siempre será una violación de LSP? En caso afirmativo, ¿cómo hago extend
mis clases?
Por ejemplo, digamos que tenemos un Bird
tipo. Y sus subtipos son Eagle
y Humming Bird
. Ahora ambos subtipos tienen un comportamiento común como el Bird
. Pero Eagle
también tiene un buen comportamiento depredador (que no está presente en el Bird
tipo general ), que quiero usar . Por lo tanto, ahora no podré hacer esto:
Bird bird = new Eagle();
Entonces, ¿dar Eagle
ese comportamiento extra está rompiendo el LSP?
En caso afirmativo, ¿eso significa que no puedo extender mis clases porque eso causaría una violación de LSP?
class Eagle extends Bird {
//we are extending Bird since Eagle has some extra behavior also
}
La extensión de clases debe permitirse de acuerdo con el principio de Abierto / Cerrado ¿verdad?
Gracias de antemano por responder! Como puede ver claramente, LSP me tiene confundido como cualquier cosa.
Editar: consulte esta respuesta SO. En esto nuevamente, cuando Car
tiene un comportamiento adicional como ChangeGear
, viola el LSP. Entonces, ¿cómo ampliamos una clase, sin violar el LSP?
fuente
Respuestas:
Respuesta muy simple: no.
El punto para el LSP es que
S
debe ser sustituible porT
. Entonces, siT
implementa unadelete
función, tambiénS
debería implementarla y debería realizar una eliminación cuando se le llame. Sin embargo,S
es libre de agregar funcionalidades adicionales además de lo queT
ofrece. Los consumidores de aT
, cuando reciben unaS
, desconocen esta funcionalidad adicional, pero se permite que los consumidores laS
utilicen directamente.Algunos ejemplos de cómo se puede violar el principio pueden ser:
Respuesta un poco más compleja: no, siempre y cuando no comience a afectar el estado u otro comportamiento esperado del tipo base.
Por ejemplo, lo siguiente sería una violación:
El tipo
Point2D
,, es inmutable; su estado no puede ser cambiado. ConMyPoint2D
, he eludido deliberadamente ese comportamiento para hacerlo mutable. Eso rompe la restricción del historialPoint2D
y, por lo tanto, es una violación del LSP.fuente
delete
función que sería una violación de LSP?Por supuesto no. Si el objeto Eagle puede ser utilizado por cualquier código que espera un Bird o una subclase, y se comporta como un Bird debería comportarse, está bien.
Por supuesto, el comportamiento de Eagle solo puede ser usado por código que es consciente de que es un objeto de este tipo. Es de esperar que algún código cree explícitamente un objeto Eagle y lo use como un objeto Eagle, al tiempo que puede usar cualquier código que espere objetos Bird.
fuente