31 de septiembre de 2003, Vol. 4, No. 5. ISSN: 1607-5079
 
 
[contenidos de RDU...] [Ver ejemplares anteriores de RDU...] [Volver a la portada de RDU] [Busca en los archivos de RDU] [Recomienda RDU a un amigo]  

Gerardo Rossel
grossel@dc.uba.ar
[¿Cómo citar este artículo]
Andrea Manna
amanna@dc.uba.ar
[Bajar este artículo]

 

Las ideas del Diseño por Contratos (Bertrand, 1992, 1997 y Mitchell, 2002 ), tienen sus raíces en los métodos formales para la construcción de software, pero mantienen una visión más pragmática. Requieren muy poco esfuerzo extra pero generan software mucho más confiable. La importancia de comprender el diseño por contratos, queda clara en la afirmación del pionero de la ingeniería de software Tom DeMarco: “Yo creo que el uso de contratos a la Eiffel entre módulos es la no-práctica más importante en el mundo del software hoy. Por esto yo quiero decir que no hay ninguna otra práctica siendo impulsada actualmente que tenga mayor capacidad de mejorar la calidad del software producido.” (DeMarco 1997).

El diseño por contratos puede ser visto como la aplicación a la construcción de software de los contratos que rigen los asuntos de las personas. Cuando dos personas establecen un contrato se desprenden, de éste, las obligaciones y beneficios de cada una. Este tipo de contratos en software especifican, en forma no ambigua, las relaciones entre las rutinas y los llamadores de las mismas. Podemos ver un sistema como un conjunto de elementos de software interrelacionados, donde cada uno de los elementos tiene un objetivo con vistas a satisfacer las necesidades de los otros. Dichos objetivos son los contratos. Los contratos deben cumplir, por lo menos, con dos propiedades: ser explícitos y formar parte del elemento de software en sí mismo.

El Diseño por Contratos da una visión de la construcción de sistemas como un conjunto de elementos de software cooperando entre sí. Los elementos juegan en determinados momentos alguno de los dos roles principales proveedores o clientes. La cooperación establece claramente obligaciones y beneficios, siendo la especificación de estas obligaciones y beneficios los contratos. Un contrato entre dos partes protege a ambas. Por un lado protege al cliente por especificar cuanto debe ser hecho y por el otro al proveedor por especificar el mínimo servicio aceptable.

Siguiendo la metáfora de los contratos entre las personas, se puede ver el ejemplo propuesto en (Waldén,1995) que es a su vez una modificación del usado en (Meyer,1992.). Si alguien se encuentra en Estocolmo y necesita enviar un paquete importante a una dirección en la otra punta de la ciudad. Hay dos opciones: llevar el paquete uno mismo o enviarlo mediante alguna empresa de mensajería. Si se elige la segunda opción se establece un contrato entre el servicio de mensajería y el que necesita enviar el mensaje. En Estocolmo existe el servicio “Green Delivery” que es prestado mediante bicicleta. El siguiente cuadro muestra un resumen del acuerdo:


Claramente, las obligaciones de una parte son los beneficios de la otra parte. Una de las reglas más importantes para el diseño de contratos es el principio de No Cláusulas Ocultas. Es decir que, si el contrato establece que el cliente debe cumplir con determinado requisito, ese requisito es todo lo que el cliente debe cumplir, o sea, no hay sorpresas. Tómese en cuenta que existen regulaciones externas que forman parte del contexto más general donde se desenvuelve el contrato (el paquete no puede contener una bomba). En el software, estas regulaciones externas, como se verá luego, toman la forma de invariantes de clase.


 
Dado que los ejemplos que se mostrarán son realizados en el lenguaje Eiffel se usará la terminología del mismo (Meyer,1992b): las clases están compuestas de características ( features ) las cuales pueden ser rutinas (procedimientos o funciones) o atributos. En otros contextos la terminología cambia (funciones miembro y variables miembro en C++, métodos y variables de instancia en Smalltalk).


Los contratos de software se especifican mediante la utilización de expresiones lógicas ( más una forma de especificar el valor anterior a una computación: old ) denominadas aserciones. Existen diferentes tipos de aserciones. En el Diseño por Contratos se utilizan tres tipos de aserciones:

• Precondiciones
• Poscondiciones
• Invariante de Clase.

Antes de explicar las aserciones y su rol en el Diseño por Contratos, se detallará el concepto de tripleta de Hoare (Hoare 1969) la cual es una notación matemática que viene de la validación formal de programas. Sea A alguna computación y P, Q aserciones, entonces la siguiente expresión:

{ P } A { Q }

representa lo que se llama fórmula de corrección. La semántica de dicha fórmula es la siguiente: cualquier ejecución de A que comience en un estado en el cual se cumple P dará como resultado un estado en el cual se cumple Q. Por ejemplo

{ x > 10 } x := x /2 { x >= 5}

O sea que si se parte de un estado en el cual x es mayor que 10 y luego se aplica la computación x := x/2 entonces como resultado x será mayor o igual a 5. A la aserción P se la llama precondición y a Q se la llama poscondición. En el ejemplo la precondición es x > 10 y la poscondición x >=5.

 


Se puede entonces definir el principio de no-redundancia mencionado anteriormente: Bajo ninguna circunstancia el cuerpo de una rutina deberá chequear el cumplimiento de la precondición. La precondición compromete al cliente, ya que define las condiciones por las cuales una llamada a la rutina es válida. Las poscondiciones comprometen a la clase (donde se implementa la rutina) ya que establecen las obligaciones de la rutina. Es muy importante notar que la precondición y la poscondición que definen el contrato forman parte del elemento de software en sí.


D.R. © Coordinación de Publicaciones Digitales. DGSCA-UNAM