Académique Documents
Professionnel Documents
Culture Documents
Resumen
El presente documento contiene un breve presentaci
on de la tecnica de
Dise
no por Contrato, un metodo eficaz para desarrollar software libre de
fallos (bugs) desde el inicio del desarrollo del mismo. En primer lugar se
expone la motivaci
on del Dise
no por Contrato. A continuaci
on, se describe
en que consiste el Dise
no por Contrato. Por u
ltimo se describe el caso del
Ariane 5, uno de los m
as famosos casos de desastres software donde el uso
del Dise
no por Contrato hubiese permitido ahorrar unos 500 millones de
d
olares.
1.
Introducci
on
1.1.
La t
ecnica del avestruz
1 public c l a s s MatrizCuadrada {
2
3
// Array b i d i m e n s i o n a l que r e p r e s e n t a l a m a t r i z
4
int [ ] [ ] matriz = null ;
5
6
/
7
Crea una m a t r i z cuadrada de l a dimensi
on i n d i c a d a
8
@param dimension La dimensi
o n de l a m a t r i z a s e r c r e ada
9
/
10
public MatrizCuadrada ( i n t d i m e n s i o n ) {
11
m a t r i z = new i n t [ d i m e n s i o n ] [ d i m e n s i o n ] ;
12
} // M at r i z
13
14
/
15
Asigna un v a l o r a l e l e m e n t o ( i , j ) de l a m a t r i z
16
@param i F i l a d e l e l e m e n t o a s e r a s i g n a d o
17
@param j Columna d e l e l e m e n t o a s e r a s i g n a d o
18
@param v a l o r Valor a s e r a s i g n a d o a l e l e m e n t o ( i , j )
19
/
20
public void s e t ( i n t i , i n t j , i n t v a l o r ) {
21
this . matriz [ i ] [ j ] = valor ;
22
} // s e t
23
24
/
25
Devuelve e l v a l o r d e l elemento ( i , j )
26
@param i La f i l a d e l e l e m e n t o a s e r d e v u e l t o
27
@param j La columna d e l e l e m e n t o a s e r d e v u e l t o
28
@return El v a l o r d e l e l e m e n t o en l a p o s i c i o
n ( i , j )
29
/
30
public i n t g e t ( i n t i , i n t j ) {
31
return m a t r i z [ i ] [ j ] ;
32
} // g e t
33
34
/
35
D e v u e l v e l a dimensi
o n de l a m a t r i z
36
@return La dimensi
o n de l a m at r i z , e s d e c i r , a l s e r
37
cuadrada , su n
u mero de f i l a s o columnas
38
/
39
public i n t g e tD i m e n s i o n ( ) {
40
return t h i s . m a t r i z . l e n g t h ;
41
} // dimension
42
43 } // M at r i z
1 public void s e t ( i n t i ,
2
i f ( ( 0 <= i ) && ( i <
3
(0 <= j ) && ( j
4
matriz [ i ] [ j ] =
5
} // i f
6 } // s e t
1 public void s e t ( i n t i , i n t j , i n t v a l o r ) {
2
i f ( ( 0 <= i ) && ( i < m a t r i z . l e n g t h ) &&
3
(0 <= j ) && ( j < m a t r i z [ 0 ] . l e n g t h ) ) {
4
matriz [ i ] [ j ] = valor ;
5
} else {
6
throw new IndexOutOfBoundsException ( ) ;
7
} // i f
8 } // s e t
1.2.
Lanzamiento de Excepciones
1 public void s e t ( i n t i , i n t j , i n t v a l o r ) {
2
i f ( ( 0 <= i ) && ( i < m a t r i z . l e n g t h ) &&
3
(0 <= j ) && ( j < m a t r i z [ 0 ] . l e n g t h ) ) {
4
matriz [ i ] [ j ] = valor ;
5
} else {
6
System . out . p r i n t l n ( ERROR: MatrizCuadrada . s e t : +
7
I n d i c e s ( + i + , + j + ) f u e r a de r a n g o ) ;
8
} // i f
9 } // s e t
2.
Dise
no por Contrato
El dise
no por contrato es una tecnica de dise
no software introducida por
Bertrand Meyer [Jezequel and Meyer, 1997, Meyer, 2000, 2009], cuyo objetivo
es aumentar la fiabilidad de los programas software mediante la especificacion
de contratos.
Un contrato, informalmente hablando, establece en que condiciones es seguro
realizar una llamada a un metodo, y que es lcito considerar como cierto tras
la ejecucion de dicho metodo. Desde un punto de vista formal, un contrato de
un metodo M se define como una tripleta {P }M {Q}, donde P y Q reciben el
nombre de precondici
on y postcondici
on respectivamente.
Tanto las precondiciones como las precondiciones son f
ormulas l
ogicas, del
tipo (x > 0) (y > 0). El significado de un contrato es siempre que se invoque al metodo M de forma que la precondici
on se satisfaga, es decir, que P
sea verdadero, el metodo M termina y a su finalizaci
on la postcondici
on Q es
verdadera.
Es decir, la precondici
on establece las condiciones que tiene que cumplir
cualquier programa que invoque al metodo M ; mientras que la postcondici
on
indica a que se compromete el metodo M siempre y cuando su precondici
on
se satisfaga. Como si de un contrato de la vida real se tratase, ambas partes
se comprometen a algo. En adelante denominaremos al programa que invoca al
metodo M el cliente; y al metodo M el proveedor. De esta forma, la precondici
on
establece las garantas que debe ofrecer el cliente al proveedor, mientras que la
postcondici
on establece las garantas que debe ofrecer el proveedor al cliente.
Debe advertirse que la definici
on de contrato establece que el metodo M
debe terminar en un estado que satisfaga la postcondici
on solo en los casos
en que la precondici
on se satisface. En caso de que dicha precondici
on no se
satisfaga, el metodo M no tiene porque terminar en un estado que satisfaga la
postcondici
on, de hecho no tiene ni porque terminar. Esto significa que siempre
que no se satisfaga la precondici
on, el metodo M puede hacer lo que le venga
en gana, porque al violar el cliente las condiciones del contrato, el contrato se
anula. Es responsabilidad del cliente asegurar que cada peticion al proveedor
satisface las precondiciones del contrato.
Por ejemplo, para el metodo set de la clase MatrizCuadrada se podra definir
el contrato que se muestra en la Figura 5. La precondici
on asegura que los
ndices del elemento a modificar esten dentro de las dimensiones de la matriz.
La postcondici
on indica que si inmediatamente despues de realizar una llamada
al metodo set realizamos una llamada al metodo get con los mismo ndices,
1
2
3
4
5
6
Figura 6: C
odigo libre de llamadas erroneas
obtendremos el valor que acabamos de escribir.
El lector no obstante podra argumentar sino estara de mas verificar al
comienzo de cada metodo que la precondici
on del mismo se satisface, tal como
ocurre, por ejemplo, en el caso de la tecnica de la avestruz segura (ver Figura 2).
Antes de responder a esta pregunta, examinemos el codigo de la Figura 6. En
este caso puede observarse que, por la propia construccion de los bucles, nunca se
realizara una llamada con valores incorrectos para los par
ametros i y j. Por tanto,
si el metodo set comprobase que los valores de los par
ametros son correctos,
estaramos haciendo un trabajo redundante e in
util. Ello nos lleva a enunciar el
principio de no redundancia.
Principio de No Redundancia
Bajo ning
un concepto debe el cuerpo de un metodo verificar el
cumplimiento de la precondici
on de la rutina.
Por tanto, siguiendo un esquema de dise
no por contrato, cada metodo debe
declarar las precondiciones bajo las cuales tiene sentido o es factible que dicho
metodo realice su trabajo y termine de forma que satisfaga su postcondici
on.
Son los clientes de los metodos los que tienen que asegurar que no se realizan llamadas a dichos metodos que no satisfagan las precondiciones. Para ello deberan
realizar todas las comprobaciones que se consideren necesarias. Por ejemplo, en
el caso de la Figura 6, por la propia construccion del programa, no es necesario
realizar comprobacion alguna por parte del cliente.
En caso de que se realice una llamada a un metodo que no satisfaga las
7
1 public c l a s s CuentaBancaria {
2
3
protected double t o t a l I n g r e s o s = 0 . 0 ;
4
protected double t o t a l G a s t o s
= 0.0;
5
protected double s a l d o A c t u a l
= 0.0;
6
7
/
8
R e i n t e g r a a l due
n o de l a c u e n t a b a n c a r i a l a c a n t i d a d
indicada
9
@param c a n t i d a d La c a n t i d a d a s e r r e i n t e g r a d a
10
/
11
public void s a c a r D i n e r o ( double c a n t i d a d ) {
12
this . totalGastos = this . totalGastos + cantidad ;
13
this . saldoActual = this . saldoActual cantidad ;
14
} // s ac ar D i n e r o
15
16 } // CuentaBancaria
3.
sentencias al mismo tiempo, o aunque podamos, no hay una razon de peso para
hacerlo.
En general, el orientaci
on a objetos se considera que es perfectamente v
alido
violar el invariante durante la ejecucion de un metodo p
ublico, siempre y cuando
se garantice que el invariante se satisface tanto al comienzo como al final de
la llamada a dicho metodo. Por tanto, al igual que con las precondiciones, el
cliente debe asegurarse de que todos los invariantes de la aplicaci
on se satisfacen
antes de realizar una llamada a un metodo; y como si de una postcondici
on se
tratase, el cuerpo de un metodo debe asegurarse de que el invariante se sigue
satisfaciendo al final de su ejecucion (aunque en medio de la ejecucion se puede
haber violado el invariante repetidas veces.)
4.
El modulo software del SRI se haba reutilizado tal cual del proyecto Ariane
4. Esta
es tambien una decision loable y acertada por parte de los ingenieros
del Ariane 5. Si existe un m
odulo software que sirve para resolver nuestra tarea,
y dicho modulo software ademas tenemos la garanta de que ha sido probado
y funciona correctamente (el proyecto del Ariane 4 fue un exito), lo l
ogico y lo
recomendado es usarlo, en lugar de crear uno nuevo.
El motivo por el cual no exista manejador para dicha excepci
on es, que
por ciertos motivos de seguridad, la carga de trabajo del procesador del SRI no
poda ser superior al 80 %. Para mantener la carga de trabajo dentro los lmites
establecidos, solo se crearon manejadores de excepci
on para las conversiones de
variables que eran susceptibles de provocar desbordamientos aritmeticos. Dada
la trayectoria del Ariane 4, se poda asegurar con total certeza que ciertas conversiones no iban a provocar jamas desbordamientos, porque el rango de valores
que podan recibir estas variables nunca iban a provocar desbordamientos. Por
tanto, los ingenieros del Ariane 4 decidieron no crear manejadores de excepci
on
para aquellas conversiones para las cuales saban con absoluta certeza que eran
seguras. Al eliminar dichos manejadores, aseguraban tambien que la ocupaci
on
del procesador del SRI se mantena dentro del lmite del 80 % establecido. Por
tanto, la decision de eliminar estos manejadores dentro del proyecto del Ariane
4 se debe considerar tambien como una decision acertada. En todos los proyectos software es frecuente tomar decisiones de compromiso entre fiabilidad y
eficiencia.
El verdadero problema fue que cuando los ingenieros del Ariane 5 reutilizaron
el modulo software del SRI para el Ariane 4 desconocan las decisiones que
haban tomado los ingenieros del Ariane 4 comentadas en el p
arrafo anterior. El
Ariane 5 tena una trayectoria de vuelo diferente a la del Ariane 4, por lo cual
las conversiones de variables que eran seguras para el Ariane 4, es decir, pasaban
a ser inseguras dada la trayectoria del Ariane 5. No obstante, los ingenieros del
Ariane 5 desconocan este hecho puesto que no haba sido hecho explcito en
ninguna parte.
Por tanto, la verdadera causa del problema que origin
o la explosi
on del
Ariane 5 fue que los ingenieros del Ariane 5 reutilizaron un modulo software
del cual desconocan sus precondiciones. En tiempo de ejecucion se produjo
una llamada a dicho modulo que no satisfaca estas precondiciones, por lo que
se produzco una excepci
on que caus
o la parada del sistema y la consiguiente
explosi
on. Si las precondiciones del modulo reutilizado del Ariane 4 hubiesen
estado disponibles, los ingenieros del Ariane 5 hubiesen podido comprobar que
no se producan llamadas incorrectas a dicho modulo. Dada la trayectoria del
Ariane 5, los ingenieros hubiesen detectado que ciertos par
ametros, en el caso
particular del Ariane 5, podan tomar valores incorrectos, realizando las acciones
oportunas para prevenir dicho error.
Por tanto el verdadero fallo fue que los ingenieros del Ariane 4 no hicieron
explcitas las precondiciones del modulo software para el SRI, y que los ingenieros del Ariane 5 reutilizaron dicho modulo software asumiendo que dichas
precondiciones no existan.
Adviertase que si hubiese existido un manejador para la excepcion que pro10
5.
Sumario
Referencias
Jean-Marc Jezequel and Bertrand Meyer. Design by Contract: The Lessons of
Ariane. IEEE Computer, 30(1):129130, 1997.
11
12