stringtranslate.com

Diseño por contrato

Un esquema de diseño por contrato

El diseño por contrato ( DbC ), también conocido como programación por contrato , programación por contrato y programación de diseño por contrato , es un enfoque para diseñar software .

Prescribe que los diseñadores de software deben definir especificaciones de interfaz formales , precisas y verificables para los componentes de software , que amplíen la definición ordinaria de tipos de datos abstractos con precondiciones , poscondiciones e invariantes . Estas especificaciones se denominan "contratos", de acuerdo con una metáfora conceptual con las condiciones y obligaciones de los contratos comerciales.

El enfoque DbC supone que todos los componentes del cliente que invocan una operación en un componente del servidor cumplirán las condiciones previas especificadas como necesarias para esa operación.

Cuando esta suposición se considera demasiado arriesgada (como en la computación multicanal o distribuida ), se adopta el enfoque inverso , lo que significa que el componente del servidor prueba que todas las condiciones previas relevantes sean verdaderas (antes o mientras se procesa la solicitud del componente del cliente ) y responde con un mensaje de error adecuado si no es así.

Historia

El término fue acuñado por Bertrand Meyer en relación con su diseño del lenguaje de programación Eiffel y descrito por primera vez en varios artículos a partir de 1986 [1] [2] [3] y las dos ediciones sucesivas (1988, 1997) de su libro Object-Oriented Software Construction . Eiffel Software solicitó el registro de marca para Design by Contract en diciembre de 2003, y le fue concedido en diciembre de 2004. [4] [5] El propietario actual de esta marca es Eiffel Software. [6] [7]

El diseño por contrato tiene sus raíces en el trabajo sobre verificación formal , especificación formal y lógica de Hoare . Las contribuciones originales incluyen:

Descripción

La idea central de DbC es una metáfora sobre cómo los elementos de un sistema de software colaboran entre sí sobre la base de obligaciones y beneficios mutuos . La metáfora proviene de la vida empresarial, donde un "cliente" y un "proveedor" acuerdan un "contrato" que define, por ejemplo, que:

De manera similar, si el método de una clase en programación orientada a objetos proporciona una determinada funcionalidad, puede:

El contrato equivale semánticamente a un triple de Hoare que formaliza las obligaciones. Esto se puede resumir en las "tres preguntas" que el diseñador debe responder repetidamente en el contrato:

Muchos lenguajes de programación tienen facilidades para hacer afirmaciones como estas. Sin embargo, DbC considera que estos contratos son tan cruciales para la corrección del software que deberían ser parte del proceso de diseño. De hecho, DbC recomienda escribir las afirmaciones primero . [ cita requerida ] Los contratos pueden escribirse mediante comentarios de código , implementarse mediante un conjunto de pruebas o ambos, incluso si no existe un soporte de lenguaje especial para contratos.

La noción de contrato se extiende hasta el nivel de método/procedimiento; el contrato para cada método normalmente contendrá la siguiente información: [ cita requerida ]

Las subclases de una jerarquía de herencia pueden debilitar las precondiciones (pero no fortalecerlas) y fortalecer las poscondiciones y los invariantes (pero no debilitarlos). Estas reglas se aproximan a la subtipificación conductual .

Todas las relaciones de clase se dan entre clases de cliente y clases de proveedor. Una clase de cliente está obligada a realizar llamadas a las características del proveedor donde el estado resultante del proveedor no sea violado por la llamada del cliente. Posteriormente, el proveedor está obligado a proporcionar un estado de retorno y datos que no violen los requisitos de estado del cliente.

Por ejemplo, un búfer de datos de un proveedor puede exigir que los datos estén presentes en el búfer cuando se llama a una función de eliminación. Posteriormente, el proveedor garantiza al cliente que cuando una función de eliminación finaliza su trabajo, el elemento de datos se eliminará, de hecho, del búfer. Otros contratos de diseño son conceptos de invariante de clase . El invariante de clase garantiza (para la clase local) que el estado de la clase se mantendrá dentro de las tolerancias especificadas al final de cada ejecución de función.

Al utilizar contratos, un proveedor no debe intentar verificar que se cumplan las condiciones del contrato (una práctica conocida como programación ofensiva) ; la idea general es que el código debe "fallar estrepitosamente" y que la verificación del contrato es la red de seguridad.

La propiedad "fail hard" de DbC simplifica la depuración del comportamiento del contrato, ya que el comportamiento previsto de cada método está claramente especificado.

Este enfoque difiere sustancialmente del de la programación defensiva , en el que el proveedor es responsable de determinar qué hacer cuando se rompe una condición previa. En la mayoría de los casos, el proveedor lanza una excepción para informar al cliente de que se ha roto la condición previa y, en ambos casos (tanto en DbC como en la programación defensiva), el cliente debe determinar cómo responder a eso. En tales casos, DbC facilita el trabajo del proveedor.

El diseño por contrato también define criterios de corrección para un módulo de software:

El diseño por contrato también puede facilitar la reutilización del código, ya que el contrato para cada fragmento de código está completamente documentado. Los contratos para un módulo pueden considerarse como una forma de documentación del software sobre el comportamiento de ese módulo.

Implicaciones en el desempeño

Las condiciones del contrato nunca deben violarse durante la ejecución de un programa libre de errores. Por lo tanto, los contratos normalmente solo se verifican en modo de depuración durante el desarrollo del software. Más adelante, en el lanzamiento, las verificaciones del contrato se desactivan para maximizar el rendimiento.

En muchos lenguajes de programación, los contratos se implementan con assert . Las aserciones se compilan de forma predeterminada en modo de lanzamiento en C/C++ y se desactivan de manera similar en C# [8] y Java.

Al iniciar el intérprete de Python con "-O" (para "optimizar") como argumento, el generador de código Python también no emitirá ningún código de bytes para las afirmaciones. [9]

Esto elimina efectivamente los costos de tiempo de ejecución de las afirmaciones en el código de producción, independientemente de la cantidad y el gasto computacional de las afirmaciones utilizadas en el desarrollo, ya que el compilador no incluirá dichas instrucciones en la producción.

Relación con las pruebas de software

El diseño por contrato no reemplaza las estrategias de prueba habituales, como las pruebas unitarias , las pruebas de integración y las pruebas del sistema . Más bien, complementa las pruebas externas con pruebas internas propias que se pueden activar tanto para pruebas aisladas como en el código de producción durante una fase de prueba.

La ventaja de las pruebas internas es que pueden detectar errores antes de que se manifiesten como resultados no válidos observados por el cliente, lo que permite una detección más temprana y más específica de los errores.

El uso de afirmaciones puede considerarse una forma de oráculo de prueba , una forma de probar el diseño mediante la implementación del contrato.

Soporte de idiomas

Idiomas con soporte nativo

Los lenguajes que implementan la mayoría de las características de DbC de forma nativa incluyen:

Además, la combinación de métodos estándar en el Sistema de Objetos Common Lisp tiene los calificadores de método :beforey :afterque :aroundpermiten escribir contratos como métodos auxiliares, entre otros usos.

Véase también

Notas

  1. ^ Meyer, Bertrand: Diseño por contrato , Informe técnico TR-EI-12/CO, Interactive Software Engineering Inc., 1986
  2. ^ Meyer, Bertrand: Diseño por contrato , en Avances en ingeniería de software orientada a objetos , eds. D. Mandrioli y B. Meyer, Prentice Hall, 1991, págs. 1–50
  3. ^ Meyer, Bertrand: "Aplicación del "Diseño por contrato"", en Computer (IEEE), 25, 10, octubre de 1992, págs. 40-51.
  4. ^ "Registro en la Oficina de Patentes y Marcas de los Estados Unidos para "DISEÑO POR CONTRATO"". Archivado desde el original el 2016-12-21 . Consultado el 2009-06-22 .[ enlace muerto ]
  5. ^ "Registro en la Oficina de Patentes y Marcas de los Estados Unidos para el diseño gráfico con las palabras "Diseño por contrato"". Archivado desde el original el 21 de diciembre de 2016. Consultado el 22 de junio de 2009 .[ enlace muerto ]
  6. ^ "Estado de la marca registrada y recuperación de documentos - 78342277". Recuperación de solicitudes y registros de marcas registradas de la USPTO .
  7. ^ "Estado de la marca registrada y recuperación de documentos - 78342308". Recuperación de solicitudes y registros de marcas registradas de la USPTO .
  8. ^ "Afirmaciones en código administrado". Microsoft Developer Network . 15 de noviembre de 2016. Archivado desde el original el 22 de agosto de 2018.
  9. ^ Documentación oficial de Python, declaración assert
  10. ^ Bright, Walter (1 de noviembre de 2014). "Lenguaje de programación D, programación por contrato". Digital Mars . Consultado el 10 de noviembre de 2014 .
  11. ^ Hodges, Nick. "Escriba código más limpio y de mayor calidad con contratos de clase en Delphi Prism". Embarcadero Technologies. Archivado desde el original el 26 de abril de 2021. Consultado el 20 de enero de 2016 .
  12. ^ Findler, Felleisen Contratos para funciones de orden superior
  13. ^ "Documentación de la biblioteca estándar de Scala: afirmaciones". EPFL . Consultado el 24 de mayo de 2019 .
  14. ^ La tipificación fuerte como otro "cumplimiento de contrato" en Scala, consulte la discusión en scala-lang.org/.

Bibliografía

Enlaces externos