Diseño Por Contrato
El Diseño Por Contrato (Design by Contract - DbC) es una metodología para el diseño e implementación de aplicaciones y componentes popularizada por el lenguaje de programación Eiffel.
En Estados Unidos "Design by Contract" es una marca registrada, por lo que muchos desarrolladores lo llaman Programming by Contract (Programación por Contratos), o Contract Programming (Programación Contractual), o contract-first development (desarrollo con primero el contrato).
Contenido
Beneficios
- Una mejor comprensión de la programación orientada a objetos. Esto se debe a que el propio prototipo de un recurso de una clase es también parte del contrato que éste ofrece. Mediante razonamientos de este tipo, por ejemplo, se justifica el comportamiento covariante de los tipos de retornos de los métodos en Eiffel.
- Menos errores en el código gracias a una mejor representación de las especificaciones.
- Un sistema efectivo para detectar errores.
- Una forma práctica de documentar el código al mismo tiempo en que se programa.
- Una imbricación eficaz con los mecanismos de herencia y reutilización.
Descripción
La idea central de DbC es una metáfora sobre cómo interactuan los elementos de un sistema de software para colaborar entre si, basándose en obligaciones y beneficios mutuos. La metáfora proviene del mundo de los negocios, en donde un "cliente" y un "proveedor" firman un "contrato" que define por ejemplo:
- el proveedor debe brindar cierto producto (obligación) y tiene derecho a que el cliente le pague una cuota (beneficio).
- el cliente paga una cuota (obligación) y tiene derecho a obtener el producto (beneficio).
- ambas partes deben satisfacer ciertas obligaciones, como leyes y regulaciones, que se aplican a todos los contratos.
De manera similar, si una rutina de una clase en Programación Orientada a Objetos brinda cierta funcionalidad, podría:
- imponer ciertas obligaciones que se garanticen por cualquier módulo cliente que la invoque: la precondición de la rutina - una obligación del cliente, y un beneficio para el proveedor (la rutina en si misma), ya que la libera de tener que gestionar casos por fuera de la precondición.
- garantizar cierto comportamiento a la salida: la postcondición de la rutina - una obligación del proveedor, y obviamente un beneficio para el cliente.
- mantener cierta propiedad, asumida al momento de la entrada y garantizada a la salida: las invariantes de la clase.
El contrato es la formalización de estres obligaciones y beneficios. Se podría resumir al Diseño por Contrato por estas tres preguntas que el diseñador del compomnente debe preguntarse:
- ¿Qué espera?
- ¿Qué garantiza?
- ¿Qué mantiene?
Muchos lenguajes brindan facilidades para hacer verificaciones como estas. Sin embargo, DbC considera que los contratos son cruciales para crear software correcto, y que deben ser parte del proceso de diseño del software. De hecho, DbC fometa escribir primero las asersiones.
La noción de contrato se extiende hacia el nivel de los métodos/procedimientos; el contrato para cada método normalmente contendrá la siguiente información:
- tipos y valores aceptados y no aceptados para la entrada, y su significado.
- tipos y valores de retorno, y su significado.
- tipos y valores de error y condiciones de excepción, que puedan ocurrir, y su significado.
- efectos secundarios.
- precondiciones, que las subclases pueden debilitar (pero no reforzar)
- postcondiciones, que las subclases pueden reforzar (pero no debilitar)
- invariantes, que las subclases pueden reforzar (pero no debilitar)
- (raramente) garantías de rendimiento, por ejemplo, de tiempo o espacio utilizado.
Cuando se utilizan contratos, el código del programa por si mismo nunca debe intentar verificar las condiciones del contrato; la idea es que el código dbe "fallar duro", siendo la verificación del contrato la red de contención. Este concepto de "fallar duro" de DbC simplifica el debug del comportamiento del contrato, ya que el comportamiento requerido para cada rutina está claramente especificado.
Nunca se deben violar las condiciones del contrato en la ejecución del programa; por lo tanto se lo puede dejar activado para debug, o quitado completamente del código productivo por motivos de rendimiento.
Todas las relaciones de clases son entre clases Cliente y clases Proveedor. Una clase Cliente está obligada a hacer las llamadas al Proveedor
La Prueba Unitaria verifica módulos aislados, para comprobar si cumplen con el contrato asumiendo que los demás proveedores cumplen el suyo. La Prueba De Integracion comprueba que varios módulos funcionan correctamente entre si. El Diseño por Contrato también facilita la reutilización de código, ya que el contrato para cada pieza de código está completamente documentado. Los contratos de un módulo también puede verse como una forma de documentación para el comportamiento del módulo.
Herramientas
Hay varias herramientas que facilitan la implementación de DbC en en software.
Algunas herramientas de DbC para Java: