valuacion sustitucion solid segregación principios principio open interfaces ejemplos economia devexperto dependencia close constructor class-method lsp

constructor - sustitucion - principio open close



¿Deberían los constructores cumplir con el Principio de Sustitución de Liskov? (3)

Por lo general, trato de asegurarme de que las instancias de mis objetos cumplen con el Principio de sustitución de Liskov , pero siempre me he preguntado si la gente piensa que LSP debería aplicarse a los constructores también.

He intentado buscar en Google para esto, pero no he podido encontrar opiniones fuertes de ninguna manera.

Debo señalar que la mayor parte de mi codificación está en Ruby, pero a veces encuentro que mis constructores de subclases son ligeramente diferentes de la clase padre. Toman el mismo conjunto de argumentos base y, a menudo, argumentos extra. Algunas veces esto también ocurre con otros métodos de clase.

En la parte posterior de mi cabeza esto siempre se ha sentido como una violación LSP, pero quería ver si alguien más se siente de esta manera también.


Definitivamente no.

Los constructores están normalmente especializados para subtipos. Intentar aplicar LSP a los constructores sería como decir que los subtipos no pueden haber agregado métodos o miembros específicos. Pero la restricción es solo al revés.

Y también estoy de acuerdo con Philip, los constructores no son realmente parte de un tipo (y en algunos idiomas puedes usar fácilmente otras fábricas en lugar de constructores). Utilizando la terminología smalltalk, diría que los constructores son métodos de metaclases.

No hay violación de LSP aquí, solo se aplica a métodos de instancia, no a métodos de clase (constructores o cualquier otro método de clase).


Esta es una especie de pregunta obstinada, pero la manera en que tiendo a escribir la mía es tal que los parámetros adicionales no tienen ninguna relación con el cambio de funcionalidad. Con esto quiero decir que cuando mi constructor requiere un parámetro extra en una subclase es para mantener la funcionalidad estándar (pero haciendo diferentes cosas subyacentes) de esta manera digamos que creo ClassA = new ClassB (con algunos argumentos); entonces la funcionalidad es la misma ya sea que haga esto o ClassA = new ClassA (); y usualmente uso algún tipo de método Factory para crearlos, así que es perfecto en la forma en que funcionan. De nuevo, así es como hago las cosas y de ninguna manera es la manera correcta y absoluta de hacer las cosas.


No, cuando usas un constructor sabes que estás tratando con el subtipo. Esto le permite tener condiciones previas no necesarias para el constructor padre, como otros parámetros. Esta es la razón por la cual en la mayoría de los idiomas el nombre del constructor es el de la clase que se está creando.

Un buen ejemplo de cómo esto es que un ColoredSquare podría ser un subtipo correcto de Square , pero requiere un parámetro adicional: color . Si no pudieras hacer cosas como este, los subtipos serían mucho menos útiles.

En cierto sentido, el constructor no es realmente parte del tipo: es una función que devuelve un elemento de ese tipo. Por lo tanto, definir un nuevo constructor para un subtipo no rompe el LSV.