Principio de sustitución de Liskov (LSP)

Hoy vamos un poco a la teoría, he escrito varios post sobre la herencia y la programación orientado a objetos, temas que van muy de la mano y cuyo fundamento se basa en el principio que da título a este post.

Este principio fue escrito por Bárbara Liskov en su trabajo sobre abstracción de tipos de datos y está relacionado con un principio que se podría decir que nació junto con la programación orientada a objetos, el diseño por contratos.

¿Cansado de datos históricos? Vamos al grano. El principio dice que cualquier función que utilice una referencia a una clase base debe ser capaz de usar cualquier clase derivada sin saberlo. Es decir que el cliente usa una referencia a la clase base, sin saber si se usa la clase derivada A o la B.

No basta con "ser" hay que "comportarse como tal".

Para lograr esto, hay que usar abstracción de datos y polimorfismo, que son las bases del principio de abierto cerrado. El Principio de sustitución de Liskov se usa para medir el correcto uso de una herencia, primero se busca abstraer y luego implementar.

oop-sampleExiste una fuerte relación entre el LSP y el concepto de diseño por contrato, usando este último los métodos de una clase declaran pre-condiciones y post-condiciones. Las primeras deben ser verdaderas para que el método se ejecute. Una vez terminado, el método garantiza que las post-condiciones sean ciertas. Usando LSP, la pre-condición se traduce a que cualquier clase derivada debe aceptar cualquier cosa que la clase base puede aceptar, mientras la post-condición se traduce a que las clases derivadas deben ajustarse a todas la post-condiciones de la clase base. Es decir, sus comportamientos y los resultados no deben infringir ninguna de las limitaciones establecidas para la clase base. Los usuarios de la clase base no debe confundirse ante una nueva clase derivada.

Por tanto, se deben tener dos criterios para usar clases bases, uno es dar a una aplicación un comportamiento común, y el otro usar métodos de ayuda para las clases derivadas. Pero sobre todo lo primero. Yo puedo crear un formulario base porque quiero que todos los formularios tengan el mismo comportamiento frente a un evento concreto, pero también lo puedo hacer para tener funciones de ayuda. Siempre es preferible el primer criterio porque el segundo criterio lo puedo aislar luego en una clase de ayuda de simple instancia y llevármelo a otro proyecto.

Resumiendo podemos decir que un sistema que use este principio será más fácil de mantener que otro que no lo use. Este principio está relacionado con otros como cohesión o acoplamiento entre clases (No hables con extraños) y con los patrones de diseño de tipo factorías (¿cómo se si debo desde el cliente usar la clase A o la B?)

Aquí os dejo un enlace a otro post muy interesante con ejemplos sobre Herencia de clases y el Principio de Liskov.

Comentarios