Principio de sustitución de Liskov - Liskov substitution principle

La sustituibilidad es un principio en la programación orientada a objetos que establece que, en un programa de computadora , si S es un subtipo de T, entonces los objetos de tipo T pueden ser reemplazados por objetos de tipo S (es decir, un objeto de tipo T puede ser reemplazado por cualquier objeto de un subtipo S) sin alterar ninguna de las propiedades deseables del programa (corrección, tarea realizada, etc.). Más formalmente, el principio de sustitución de Liskov ( LSP ) es una definición particular de una relación de subtipificación, denominada subtipificación conductual ( fuerte ) , que fue presentada inicialmente por Barbara Liskov en un discurso de apertura de la conferencia de 1988 titulado Jerarquía y abstracción de datos . Es una relación semántica más que meramente sintáctica, porque pretende garantizar la interoperabilidad semántica de tipos en una jerarquía, tipos de objetos en particular. Barbara Liskov y Jeannette Wing describieron el principio de manera sucinta en un artículo de 1994 de la siguiente manera:

Subtipo Requisito : Vamos a ser una propiedad comprobable acerca de los objetos de tipo T . Entonces debe ser cierto para los objetos de tipo S , donde S es un subtipo de T .

En el mismo artículo, Liskov y Wing detallaron su noción de subtipificación conductual en una extensión de la lógica de Hoare , que guarda cierta semejanza con el diseño por contrato de Bertrand Meyer en el sentido de que considera la interacción de la subtipificación con precondiciones , poscondiciones e invariantes .

Principio

La noción de Liskov de un subtipo conductual define una noción de sustituibilidad de objetos; es decir, si S es un subtipo de T , entonces los objetos de tipo T en un programa pueden ser reemplazados por objetos de tipo S sin alterar ninguna de las propiedades deseables de ese programa (por ejemplo, corrección ).

El subtipo de comportamiento es una noción más fuerte que el subtipo típico de funciones definidas en la teoría de tipos , que se basa solo en la contravarianza de los tipos de parámetros y la covarianza del tipo de retorno. El subtipo de comportamiento es indecidible en general: si q es la propiedad "el método para x siempre termina ", entonces es imposible para un programa (por ejemplo, un compilador) verificar que es cierto para algún subtipo S de T , incluso si q se cumple de t . No obstante, el principio es útil para razonar sobre el diseño de jerarquías de clases.

El principio de sustitución de Liskov impone algunos requisitos estándar en las firmas que se han adoptado en los lenguajes de programación orientados a objetos más nuevos (generalmente a nivel de clases en lugar de tipos; consulte subtipificación nominal frente a estructural para la distinción):

  • Contravarianza de tipos de parámetros de método en el subtipo.
  • Covarianza de tipos de retorno de método en el subtipo.
  • Los métodos del subtipo no pueden generar nuevas excepciones, excepto si son subtipos de excepciones generadas por los métodos del supertipo.

Además de los requisitos de firma, el subtipo debe cumplir una serie de condiciones de comportamiento. Estos se detallan en una terminología similar a la de diseño por metodología de contrato , lo que genera algunas restricciones sobre cómo los contratos pueden interactuar con la herencia :

  • Las condiciones previas no se pueden reforzar en el subtipo.
  • Las poscondiciones no se pueden debilitar en el subtipo.
  • Las invariantes deben conservarse en el subtipo.
  • Restricción del historial (la "regla del historial"). Los objetos se consideran modificables solo a través de sus métodos ( encapsulación ). Debido a que los subtipos pueden introducir métodos que no están presentes en el supertipo, la introducción de estos métodos puede permitir cambios de estado en el subtipo que no están permitidos en el supertipo. La restricción de la historia lo prohíbe. Fue el elemento novedoso introducido por Liskov y Wing. Una violación de esta restricción puede ejemplificarse definiendo un punto mutable como un subtipo de un punto inmutable . Esta es una violación de la restricción de la historia, porque en la historia del punto inmutable , el estado es siempre el mismo después de la creación, por lo que no puede incluir la historia de un punto mutable en general. Sin embargo, los campos agregados al subtipo pueden modificarse de manera segura porque no son observables a través de los métodos de supertipo. Por lo tanto, se puede definir un círculo con centro inmutable y radio mutable como un subtipo de un punto inmutable sin violar la restricción de la historia.

Orígenes

Las reglas sobre las condiciones previas y posteriores son idénticas a las introducidas por Bertrand Meyer en su libro de 1988 Construcción de software orientada a objetos . Tanto Meyer como luego Pierre America, quien fue el primero en usar el término subtipificación conductual , dieron definiciones teóricas de prueba de algunas nociones de subtipificación conductual, pero sus definiciones no tomaron en cuenta el alias que puede ocurrir en lenguajes de programación que admiten referencias o punteros. . Tener en cuenta el aliasing fue la principal mejora realizada por Liskov y Wing (1994), y un ingrediente clave es la restricción histórica. Según las definiciones de Meyer y América, un punto mutable sería un subtipo de comportamiento de un punto inmutable, mientras que el principio de sustitución de Liskov lo prohíbe.

Crítica

Si bien se usa ampliamente, se ha dicho que la caracterización de subtipos de comportamiento como la capacidad de sustituir objetos de subtipo por objetos de supertipo es defectuosa. No hace ninguna mención de las especificaciones , por lo que invita a una lectura incorrecta en el que la aplicación del supertipo se compara con la aplicación del subtipo. Esto es problemático por varias razones, una de las cuales es que no es compatible con el caso común en el que el supertipo es abstracto y no tiene implementación. Además, de manera más sutil, en el contexto de la programación imperativa orientada a objetos es difícil definir con precisión qué significa cuantificar universal o existencialmente sobre objetos de un tipo dado, o sustituir un objeto por otro. Cuando aplicamos subtipos, generalmente no estamos sustituyendo objetos de subtipo por objetos de supertipo, simplemente estamos usando objetos de subtipo como objetos de supertipo. Es decir, son los mismos objetos, los objetos de subtipo, los que también son objetos de supertipo.

En una entrevista en 2016, la propia Liskov explica que lo que presentó en su discurso de apertura fue una "regla informal", que Jeannette Wing propuso más tarde que "intentaran averiguar con precisión qué significa esto", lo que llevó a su publicación conjunta sobre comportamientos subtipificación, y de hecho que "técnicamente, se llama subtipificación conductual". Durante la entrevista, no utiliza terminología de sustitución para discutir los conceptos.

Ver también

Referencias

Bibliografía

Referencias generales

Referencias específicas

enlaces externos