2011-03-30 13 views
48

lo general tratan de asegurarse de que mis instancias de objetos cumplen con la Liskov Substitution Principle, pero siempre me he preguntado por qué la gente piensa está LSP debe aplicarse a los constructores también?¿Deberían los constructores cumplir con el Principio de Sustitución de Liskov?

he intentado buscando en Google para esto, pero no he sido capaz de encontrar cualquier opinión de cualquier manera fuertes.

Debo notar 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.

Respuesta

50

No, cuando se utiliza un constructor de saber que está 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.

+5

"cuando usas un constructor sabes que estás tratando con el subtipo". Gracias. Es un excelente punto. – Chance

+0

Probablemente sea importante hacer una distinción entre constructores, métodos de fábrica estáticos, métodos de fábrica que son instancias del tipo que se está produciendo (especialmente 'Clone') y otras fábricas. Las fábricas estáticas pueden producir diferentes tipos de objetos que se derivan del tipo de retorno, pero el LSP debe aplicarse a todos los objetos producidos; sin embargo, no es necesario que las clases derivadas admitan los mismos métodos estáticos que la clase base. Si una clase admite un método de fábrica como 'Clone', se debe respetar el LSP y admitir una semántica similar en los subtipos. – supercat

+0

Para las fábricas que devuelven cosas de otros tipos, el artículo devuelto por una fábrica derivada debe ser utilizable como una instancia de un artículo que sería devuelto por la fábrica base. Entonces, si 'CarFactory' tiene un método' MakeCar() 'que devuelve' Car', que a su vez admite un método 'Drive()', uno debería poder llamar a 'SomeCarFactory.MakeCar(). Drive()' incluso si 'SomeCarFactory' es realmente un' FordFactory' (que hereda 'CarFactory') que devuelve' Ford' (que hereda 'Car'). – supercat

1

Esta es una pregunta obstinada, pero la manera en que suelo escribir la mía es tal que los parámetros adicionales no tienen nada que ver 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.

13

Definitivamente No.

constructores son normalmente especializados para los 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 puede 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 los métodos de instancia, no a los métodos de clase (constructores o cualquier otro método de clase).

Cuestiones relacionadas