Sie sind auf Seite 1von 60

Tipos Abstractos de Datos y Diseo por Contrato

1.- Motivacin de los tipos abstractos de datos


Nuestro objetivo es obtener descripciones apropiadas de los objetos, para lo cual se necesita un
mtodo que satisfaga tres condiciones:
Las descripciones deben ser precisas y no ambiguas.
Deberan ser completas, o al menos tan completas como sea necesario en cada caso. Qui! se
decidan omitir algunos detalles.
No deberan especificar m!s de lo necesario.
"l #ltimo punto es el que $ace que la respuesta no sea trivial. Despus de todo es f!cil ser preciso,
no ambiguo y completo si se %descorre la cortina& y se dejan ver todos los detalles de la
representaci'n de los objetos. (ero normalmente esto es demasiada informaci'n para los creadores
de elementos soft)are que necesitan acceder a los objetos. *l proporcionar el c'digo fuente de la
clase como fuente primaria de informaci'n para los creadores de elementos soft)are que se apoyan
en dic$o clase, lo que ocurre es que se permite que los elementos soft)are usen un objeto de una
cierta clase tomando como base una informaci'n que ata+e m!s a la representaci'n del objeto que a
sus propiedades esenciales, lo que implica que estamos sumergiendo a los creadores de elementos
soft)are en un mar de detalles, impidindoles concentrarse en su propio trabajo y poniendo
obst!culos para nuestras esperanas de una evoluci'n suave del soft)are.
"s m!s, distintas clases, que por tanto muy probablemente definen estructuras de datos distintas
entre s, pueden compartir las mismas propiedades esenciales. De $ec$o, cada una de estas
estructuras de datos es una representaci'n posible de las mismas propiedades esenciales, y adem!s
cada una de estas representaciones posibles es #til en determinados casos. ,eleccionar una de ellas
como la definici'n de dic$as propiedades esenciales sera realmente utiliar una representaci'n
particular como especificaci'n y sera adem!s un caso tpico de especificar m!s de lo necesario. "s
m!s, no $ay forma de justificar que una de las representaciones es m!s representativa que otra dado
que la mayora de la informaci'n propia de la representaci'n del objeto es irrelevante para
comprender las propiedades esenciales del mismo.
"ntonces, -c'mo conservar la completitud, la precisi'n y la no ambig.edad sin pagar el precio de
una especificaci'n e/cesiva0 La respuesta es que si ocurre que dos o m!s representaciones distintas
entre s 1que por tanto $an sido definidas en clases tambin distintas entre s y donde cada
representaci'n o estructura de datos describe la forma de los objetos de la clase que la define1
comparten las mismas propiedades esenciales es porque $ay algo que las une. (ues bien, lo que une
a las diferentes representaciones a pesar de todas sus diferencias es que los respectivos conjuntos de
objetos asociados a cada una tienen todos en com#n ciertas operaciones que goan de ciertas
propiedades. ,i se centra la atenci'n no en una forma particular de representaci'n sino en estas
operaciones y sus propiedades, se puede obtener una caracteriaci'n abstracta y #til de esas
propiedades esenciales.
2a $emos establecido el porqu de nuestra b#squeda de una manera de describir apropiadamente los
objetos. *nte estos problemas, la teora formal de los tipos abstractos de datos es la respuesta, ya
que proporciona el modo de lograr una especificaci'n de los objetos que es completa y precisa, no
e/cesiva y carente de ambig.edad, centr!ndose, para lograr tales fines, en describir las propiedades
esenciales de los objetos en ve de su representaci'n fsica. De $ec$o, la teora formal de los tipos
abstractos de datos es la base te'rica del mtodo orientado a objetos, y en verdad lo que $ace esta
teora es e/presar formalmente la idea ya presente en el mtodo orientado a objetos de que los
objetos que describe una clase se definen #nicamente por lo que se puede $acer con ellos: los
mtodos 1o rutinas1 y las propiedades formales de estos mtodos 1los contratos1.
La falta de una forma de describir apropiadamente los objetos no s'lo ocasiona los problemas
indicados m!s arriba. De $ec$o, el impacto de todas estas ideas en la pr!ctica es realmente
importante. ,e estima que el 345 del coste del soft)are se dedica al mantenimiento. * su ve, m!s
del 635 del coste del mantenimiento proviene de la necesiad de tener en cuenta cambios en los
formatos de los datos. 7ay demasiados sistemas soft)are que est!n muy estrec$amente ligados a la
estructura fsica de los datos que manipulan. ,i un mtodo de desarrollo de soft)are se basa en la
representaci'n fsica de las estructuras de datos para guiar el an!lisis y el dise+o, es probable que no
sea adecuado para producir soft)are fle/ible. "s importante tener claro entonces que es una
necesidad evitar asociar el soft)are con las representaciones fsicas e/actas de los datos.
*ntes de que alguien se $aga la pregunta, es conveniente tener claro que la cuesti'n no es que
alguna parte del sistema soft)are conoca la representaci'n fsica de los datos: esto es inevitable
puesto que los datos deben ser accedidos finalmente para su manipulaci'n interna, sino que con los
mtodos tradicionales de dise+o este conocimiento se distribuye sobre muc$as partes del sistema,
provocando modificaciones injustificadamente grandes en los sistemas soft)are en el momento en
que cambia alguna de las representaciones fsicas de los datos 1como inevitablemente ocurrir! tarde
o temprano. ,i cambia el formato de los datos, es raonable suponer que un sistema soft)are que
manipule dic$os datos necesite ser adaptado8 lo que no es aceptable es que esa necesidad se
e/tienda a todo el sistema, de tal modo que un cambio en dic$o formato cause cambios en el
sistema soft)are en una magnitud desproporcionada con el tama+o conceptual del cambio en la
especificaci'n.
2.- Concepto y definicin de un tipo abstracto de datos
9na confusi'n $abitual es considerar que el concepto matem!tico de conjunto es el m!s indicado
para e/plicar qu es un tipo de datos8 sin embargo, el concepto matem!tico m!s apropiado para
e/plicar la naturalea de un tipo de datos es el de !lgebra.
9n tipo de datos es un !lgebra, es decir, un conjunto de valores, llamado dominio, caracteriados
por el conjunto de operaciones que sobre ellos se pueden aplicar y por el conjunto de propiedades
que dic$as operaciones poseen y que determinan inequvocamente su comportamiento.
9n valor perteneciente al dominio de un tipo de datos se denomina una instancia o ejemplar del
tipo de datos.
9n tipo abstracto de datos es un tipo de datos que se define mediante una especificacin que es
independiente de cualquier implementacin.
(or tanto, la especificaci'n del tipo abstracto de datos es la definici'n del mismo. La idea principal
que est! detr!s de la palabra %abstracto& es precisamente la separaci'n e independencia de la
especificaci'n del tipo abstracto de datos de una implementaci'n suya.
:eamos con detenimiento lo que supone la independencia de la especificaci'n respecto de una
implementaci'n suya. La especificaci'n del tipo abstracto de datos describe el comportamiento
e/terno del mismo, es decir, qu $ace el tipo abstracto de datos, mientras que una implementaci'n
suya describe c'mo lo $ace. La especificaci'n es independiente de cualquier implementaci'n
puesto que no es necesario saber nada de sta para desarrollar aqulla8 sin embargo, cualquier
implementaci'n es dependiente de la especificaci'n correspondiente ya que se lleva a cabo
bas!ndose en sta, puesto que para que una implementaci'n sea correcta debe conservar las
propiedades de la especificaci'n que dice implementar. *dem!s, una misma especificaci'n puede
tener varias implementaciones asociadas, cada una con sus propios requisitos de consumo de
espacio de memoria y de tiempo de ejecuci'n, de manera que puede variar qu implementaci'n es
la m!s apropiada usar en un conte/to dado seg#n los requerimientos de ste.
:eamos a$ora con detenimiento lo que supone la separaci'n de la especificaci'n respecto de una
implementaci'n suya. La separaci'n de la especificaci'n del tipo abstracto de datos de su
implementaci'n implica que sta es inaccesible a los clientes, lo que ayuda a stos a la producci'n
de soft)are correcto ya que se evitan los errores debidos al conocimiento de la implementaci'n del
tipo abstracto de datos. "ste ocultamiento de la informaci'n de la implementaci'n al cliente
tambin ayuda a que ste no se despiste en un mar de detalles a la $ora de desarrollar sus propios
elementos soft)are. (or todo ello, desde la perspectiva del cliente, no es deseable acceder a la
implementaci'n del tipo abstracto de datos para poder usar dic$a implementaci'n8 pero, adem!s, es
que tampoco es necesario ya que el cliente, para poder usar una implementaci'n de un tipo
abstracto de datos, s'lo necesita conocer qu $ace ste, es decir, su especificaci'n.
* partir de a$ora abreviaremos a veces Tipo Abstracto de Datos con el acr'nimo TAD. "n ingls
el acr'nimo es ADT, de Abstract Data Type.
3.- Especificacin de un tipo abstracto de datos
3.1.- Motivacin de la especificacin foral de un TAD
* continuaci'n vamos a estudiar c'mo desarrollar la especificaci'n de un ;*D, para lo que vamos a
tomar como ejemplo el ;*D Pila.
De manera informal, podemos definir o especificar el ;*D Pila como el conjunto de las pilas tal
que una pila es una secuencia de elementos, que puede estar vaca, tal que un #nico e/tremo,
conocido como la cima, es el que se usa para insertar y recuperar elementos, de modo que el #ltimo
que entra es el primero que sale, comportamiento conocido en ingls por las siglas LIFO <Last In
First Out=, es decir, que el #ltimo elemento que se inserta en la pila es el primero que se recupera.
"l ;*D Pila tiene tpicamente disponibles las siguientes operaciones de inters:
9na orden que pone un elemento en la cima de la pila. Llamaremos a esta operaci'n apila.
9na orden que quita el elemento que est! en la cima de la pila, si sta no est! vaca. ,e la
llamar! desapila.
9na consulta para ver cu!l es el elemento que est! en la cima de la pila, si sta no est! vaca.
,e la llamar! cima.
9na consulta para determinar si la pila est! vaca, lo que permite a los clientes determinar de
antemano si pueden $acer desapila o cima. Llamaremos a esta operaci'n vaca.
9na constructora que proporciona una pila inicialmente vaca. Llamaremos a esta operaci'n
crea.
"s verdad que la elecci'n de los nombres de las operaciones es totalmente arbitraria en el sentido de
que cambiar el nombre de una operaci'n no altera las propiedades que cumple, y as, por ejemplo,
se podra $aber escogido el nombre a en lugar de apila, d en lugar de desapila, c en lugar de cima, v
en lugar de vaca y cr en lugar de crea8 o, lo que es peor, $aber escogido el nombre de apila en
lugar de desapila, desapila en lugar de cima, cima en lugar de vaca, vaca en lugar de crea y crea
en lugar de apila. ,in embargo, no podemos por ello concluir que la elecci'n de los nombres es un
mero asunto de cosmtica. *unque es informaci'n puramente subjetiva la que proporcionan los
nombres de las operaciones, es bien cierto que los nombres significativos contribuyen a facilitar la
comprensi'n del comportamiento de la operaci'n, lo que facilita el desarrollo de soft)are
reutiliable. No $ay que olvidar que un buen soft)are reutiliable es un soft)are que proporciona
una funcionalidad correcta y que la proporciona con nombres correctos.
9na especificaci'n de un ;*D como la anterior dada en lenguaje natural es informal. "s el primer
paso para la comprensi'n del ;*D, pero es evidente que las descripciones informales como las
anteriores no son suficientes. Las especificaciones dadas en lenguaje natural tienden a ser
imprecisas, ambig.as, redundantes, incompletas, verbosas y a menudo meclan de manera aleatoria
diferentes niveles de abstracci'n 1es decir, no est!n en una forma bien estructurada1. Dado que es
necesario conocer con precisi'n c'mo los clientes pueden utiliar estas operaciones y lo que ellas
realiar!n para estos clientes, es necesario un paso m!s que consiste en llevar a cabo una
especificaci'n del ;*D que sea formal. :amos a ver una tcnica para especificar formalmente tipos
abstractos de datos, conocida como especificacin algebraica o ecuacional.
3.2.- !i"natura de la especificacin foral de un TAD
9na especificaci'n formal algebraica de un tipo abstracto de datos consta de cuatro p!rrafos o
cl!usulas: TIPO, FUNCIONES, AIO!AS y P"ECONDICIONES.
"l p!rrafo TIPO indica el nombre del ;*D que se define en la especificaci'n.
TIPO
Pila[G]
La especificaci'n ser! la de un ;*D Pila#$%, que describe las pilas de elementos de un ;*D
arbitrario $. "n Pila#$%, $ denota un ;*D arbitrario y no concretado. $ se denomina parmetro
genrico formal del ;*D Pila#$% y se dice que Pila#$% es un ;*D genrico. "l mecanismo que
permite este tipo de especificaci'n parametriada se conoce con el nombre de genericidad.
"s posible escribir especificaciones de tipos abstractos de datos sin genericidad, pero al precio de
repeticiones injustificadas. -De qu sirve tener especificaciones separadas para los tipos abstractos
de datos %pilas de cuentas bancarias&, %pilas de enteros& y dem!s0 "stas especificaciones seran
idnticas e/cepto all! d'nde se refieran e/plcitamente al ;*D de los elementos de la pila 1cuentas
bancarias o enteros en nuestros ejemplos1. "scribir estas especificaciones y llevar a cabo despus la
sustituci'n de los tipos abstractos de datos manualmente resultara tedioso. La reutiliaci'n es
deseable no s'lo para los programas sino >tambin para las especificaciones? @racias a la
genericidad se puede $acer e/plcita la parametriaci'n de tipos abstractos de datos escogiendo
alg#n nombre arbitrario, en este caso $, para representar el ;*D variable de los elementos de las
pilas.
Aomo resultado, siendo rigurosos, un TAD genrico como Pila#$% no es ya e/actamente un ;*D,
sino un patrn de tipos abstractos de datos, lo que implica, si no olvidamos que un ;*D es un
tipo de datos, que un ;*D genrico como Pila#$% es un tipo de datos genrico y, por tanto, no es
ya tampoco e/actamente un tipo de datos, sino un patrn de tipos de datos. (ara obtener un ;*D 1
y, por tanto, un tipo de datos1 directamente utiliable, se debe conseguir un cierto ;*D 1que, por
tanto, es un cierto tipo de datos1, por ejemplo el ;*D Cuenta que modela las cuentas bancarias, y
$ay que proporcionarlo como parmetro genrico real correspondiente al par!metro genrico
formal $. De modo que aunque Pila#$% en en s un patr'n de tipos abstractos de datos 1y por ende
un patr'n de tipos de datos1, la notaci'n Pila#Cuenta% e/presa un ;*D totalmente definido y, por
tanto, tambin es un tipo de datos totalmente definido. ;al ;*D y, por tanto, tambin tal tipo de
datos, obtenido al proporcionar par!metros genricos reales a un ;*D genrico 1que, por tanto, es
un tipo de datos genrico1, se dice que es derivado genricamente.
Las nociones que se acaban de ver se pueden aplicar recursivamente, de manera que un ;*D que se
utilia como par!metro genrico real de Pila#$% para producir un ;*D derivado genricamente
puede ser a su ve derivado genricamente, de modo que es perfectamente correcto utiliar la
notaci'n Pila#Pila#Cuenta%% para nombrar un ;*D y, por consiguiente, un tipo de datos:
intuitivamente puede entenderse que las instancias de este ;*D 1y, por tanto, las instancias de este
tipo de datos1 son pilas, cuyos elementos son a su ve pilas de cuentas bancarias8 los elementos de
estas #ltimas pilas son cuentas bancarias. "stricamente $ablando, por tanto, una pila particular es
una instancia no de Pila#$% 1porque como $emos visto es m!s un patr'n de tipos abstractos de
datos que un ;*D y, por tanto, es m!s un patr'n de tipos de datos que un tipo de datos1 sino de
alg#n ;*D derivado genricamente 1por tanto, de alg#n tipo de datos derivado genricamente1 de
Pila#$%, como por ejemplo Pila#Cuenta%.
9na ve $ec$a la aclaraci'n, seguiremos en ocasiones, por sencille y donde no d lugar a
confusi'n, $ablando tanto del ;*D como del tipo de datos Pila#$%, e igualmente de las instancias
de Pila#$%, comprendiendo que realmente se est! $ablando tanto de un patr'n de tipos abstractos de
datos como de un patr'n de tipos de datos, e igualmente de una instancia de una de sus derivaciones
genricas, respectivamente.
Despus del p!rrafo TIPOS viene el p!rrafo FUNCIONES, que enumera las operaciones aplicables
a las instancias del ;*D. "stas operaciones ser!n las componentes esenciales de la definici'n del
;*D ya que describen sus instancias no por lo que son sino por lo que tienen que ofrecer. *
continuaci'n se puede ver el p!rrafo FUNCIONES para el ;*D Pila#$%:
FUNCIONES
apila: Pila[G] x G Pila[G]
desapila: Pila[G] Pila[G]
cima: Pila[G] G
vaca: Pila[G] Boolean
crea: Pila[G]
"n una especificaci'n algebraica, cada operaci'n de un ;*D se modela mediante una funci'n
matem!tica. De a$ la notaci'n funcional empleada arriba. Aomo sabemos, una funci'n matem!tica
es un mecanismo para obtener un resultado que pertenece a un cierto conjunto destino a partir de
alguna posible entrada que pertenece a un cierto conjunto origen. 9na funci'n matem!tica no
produce efectos laterales ni cambios de ninguna clase. "n matem!ticas el concepto de cambiar algo
no e/iste como tal. * diferencia de la ejecuci'n de un sistema soft)are en un computador, evaluar
una e/presi'n matem!tica nunca cambia un elemento involucrado en ella8 as, por ejemplo, calcular
la ra cuadrada del n#mero B no modifica el valor de dic$o n#mero. (or lo tanto, la funci'n
matem!tica
apila: Pila[G] x G Pila[G]
significa que apila tiene dos argumentos, una Pila de instancias de $ y una instancia de $, y
produce como resultado, no la pila ya e/istente del primer argumento modificada con un elemento
adicional en la cima de la pila, sino una nueva Pila de instancias de $ que tiene los mismos
elementos que la del primer argumento m!s un elemento adicional en la cima de la pila. C!s
formalmente, podemos decir que el conjunto origen de la funci'n apila es el conjunto Pila#$% x
$, conocido como el producto cartesiano de Pila#$% y $8 ste es el conjunto de pares &p' () cuyo
primer elemento p est! en Pila#$% y cuyo segundo elemento ( est! en $.
De manera semejante,
La funci'n desapila tiene un argumento, una Pila de instancias de $, y produce como
resultado una nueva Pila de instancias de $ que tiene los mismos elementos que la del
primer argumento menos el elemento que estaba en la cima si es que $aba alguno.
La funci'n cima tiene un argumento, una Pila de instancias de $, y produce como resultado
una instancia de $ que es el elemento que est! en la cima de la pila, si lo $ay.
La funci'n vaca tiene un argumento, una Pila de instancias de $, y produce como resultado
una instancia del ;*D *++lean que indica si la pila del argumento est! o no vaca. ,e
supone que el ;*D *++lean se $a definido previamente por separado.
La funci'n crea no tiene argumentos y produce como resultado una Pila de instancias de $
que est! vaca.
"l p!rrafo FUNCIONES no define completamente estas funciones, sino que s'lo presenta sus
perfiles, es decir, la lista de tipos abstractos de datos de sus argumentos y el ;*D del resultado. "l
perfil de una funci'n tambin recibe el nombre de signatura de la funci'n.
"n la especificaci'n informal que dimos al principio de esta secci'n clasificamos las operaciones
del ;*D en 'rdenes, consultas y constructoras. Aon la especificaci'n formal algebraica de un ;*D
T, como en nuestro ejemplo Pila#$%, se puede definir la correspondiente clasificaci'n de las
funciones de forma m!s rigurosa. La clasificaci'n e/amina simplemente d'nde aparece T, con
respecto a la flec$a, en la signatura de cada funci'n, proporcionando tres categoras de funciones:
9na funci'n como crea para la cual T aparece s'lo a la derec$a de la flec$a es una funci'n
de construcci'n o funci'n constructora o abreviadamente una constructora. Codela una
operaci'n que produce instancias de T a partir de instancias de otros tipos abstractos de
datos o, como en el caso de una funci'n constructora constante como crea, sin partir de
argumento alguno.
9na funci'n como cima y vaca en las cuales T s'lo aparece a la iquierda de la flec$a es
una funci'n de consulta o abreviadamente una consulta. Codela una operaci'n que da
como resultado propiedades de las instancias de T, e/presadas en trminos de instancias de
otros tipos abstractos de datos 1*++lean y el par!metro genrico $ en los ejemplos1.
9na funci'n como apila y desapila en las que T aparece en ambos lados de la flec$a es una
funci'n de orden o abreviadamente una orden. Codela una operaci'n que produce nuevas
instancias de T a partir de instancias e/istentes de T y posiblemente tambin de instancias de
otros tipos abstractos de datos.
La parte de la especificaci'n algebraica del ;*D compuesta por las cl!usulas TIPO y FUNCIONES
recibe el nombre de signatura del ;*D. La signatura de un ;*D tambin recibe el nombre de
interfaz del ;*D. "n el ejemplo que nos ocupa, dado que Pila#$% es un ;*D genrico, y por tanto
un patr'n de tipos abstractos de datos, la parte de la especificaci'n algebraica del ;*D genrico
compuesta por las cl!usulas TIPO y FUNCIONES no es ya e/actamente una signatura de un ;*D
sino un patr'n de signaturas de tipos abstractos de datos.
3.3.- !e#ntica de la especificacin foral de un TAD
,upongamos que el ;*D Enter+, que modela los n#meros enteros y que $a sido definido
previamente por separado 1del mismo modo que suponemos que el ;*D *++lean $a sido tambin
definido previamente por separado1, se proporciona como par!metro genrico real correspondiente
al par!metro genrico formal $ en Pila#$%, obteniendo as como derivaci'n genrica el ;*D
Pila#Enter+% que contar!, por tanto, con su propia signatura, la cual est! definida implcitamente a
travs del mecanismo de genericidad.
De nuevo nos permitimos recordar que un ;*D es un tipo de datos, luego por consiguiente un ;*D
es un !lgebra. (or tanto, consta de un conjunto de valores, llamado dominio, un conjunto de
operaciones sobre dic$os valores y un conjunto de propiedades de esas operaciones.
Aomo estamos viendo, este !lgebra est! definida formalmente mediante una especificaci'n
algebraica. La cl!usula FUNCIONES modela el conjunto de operaciones del !lgebra mediante
funciones matem!ticas. "sta cl!usula describe las instancias del ;*D no por lo que son, sino por lo
que tienen que ofrecer, es decir, por el conjunto de operaciones aplicables sobre ellas. *
continuaci'n, vamos a construir los restantes elementos del !lgebra 1el dominio y el conjunto de
propiedades de las operaciones1 estudiando para ello cu!l es la sem!ntica de la tcnica de
especificaci'n algebraica, tarea para la cual usaremos como ejemplo el ;*D Pila#Enter+%.
Cediante la aplicaci'n sucesiva y correcta de las funciones de una signatura se pueden construir
trminos sobre ella. *s,
crea
o bien
apila(crea, cima(desapila(apila(apila(crea, -2), 3))))
o bien
desapila(apila(apila(apila(crea, 0), 4), -))
o bien
cima(desapila(apila(apila(crea, -2), 3)))
o bien
vaca(desapila(apila(crea, !)))
son cinco ejemplos de trminos sobre la signatura del ;*D Pila#Enter+%.
La sem!ntica de la tcnica formal de especificaci'n algebraica establece que cada trmino
sint!cticamente correcto construido sobre una signatura denota un valor del dominio del ;*D al que
pertenece el trmino construido. Aomo es l'gico, un trmino pertenece al ;*D resultado que figura
en el perfil de la funci'n m!s e/terna de dic$o trmino.
*s, los tres primeros trminos de ejemplo pertenecen al ;*D Pila#Enter+%, por lo que denotan un
valor del dominio del ;*D Pila#Enter+%8 sin embargo, el cuarto trmino de ejemplo, por pertenecer
al ;*D Enter+, denota un valor del dominio del ;*D Enter+, mientras el quinto trmino de
ejemplo, por pertenecer al ;*D *++lean, denota un valor del dominio del ;*D *++lean.
* su ve, esta sem!ntica afirma que s'lo pertenecen al dominio de un ;*D aquellos valores que
pueden ser generados mediante los trminos sint!cticamente correctos que pertenecen a dic$o ;*D,
independientemente de la signatura sobre la que $ayan sido construidos.
*s, al igual que el quinto trmino de ejemplo anterior pertenece al ;*D *++lean, tambin puede
$aber otros trminos que pertenecan al ;*D Doolean y que $ayan sido construidos sobre otra
signatura distinta a la del ;*D Pila#Enter+%. (ara empear, dado que suponemos que el ;*D
*++lean $a sido definido de manera correcta previamente por separado, es seguro y cierto que sobre
la signatura del propio ;*D *++lean se pueden construir trminos que pertenecen a este ;*D.
(or tanto, no necesitamos inventar una notaci'n especial para nombrar los valores del dominio de
un ;*D. "l %nombre& de una instancia de un ;*D es simplemente el trmino sint!cticamente
correcto que construye dic$o valor del dominio del ;*D mediante la aplicaci'n reiterada de
funciones de una signatura.
*s, por ejemplo, no es necesario inventar un nombre para el valor del dominio del ;*D Doolean
significado por el trmino
vaca(crea)
dado que el mismo trmino es el nombre de la instancia.
*$ora bien, f!cilmente nos encontramos con una nueva situaci'n que obliga a $acer ciertas
modificaciones a la sem!ntica vista $asta a$ora. (uede ocurrir que dos trminos sint!cticamente
distintos signifiquen el mismo valor seg#n la idea intuitiva que el desarrollador posee acerca del
;*D que est! construyendo.
:eamos varios ejemplos con el ;*D Pila#Enter+%. "n el primer ejemplo, el trmino
desapila(apila(apila(apila(crea, 0), 4), -))
y el trmino
apila(apila(crea, 0), 4)
denotan ambos una instancia del ;*D Pila#Enter+% que es una pila en la que est!n apilados los
n#meros enteros 4 y E, siendo el elemento de la cima el E y el siguiente y #ltimo elemento el 4.
"n el segundo ejemplo, el trmino
vaca(desapila(apila(crea, !)))
y el trmino
vaca(desapila(apila(desapila(apila(crea, 0)), 3)))
denotan ambos el valor ,erdader+ del dominio del ;*D *++lean, puesto que en ambos trminos la
funci'n vaca se est! aplicando sobre subtrminos sint!cticamente distintos entre s que pertenecen
al ;*D Pila#Enter+% y que denotan el mismo valor del dominio del ;*D Pila#Enter+% que es una
pila vaca, es decir, que carece de elementos.
"n el tercer ejemplo, el trmino
cima(desapila(apila(apila(crea, -2), 3)))
y el trmino
cima(apila(apila(crea, !), -2))
denotan ambos el valor 1B del dominio del ;*D Enter+, ya que en ambos trminos la funci'n cima
se est! aplicando sobre un subtrmino tal que el valor del dominio denotado por l es una pila tal
que tiene en la cima el n#mero entero 1B. "n este caso, los dos subtrminos, que pertenecen al ;*D
Pila#Enter+%, son distintos entre s y adem!s denotan valores distintos del dominio del ;*D
Pila#Enter+%. "l primer trmino denota la pila que tiene un #nico elemento, el 1B, que adem!s es el
elemento de la cima, mientras que el segundo subtrmino denota la pila que tiene dos elementos, los
n#meros enteros 6 y 1B, donde el elemento de la cima es el 1B y el siguiente y #ltimo elemento es el
6. No obstante, no tiene por qu ser as, ya que los dos subtrminos del ;*D Pila#Enter+% sobre los
que se aplica la funci'n cima podran denotar el mismo valor del dominio del ;*D Pila#Enter+%.
*s ocurre, por ejemplo, con el trmino
cima(desapila(apila(apila(crea, -2), 3)))
y el trmino
cima(apila(crea, -2))
"n todos los ejemplos anteriores, intuitivamente ambos trminos significan el mismo valor del
dominio. ,in embargo, la sem!ntica de la tcnica formal de especificaci'n algebraica considera, por
defecto, valores distintos a aqullos que se construyen mediante trminos sint!cticamente distintos.
(or tanto, necesitamos alg#n mecanismo para poder e/presar la igualdad de valores construidos de
modo distinto, es decir, necesitamos alg#n mecanismo para poder e/presar que dos trminos
sint!cticamente distintos son equivalentes. "ste mecanismo son los axiomas o ecuaciones que se
sit#an en la cl!usula AIO!AS que toda especificaci'n algebraica debe incluir.
,int!cticamente, una ecuaci'n o a/ioma de una especificaci'n algebraica tiene la forma
"
!
# "
2
siendo t
-
y t
.
dos trminos sint!cticamente correctos del mismo tipo de datos, o lo que es lo mismo,
del mismo ;*D o que pertenecen al mismo ;*D. ,em!nticamente, un a/ioma e/presa que el
trmino t
-
es equivalente al trmino t
.
o, lo que es igual, que el valor del dominio de dic$o ;*D
construido mediante el trmino t
-
es el mismo que el valor del dominio del mismo ;*D construido
mediante el trmino t
.
. (ara no tener que escribir infinitas ecuaciones, se admite que los trminos
que aparecen en una ecuaci'n tengan variables. Dic$as variables $an de ser de los tipos abstractos
de datos apropiados y se acostumbra a declararlas antes del conjunto de ecuaciones. La
interpretaci'n de las ecuaciones es, entonces, la de establecer la igualdad de los pares de valores que
se obtienen asignando a las variables todos los posibles valores del dominio de su ;*D. "s decir,
cada ecuaci'n es una f'rmula l'gica cuantificada universalmente por sus variables. N'tese,
finalmente, que las ecuaciones constituyen un conjunto y, por tanto, el orden en que se escriban es
irrelevante.
No obstante, la tarea de escribir los a/iomas de la especificaci'n algebraica de un ;*D dista muc$o
de ser sencilla. "s difcil estar seguros de si las ecuaciones escritas $asta el momento e/presan todas
las igualdades que deseamos. -No podra ocurrir que, pese a las ecuaciones, tengamos todava m!s
valores en el dominio del ;*D de los debidos0 -A'mo podemos estar seguros de que no $acen falta
m!s ecuaciones0 F, igualmente, -c'mo podemos estar seguros de que no sobran ecuaciones0 La
realidad es que no e/iste un mtodo e/acto para escribir de manera correcta una especificaci'n
algebraica. *$ora bien, partiendo de la idea intuitiva e informal que el desarrollador tiene en su
cabea del ;*D que quiere especificar, s vamos a estudiar un mtodo sistem!tico para construir
especificaciones algebraicas basado en un conjunto de $eursticas que, en la mayora de los casos,
se $an revelado #tiles y que conduce, con gran probabilidad, a que el desarrollador especifique lo
que realmente desea y no un ;*D distinto.
* la ve que estudiamos este mtodo sistem!tico para desarrollar especificaciones algebraicas
vamos a ir profundiando m!s en la sem!ntica de la tcnica formal de este tipo de especificaciones.
La sem!ntica de la especificaci'n algebraica de un ;*D establece que e/iste al menos un
subconjunto del conjunto formado por las funciones constructoras y de orden de la signatura de
dic$o ;*D, cuyos elementos reciben el nombre de funciones generadoras o simplemente
generadoras, tal que tiene la propiedad de que s'lo con ellas es posible generar cualquier valor del
dominio del ;*D, y e/cluyendo cualquiera de ellas $ay valores del dominio que no pueden ser
generados8 es decir, s'lo pertenecen al dominio del ;*D aquellos valores que pueden ser generados
mediante trminos sint!cticamente correctos construidos sobre la signatura de dic$o ;*D y
formados #nicamente por generadoras.
9n conjunto de generadoras de un ;*D puede ser a su ve libre o no libre. 9n conjunto de
generadoras es libre cuando todo trmino sint!cticamente correcto formado #nicamente por ellas
denota un valor diferente del dominio del ;*D. 9n conjunto de generadoras es no libre cuando dos
o m!s trminos sint!cticamente correctos y distintos formados #nicamente por ellas denotan un
mismo valor del dominio del ;*D.
"l mtodo sistem!tico para desarrollar especificaciones algebraicas indica que para escribir los
a/iomas es necesario escoger un conjunto de generadoras para un ;*D. Dado que puede $aber
varios conjuntos posibles de generadoras para un determinado ;*D, siempre es mejor escoger, de
e/istir, uno que sea libre, ya que, si el conjunto de generadoras escogido para escribir las ecuaciones
de la especificaci'n algebraica del ;*D no es libre, en la cl!usula AIO!AS ser! necesario escribir
las correspondientes ecuaciones entre generadoras, que e/presan la equivalencia entre trminos
formados e/clusivamente por funciones generadoras.

*dem!s de escribir las ecuaciones entre generadoras, si son necesarias, $ay que escribir, para cada
funci'n constructora o de orden que no est en el conjunto de generadoras, tantas ecuaciones como
sean necesarias para que quede completamente especificado lo que la funci'n devuelve cuando es
aplicada a una instancia arbitraria creada por las generadoras, garantiando que todo trmino que
tiene a esta funci'n como la m!s e/terna es equivalente a alg#n trmino formado #nicamente por
generadoras.
;ambin es necesario escribir, para cada funci'n de consulta, tantas ecuaciones como sean
necesarias para que quede completamente especificado lo que la funci'n devuelve cuando es
aplicada a una instancia arbitraria creada por las generadoras, garantiando en este caso que todo
trmino que tiene a esta funci'n como la m!s e/terna es equivalente a alg#n trmino cuya funci'n
m!s e/terna es una constructora o una orden del ;*D resultado de la consulta. "sta garanta tiene
un doble objetivo: por un lado no introducir nuevos valores en el dominio del ;*D resultado de la
consulta y, por otro lado, no $acer iguales valores del dominio del ;*D resultado de la consulta que
antes no lo eran.
(ara cada funci'n para la que $ay que escribir ecuaciones, a veces una ecuaci'n bastar! y otras
ser!n necesarias varias. 9na estrategia que suele funcionar es poner la funci'n como la m!s e/terna
de un trmino, y descomponer cada argumento del ;*D que se define en la especificaci'n en todos
sus posibles patrones formados con las generadoras. Los trminos as construidos se igualan a
trminos derec$os en los que la funci'n ya no es la m!s e/terna. "ste tipo de ecuaciones pueden
considerarse, ledas de iquierda a derec$a, como reglas de reescritura que permiten reducir, en un
n#mero finito de pasos, un trmino que contiene una funci'n a otro en el que sta no figura.
"n ocasiones, una funci'n puede especificarse e/clusivamente en trminos de otra u otras funciones
de su misma categora, sin que aparecan en las ecuaciones las generadoras del ;*D que se define
en la especificaci'n. ,e dice entonces que se trata de una funcin derivada.
(or tanto, podemos concluir de nuestro estudio de la sem!ntica de la tcnica formal de
especificaci'n algebraica que todos los valores del dominio del ;*D son alcanables a partir de sus
funciones generadoras, y que dos trminos construidos sobre la signatura de dic$o ;*D son
equivalentes si y s'lo si su equivalencia puede deducirse de las ecuaciones.
*unque $emos utiliado como ejemplo en esta e/posici'n el ;*D Pila#Enter+%, que es un ;*D
derivado genricamente de Pila#$%, las conclusiones e/tradas son independientes de $, y de
$ec$o, la naturalea del ;*D Enter+ no $a influido en la argumentaci'n. (or ello, las conclusiones
son aplicables al ;*D genrico y no s'lo a una de sus derivaciones genricas.
3.$.- Construccin de la especificacin foral de un TAD
"l conjunto de generadoras obvio para el ;*D Pila#$% es el formado por crea y apila, ya que con
estas dos funciones es posible generar cualquier pila imaginable. *dem!s, estas dos funciones
forman un conjunto libre de generadoras, puesto que, en efecto, toda aplicaci'n de apila produce
una pila distinta a la que ya e/ista y todas ellas son distintas de la pila vaca producida por crea. No
$acen falta, por tanto, ecuaciones entre generadoras.
(ara escribir las ecuaciones asociadas al resto de las funciones, se realia un an!lisis por casos sobre
los patrones posibles del argumento de tipo Pila#$%. "ste argumento, que representa cualquier pila
posible, o bien es una pila vaca y entonces tendr! la forma crea, o bien es una pila no vaca y
entonces tendr! la forma apila&p' () para alguna pila ya e/istente p y alg#n elemento ( que se desee
apilar. *s, por tanto, las ecuaciones para vaca son:
Para c$al%$ier &:G, p:Pila[G],
vaca(crea) # 'erdadero
vaca(apila(p, &)) # (also
"stas ecuaciones son l'gicas y nos dicen cu!ndo est! o no vaca una pila: una pila resultante de la
constructora1generadora crea est! vaca8 toda pila resultado de la orden1generadora apila que
inserta un elemento en alguna pila e/istente <vaca o no= no est! vaca.
La especificaci'n de cualquier ejemplo realista, incluso tan b!sico como las pilas, debe encontrarse
con el problema de las operaciones indefinidas: algunas operaciones no son aplicables a todos los
elementos de sus conjuntos origen. Gste es el caso de desapila y de cima: no se puede quitar un
elemento de una pila vaca8 y una pila vaca no tiene cima.
La soluci'n utiliada en las especificaciones algebraicas consiste en modelar estas operaciones
como funciones parciales. 9na funcin matemtica de un conjunto origen a un conjunto destino
/ es parcial si no est! definida para todos los miembros de . 9na funci'n que no es parcial se
denomina total. "l dominio de una funci'n parcial es el subconjunto de que contiene aquellos
elementos para los cuales la funci'n proporciona un valor.
La especificaci'n del ;*D Pila#$% aplica estas ideas a las pilas declarando desapila y cima como
funciones parciales en el p!rrafo FUNCIONES, tal y como se indica mediante la flec$a discontinua
que aparece en sus respectivos perfiles, mientras que la flec$a continua se reserva para las funciones
totales. "sto plantea un nuevo problema: c'mo especificar el dominio de estas funciones parciales.
Las funciones parciales son un $ec$o del que uno no puede evadirse en la vida del desarrollo del
soft)are, ya que reflejan simplemente la observaci'n de que no toda operaci'n es aplicable a
cualquier valor. (ero son tambin una fuente potencial de errores: si 0 es una funci'n parcial de en
/, no se puede estar seguro de si la e/presi'n 0&() tiene o no sentido aunque el valor de ( est en :
tambin tenemos que ser capaces de garantiar que el valor de ( pertenece al dominio de 0.
(ara que esto sea posible, cualquier especificaci'n de un ;*D que incluya funciones parciales debe
especificar el dominio de cada una de ellas. Gste es el papel del p!rrafo P"ECONDICIONES. (ara
el caso de Pila#$% el p!rrafo sera:
PRECONDICIONES
desapila(p:Pila[G]) require vaca(p) ) (also
cima(p:Pila[G]) require vaca(p) ) (also
en donde, para cada funci'n, la palabra reservada re1uire indica qu condiciones tienen que
satisfacer los argumentos de las funciones para pertenecer al dominio de las funciones.
La e/presi'n booleana que define el dominio se llama precondici'n de la funci'n parcial
correspondiente. *qu la precondici'n tanto de desapila como de cima e/presa que la pila que se d
como argumento no debe estar vaca. *ntes de la palabra reservada re1uire viene el nombre de la
funci'n con nombres para los argumentos <p para el argumento Pila#$% en el ejemplo=, de modo
que la precondici'n se pueda referir a stos.
N'tese la diferencia entre la operaci'n de igualdad ) y la equivalencia algebraica entre trminos #
ya que las ecuaciones de la especificaci'n indican equivalencias entre trminos mientras que la
operaci'n de igualdad es una operaci'n m!s 1en este caso infija a diferencia de las dem!s descritas
que son prefijas1 que devuelve una instancia del ;*D *++lean, de modo que los trminos
construidos por ella ser!n equivalentes algebraicamente a 'erdadero o (also. *s, en cada una
de las precondiciones anteriores, la cl!usula re1uire indica, como es l'gico, que el trmino que
aparece a continuaci'n $a de ser equivalente algebraicamente a 'erdadero.
Catem!ticamente, la precondicin de una funci'n 0 es la funcin caracterstica del dominio de 0.
La funci'n caracterstica de un subconjunto A de un conjunto es la funci'n total
c: * +'erdadero, (also,
tal que c&() es ,erdader+ si ( pertenece a A, y Fals+ en caso contrario.
*$ora que ya $emos establecido la precondici'n de las funciones parciales, podemos escribir el
resto de los a/iomas de la especificaci'n, que son los que corresponden a desapila y cima. Dado
que los a/iomas solamente $acen equivalentes trminos definidos, al $acer el an!lisis por casos
sobre los patrones posibles del argumento de tipo Pila#$% s'lo se considerar!n, en el caso de las
ecuaciones que involucran funciones parciales, aquellos patrones que den lugar a trminos
definidos, donde la condici'n para que el trmino est definido es precisamente la e/presada en la
precondici'n. (or tanto, las ecuaciones que corresponden a desapila y cima son #nicamente las que
se aplican sobre el argumento que es una pila no vaca y que entonces tiene la forma apila&p' () para
alguna pila ya e/istente p y alg#n elemento ( que se desee apilar. *s, por tanto, las ecuaciones para
desapila y cima son:
Para c$al%$ier &:G, p:Pila[G],
desapila(apila(p, &)) # p
cima(apila(p, &)) # &
,e puede observar que el comportamiento intuitivo de las pilas est! reflejado en estas dos #ltimas
ecuaciones: la cima de una pila no vaca es el #ltimo elemento apilado, y al despilar una pila no
vaca desaparece el #ltimo elemento apilado.
La especificaci'n completa es:
TIPO
Pila[G]
FUNCIONES
apila: Pila[G] x G Pila[G]
desapila: Pila[G] Pila[G]
cima: Pila[G] G
vaca: Pila[G] Boolean
crea: Pila[G]
AXIOMAS
Para c$al%$ier &:G, p:Pila[G],
desapila(apila(p, &)) # p
cima(apila(p, &)) # &
vaca(crea) # 'erdadero
vaca(apila(p, &)) # (also
PRECONDICIONES
desapila(p:Pila[G]) require vaca(p) ) (also
cima(p:Pila[G]) require vaca(p) ) (also
3.%.- Conclusiones
7aciendo una recapitulaci'n del trayecto recorrido, $emos visto c'mo un ;*D es un tipo de datos,
y por tanto un !lgebra. 7emos establecido que este !lgebra est! definida formalmente mediante una
especificaci'n algebraica. "sta definici'n del ;*D es implcita en dos sentidos:
7emos definido las operaciones del !lgebra mediante la cl!usula FUNCIONES de la
especificaci'n algebraica, que modela el conjunto de operaciones del !lgebra mediante
funciones matem!ticas. "sta cl!usula describe las instancias del ;*D no por lo que son, sino
por lo que tienen que ofrecer, es decir, por el conjunto de operaciones aplicables sobre ellas,
de modo que podemos afirmar que la definici'n de las instancias del ;*D tiene la cualidad
de ser implcita. "sta cualidad de la definici'n de las instancias de un ;*D a travs de su
especificaci'n algebraica se confirma de nuevo cuando despus $emos definido el dominio
del !lgebra precisamente en trminos de estas operaciones.
(osteriormente para esta tarea de definir el dominio del ;*D $emos necesitado definir el
conjunto de propiedades que verifican las operaciones del !lgebra mediante la cl!usula
AIO!AS de la especificaci'n algebraica. Lo que realmente est! $aciendo esta cl!usula es
definir las funciones tambin de manera implcita: en lugar de definiciones e/plcitas se
utilian a/iomas que describen las propiedades de las funciones.
La potencia de las especificaciones de los tipos abstractos de datos proviene de su capacidad para
captar las propiedades esenciales de los tipos de datos sin incurrir en una especificaci'n e/cesiva.
La especificaci'n anterior de una pila cualquiera e/presa todo lo que $ay que saber acerca de la
noci'n de pila en general, e/cluyendo todo lo que pueda ser aplicable a alguna representaci'n
concreta de las pilas. ;oda la verdad respecto a las pilas, pero nada m!s que la verdad.
"sto proporciona un modelo general de computaci'n con tipos de datos denominado c!lculo
ecuacional. ,e pueden describir secuencias complejas de operaciones mediante e/presiones
matem!ticas que goan de las propiedades $abituales del !lgebra: y se puede ver el proceso de
llevar a cabo el c'mputo como un proceso de simplificaci'n algebraica. "sto es debido a que las
funciones definidas en la especificaci'n de un ;*D permiten construir trminos posiblemente
complejos que pueden verse como e/presiones matem!ticas, y los a/iomas del ;*D permiten
simplificar tales e/presiones para generar un resultado m!s sencillo. 9na e/presi'n, sea compleja o
no, de una pila cualquiera es el equivalente matem!tico de un programa8 el proceso de
simplificaci'n es el equivalente matem!tico de un c'mputo, es decir, de la ejecuci'n de dic$o
programa.
:eamos un ejemplo, utiliando de nuevo Pila#Enter+% como derivaci'n genrica de Pila#$%. "s
posible, a partir de la especificaci'n vista antes, escribir el siguiente trmino complejo:
cima( desapila( apila( desapila( apila( apila( desapila( apila( ap
ila( apila( crea, !), 2), 3)), cima( desapila( apila( apila( crea,
4), )))), -)), .)))
,e puede ver este trmino como una e/presi'n matem!tica que vamos a simplificar utiliando los
a/iomas del ;*D.
*plicando el primer a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
cima( desapila( apila( desapila( apila( apila( desapila( apila( ap
ila( apila( crea, !), 2), 3)), cima( apila( crea, 4))), -)), .)))
*plicando el segundo a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
cima( desapila( apila( desapila( apila( apila( desapila( apila( ap
ila( apila( crea, !), 2), 3)), 4), -)), .)))
*plicando el primer a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
cima( desapila( apila( desapila( apila( apila( apila( apila( crea,
!), 2), 4), -)), .)))
*plicando el primer a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
cima( desapila( apila( apila( apila( apila( crea, !), 2), 4), .)))
*plicando el primer a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
cima( apila( apila( apila(crea, !), 2), 4))
*plicando el segundo a/ioma sobre la e/presi'n anterior, se simplifica a la siguiente e/presi'n:
4
*plicando una secuencia de simplificaciones, llevadas a cabo tan simple y mec!nicamente como las
simplificaciones de la aritmtica elemental gracias a las reglas de reescritura que proporciona la
especificaci'n mediante los a/iomas, obtenemos el valor de la e/presi'n, que es precisamente el
n#mero entero E.
"ste ejemplo da una visi'n de uno de los principales papeles te'ricos de los tipos abstractos de
datos: brindar un model formal del concepto de programa y de la ejecuci'n de programas. "ste
modelo es puramente matem!tico: no tiene ninguno de los conceptos imperativos de estado de
programa, variables cuyos valores puedan cambiar con el tiempo, o del orden en que se efect#a la
ejecuci'n. ,e basa en las tcnicas est!ndar de evaluaci'n de e/presiones de la matem!tica ordinaria.
$.- &undaentos de la ipleentacin de un tipo abstracto de
datos
$.1.- Conceptos "enerales b#sicos de la ipleentacin de un TAD
;enemos como punto de partida una elegante teora matem!tica para el modelado de tipos de datos
y, de $ec$o, como se $a visto al final del apartado anterior, del concepto de programa en general y
tambin del concepto de la ejecuci'n de un programa. (ero el tema de trabajo aqu es la arquitectura
del soft)are, no la matem!tica, ni siquiera la ciencia de la computaci'n o inform!tica te'rica, as
que podemos preguntarnos si nos $emos desviado de nuestro camino. La respuesta a esa pregunta
es que no muc$o. "n la b#squeda de una buena forma de describir los objetos, los tipos abstractos
de datos proporcionan un mecanismo de descripci'n de alto nivel, por tanto libre de cuestiones de
implementaci'n. *$ora es el momento de estudiar la implementaci'n de un tipo abstracto de datos,
lo que a su ve nos va a llevar a las estructuras fundamentales del mtodo orientado a objetos.
Auando se $abla de especificaci'n de un ;*D y de implementaci'n de un ;*D parece que el propio
;*D se divide en dos partes diferenciadas: por un lado su especificaci'n y por otro lado su
implementaci'n. "sto no es as realmente. , es cierto que en el desarrollo de un sistema soft)are
real es necesario tanto desarrollar la especificaci'n de un ;*D como al menos una implementaci'n
suya, pero en realidad esto lo que significa es que no estamos ante un #nico tipo de datos sino ante
dos tipos de datos distintos pero relacionados entre s. "l TAD viene definido por su especificaci'n
algebraica y se llama tipo implementado, mientras que una implementaci'n de ese ;*D es un tipo
de datos distinto al ;*D y se llama tipo implementador.
Aomo es l'gico, es necesario garantiar que una implementaci'n de un ;*D es correcta8 es decir, es
necesario garantiar que el tipo implementador implementa correctamente el tipo implementado.
*$ora bien, lo que ocurre en el desarrollo soft)are real es que el tipo implementado, el ;*D, se da
o se define mediante una especificaci'n algebraica, mientras que el tipo implementador se da o se
define mediante un m'dulo soft)are. "so complica la comparaci'n entre ambos porque se trata de
diferentes lenguajes matem!ticos.
No obstante, el objetivo sigue siendo claro: garantiar que el tipo implementador implementa
correctamente el tipo implementado. (ara que la implementaci'n sea correcta, se requieren ciertas
condiciones matem!ticas que en esencia dicen que el tipo implementador guarda una relaci'n
$omom'rfica con el tipo implementado8 es decir, que el tipo implementador simula adecuadamente
el tipo implementado, o lo que es lo mismo, que el m'dulo soft)are implementador define un
!lgebra que simula adecuadamente el !lgebra definida por la especificaci'n algebraica. "n
definitiva, para que una implementaci'n sea correcta debe conservar las propiedades de la
especificaci'n que dice implementar.
Hntuitivamente, implementar un ;*D consiste en:
,imular o representar los valores del tipo a implementar, el ;*D, por medio de valores del
tipo implementador.
,imular las operaciones del tipo a implementar mediante operaciones del tipo
implementador.
Hnformalmente, una implementaci'n es correcta cuando el usuario del tipo implementador no es
capa de notar la diferencia entre el tipo de datos realmente especificado, el ;*D, y el tipo de datos
implementador que lo simula.
(ara garantiar que una implementaci'n de un ;*D es correcta, $ay que establecer una
correspondencia entre los valores del tipo de datos implementado, el ;*D, y los del tipo de datos
implementador utiliado para simular aqul. "sta correspondencia se llama funci'n de abstracci'n.
La funcin de abstraccin es una aplicaci'n que establece una correspondencia entre el tipo
implementador y el tipo implementado 1es decir, establece una correspondencia entre el !lgebra de
la implementaci'n y el !lgebra de la especificaci'n1 de tal modo que a cada valor del dominio del
tipo implementador le $ace corresponder a lo sumo un valor del dominio del tipo implementado.
La inversa de la funci'n de abstracci'n, que se llama relacin de representacin, no es una
funci'n dado que en general a un valor del dominio del tipo implementado le pueden corresponder
varios valores del dominio del tipo implementador.
"n general, las caractersticas de la funci'n de abstracci'n son las siguientes:
"s parcial, ya que no todo valor del dominio del tipo implementador representa un valor del
dominio del tipo implementado. (or tanto, se puede decir que el tipo implementador tiene
valores basura en su dominio desde el punto de vista del tipo implementado. ,e llama
invariante de la representacin o invariante de la implementacin a la aserci'n que
define las condiciones l'gicas que debe cumplir un valor del dominio del tipo
implementador para representar un valor del dominio del tipo implementado. "n trminos
matem!ticos, el invariante de la representaci'n es la funci'n caracterstica del dominio de la
funci'n de abstracci'n, es decir, la propiedad que define cu!ndo dic$a funci'n es aplicable.
,e define entonces el conjunto de representantes vlidos -o conjunto de valores vlidos-
del tipo implementador como el conjunto formado por aquellos valores del dominio del
tipo implementador que satisfacen el invariante de la representaci'n. "l invariante de la
representaci'n $a de ser respetado por todas las operaciones del tipo implementador en dos
sentidos: en primer lugar, las operaciones del tipo implementador s'lo est!n obligadas a
funcionar correctamente sobre representantes v!lidos de dic$o tipo y, en segundo lugar, las
operaciones del tipo implementador que generen valores del dominio de dic$o tipo deben
comprometerse a que stos sean siempre representantes v!lidos. Aada valor v!lido del tipo
implementador es un ejemplar o instancia del mismo. 9n valor v!lido del tipo
implementador es una estructura de datos, es decir, una representaci'n fsica en la
memoria del computador, y que por tanto puede ser creada y manipulada por un sistema
soft)are durante su ejecuci'n, de un valor del dominio del tipo implementado, es decir, del
;*D que implementa el tipo implementador.
"s sobreyectiva, ya que a todo valor del dominio del tipo implementado le corresponde al
menos un valor del dominio del tipo implementador8 es decir, todos los valores del tipo
implementado, del ;*D, se pueden representar con la implementaci'n escogida.
No es necesariamente inyectiva, ya que varios valores del dominio del tipo implementador
pueden representar el mismo valor del dominio del tipo implementado. Aonsecuentemente,
la funci'n de abstracci'n induce una relaci'n de equivalencia que se llama equivalencia de
representacin y que agrupa en cada clase los valores del dominio del tipo implementador
que se corresponden con el mismo valor del dominio del tipo implementado.
$.2.- 'elacin entre la ipleentacin de un TAD y el (todo orientado
a ob)etos
La teora formal de los tipos abstractos de datos es la base te'rica del mtodo orientado a objetos.
De $ec$o, los tipos abstractos de datos sirven como base directa de los m'dulos que se necesitan en
el mtodo orientado a objetos. C!s precisamente, un sistema softare orientado a objetos se
construir! 1en el nivel de an!lisis, dise+o e implementaci'n1 como una colecci'n de tipos abstractos
de datos parcial o totalmente implementados que interact#an entre s.
*$ora bien, el concepto b!sico en el mtodo orientado a objetos es el de clase. :amos a ver
entonces c'mo se relaciona el concepto de tipo abstracto de datos con el de clase.
9na clase es un m'dulo soft)are que define, qui! de forma parcial, un tipo implementador8 o, lo
que es lo mismo, una clase es un m'dulo soft)are que define una implementaci'n, que puede ser
parcial, de un tipo abstracto de datos. Aomo ya vimos, puede $aber varias implementaciones
distintas de un ;*D, por lo que puede $aber entonces varias clases distintas que implementen el
mismo ;*D.
De modo que para obtener una clase se debe proporcionar un ;*D y $ay que decidir una
implementaci'n para el mismo. ,in embargo, la definici'n establece que la implementaci'n puede
ser parcial. La terminologa siguiente separa este caso de las clases que est!n completamente
implementadas:
9na clase que est! completamente implementada define una implementaci'n completa de un tipo
abstracto de datos y se denomina efectiva. 9na clase que est! implementada s'lo parcialmente
define una implementaci'n parcial de un tipo abstracto de datos y se denomina abstracta o
diferida. 9na clase puede ser o bien efectiva o bien diferida.
(ara obtener una clase efectiva, se deben dar todos los detalles de la implementaci'n. (ara una clase
diferida, se puede escoger un cierto estilo de implementaci'n pero dejar abiertos algunos aspectos
de la misma. "n el caso m!s e/tremo de implementaci'n parcial puede uno abstenerse de tomar
ninguna decisi'n de implementaci'n, por lo que la clase resultante ser! completamente diferida.
,eg#n lo visto, podemos definir la construccin de softare orientado a objetos como el mtodo
de desarrollo de soft)are que basa la arquitectura de cualquier sistema soft)are en una colecci'n
estructurada de implementaciones, que pueden ser parciales, de tipos abstractos de datos. La
colecci'n de implementaciones que conforman un sistema soft)are orientado a objetos es
estructurada gracias a dos relaciones entre clases: cliente y $erencia.
"n el mtodo orientado a objetos se produce la fusi'n de dos conceptos, el de m'dulo soft)are y el
de tipo de datos, dando lugar al concepto de clase que engloba a ambos. :amos a ver c'mo.
;oda clase es un m'dulo, como se $a visto, luego una clase puede ser vista como un m'dulo de tal
modo que el nombre del m'dulo es el de la clase. La clase, como m'dulo, es la unidad b!sica de
descomposici'n de un sistema soft)are orientado a objetos y proporciona a otros m'dulos distintos
a ella 1es decir, otras clases1 una serie de facilidades relacionadas. * la ve, como toda clase define
un tipo de datos implementador 1de forma semejante a como una especificaci'n algebraica define
un ;*D o tipo de datos implementado1, podemos decir que toda clase es un tipo de datos, de modo
que una clase puede ser vista como un tipo de datos de tal modo que el nombre del tipo de datos es
el de la clase.
(or tanto, una clase puede verse desde dos perspectivas diferentes pero complementarias: como
m'dulo soft)are y como tipo de datos, de modo que la fusi'n m'dulo1tipo se produce debido a que
las facilidades relacionadas que proporciona la clase, vista como m'dulo, constituyen a su ve la
definici'n de la clase, vista como tipo de datos. "s decir, la clase, vista como m'dulo, es quien se
define a s misma vista como tipo de datos8 o, de forma a#n m!s simple, el m'dulo define el tipo de
datos..
Aomo $emos visto, una clase es un tipo de datos y, adem!s, es un tipo implementador, por lo que
podemos aplicar al mtodo orientado a objetos los conceptos b!sicos generales vistos en el apartado
anterior sobre implementaci'n de tipos abstractos de datos.
(ara garantiar que una clase es una implementaci'n correcta de un ;*D, en primer lugar $ay que
establecer una correspondencia entre los valores del tipo implementado, el ;*D, y los de la clase
utiliada para simular aqul. "sta correspondencia se llama funci'n de abstracci'n.
L a funcin de abstraccin es una aplicaci'n que establece una correspondencia entre la clase
1como tipo implementador1 y el ;*D 1como tipo implementado1, de tal modo que a cada valor del
dominio de la clase le $ace corresponder a lo sumo un valor del dominio del ;*D.
La inversa de la funci'n de abstracci'n, que se llama relacin de representacin, no es una
funci'n dado que en general a un valor del dominio del ;*D le pueden corresponder varios valores
del dominio de la clase.
"n general, las caractersticas de la funci'n de abstracci'n son las siguientes:
"s parcial, ya que no todo valor del dominio de la clase representa un valor del dominio del
;*D. (or tanto, se puede decir que la clase tiene valores basura en su dominio desde el
punto de vista del ;*D. ,e llama invariante de la representacin o invariante de la
implementacin a la aserci'n que define las condiciones l'gicas que debe cumplir un valor
del dominio de la clase para representar un valor del dominio del ;*D. "n trminos
matem!ticos, el invariante de la representaci'n es la funci'n caracterstica del dominio de la
funci'n de abstracci'n, es decir, la propiedad que define cu!ndo dic$a funci'n es aplicable.
,e define entonces el conjunto de representantes vlidos -o conjunto de valores vlidos-
de la clase como el conjunto formado por aquellos valores del dominio de la clase que
satisfacen el invariante de la representaci'n. "l invariante de la representaci'n $a de ser
respetado por todas las rutinas de la clase en dos sentidos: en primer lugar, las rutinas de la
clase s'lo est!n obligadas a funcionar correctamente sobre representantes v!lidos de dic$a
clase y, en segundo lugar, las rutinas de la clase que generen valores del dominio de la clase
deben comprometerse a que stos sean siempre representantes v!lidos. Aada valor v!lido de
la clase es un ejemplar o instancia de la misma, y recibe el nombre de objeto. (or tanto, un
objeto es un ejemplar o instancia de una clase, es decir, una estructura de datos o
representaci'n fsica en la memoria del computador, y que por tanto puede ser creada y
manipulada por un sistema soft)are durante su ejecuci'n, de un valor del dominio del ;*D
que implementa la clase de ese objeto.
"s sobreyectiva, ya que a todo valor del dominio del ;*D le corresponde al menos un valor
del dominio de la clase8 es decir, todos los valores del ;*D se pueden representar con la
implementaci'n escogida.
No es necesariamente inyectiva, ya que varios valores del dominio de la clase pueden
representar el mismo valor del dominio del ;*D. Aonsecuentemente, la funci'n de
abstracci'n induce una relaci'n de equivalencia que se llama equivalencia de
representacin y que agrupa en cada clase de equivalencia los valores del dominio de la
clase que se corresponden con el mismo valor del dominio del ;*D.
Aomo es l'gico, que la funci'n de abstracci'n sea funci'n es un requisito universal: si el mismo
objeto pudiera interpretarse como que representa a m!s de un valor del dominio del ;*D, entonces
la representaci'n escogida sera ambigua y por consiguiente inadecuada.
La definici'n de clase genera como subproducto, por tanto, la definici'n de objeto. (odemos
concluir tambin que los te/tos de soft)are que sirven para producir los sistemas soft)are son las
clases. Los objetos son s'lo un concepto relativo al tiempo de ejecuci'n ya que son creados y
manipulados por el sistema soft)are durante su ejecuci'n.
(or tanto, al igual que un ;*D, una clase es un tipo de datos. Aomo ya estudiamos, los tipos
abstractos de datos, como las clases, tienen instancias: la diferencia es que una instancia de un ;*D
es un elemento puramente matem!tico 1ya que es un miembro de alg#n conjunto matem!tico1,
mientras que una instancia de una clase es una estructura de datos que puede ser creada y
manipulada por un sistema soft)are.
*$ora es necesario estudiar c'mo implementar de forma correcta un tipo abstracto de datos
mediante el mtodo orientado a objetos. (ara ello, usaremos el lenguaje de programaci'n orientado
a objetos Iava. *unque es verdad que no e/iste un mtodo e/acto para escribir, a partir de una
especificaci'n algebraica de un ;*D, una clase que implemente este ;*D correctamente, s que
e/iste un mtodo sistem!tico basado en un conjunto de $eursticas para construir implementaciones
correctas de un ;*D a partir de su especificaci'n. "ste mtodo sistem!tico se fundamenta en el
Dise!o por "ontrato, abreviado Dp" 1en ingls el acr'nimo es DbC, de Desi2n by C+ntract1, que
fue definido por Dertrand Ceyer, creador del lenguaje "iffel.
%.- &undaentos tericos del Diseo por Contrato
%.1.- *ntroduccin
Aomo ya $emos comentado, nuestro tema de trabajo es la arquitectura del soft)are en general y
escribir sistemas soft)are correctos y robustos en particular. "l estudio de los tipos abstractos de
datos no nos $a alejado demasiado de nuestro objetivo y s que nos $a proporcionado una serie de
pistas sobre c'mo mejorar notablemente la correcci'n y robuste de las aplicaciones que
desarrollamos.
"s frecuente comprobar que no se presta debida atenci'n a la sem!ntica de las clases de un sistema
soft)are. La necesidad de poner m!s atenci'n a las propiedades sem!nticas de las clases quedar!
particularmente clara si se recuerda c'mo se definen las clases: como implementaciones de tipos
abstractos de datos. Lo $abitual es que las clases consten simplemente de atributos y mtodos, que
de $ec$o representan a las funciones de la especificaci'n de un ;*D. (ero un ;*D es algo m!s que
una lista de operaciones disponibles: recurdese el papel que desempe+aban las propiedades
sem!nticas, que se e/presan como a/iomas y precondiciones. Gstas son esenciales para captar la
verdadera naturalea de las instancias de un ;*D. "sas clases que s'lo contienen atributos y
mtodos pierden el aspecto sem!ntico del concepto de ;*D y es necesario introducirlo en el mtodo
orientado a objetos para tener soft)are que no solamente sea fle/ible y reutiliable, sino tambin
correcto y robusto.
Lo primero que $abra que preguntarse es qu significa que un elemento soft)are sea correcto. (ara
considerar significativa la pregunta se necesita tener no s'lo el elemento soft)are sino tambin una
descripci'n precisa de lo que se supone que ste debe $acer, es decir, una especificaci'n. "s decir,
un elemento soft)are no puede decirse que sea correcto o incorrecto por s mismo, sino que es
correcto o incorrecto con respecto a cierta especificaci'n. "strictamente $ablando, no se debera
discutir sobre si un elemento soft)are es o no correcto, sino sobre si es consistente con su
especificaci'n. No obstante, se seguir! utiliando el trmino bien aceptado de %correcci'n& pero
siempre se debe recordar que la pregunta de si es correcto no se aplica a elementos soft)are: se
aplica a pares formados por un elemento soft)are y una especificaci'n. (or tanto, la correcci'n es
un concepto relativo.
:amos a aprender la forma de e/presar la especificaci'n de un elemento soft)are para ayudar a
establecer la correcci'n del mismo. (ara e/presar dic$a especificaci'n usaremos aserciones.
Aomprobaremos adem!s que el simple $ec$o de escribir la especificaci'n es un primer paso
precioso $acia asegurar que el soft)are va a satisfacer realmente esa especificaci'n. (or tanto, se
obtendr!n tremendos beneficios si se escriben las aserciones al mismo tiempo que se escribe el
soft)are 1o incluso antes de escribir el soft)are. "ntre las consecuencias se pueden citar las
siguientes:
(roducir soft)are que es correcto desde el principio debido a que est! dise+ado para ser
correcto. "l ttulo de un artculo escrito por 7arlan D. Cills <uno de los creadores de la
%(rogramaci'n "structurada&= en los setenta proporciona la idea correcta: 3C4m+ escribir
pr+2ramas c+rrect+s y saberl+5 (or %saberlo& se entiende equipar al soft)are, a la ve que
se escribe ste, con los argumentos que pueden demostrar que es correcto.
Ffrecer una comprensi'n muc$o mejor del problema y de sus soluciones finales.
Jacilitar la tarea de la documentaci'n del soft)are.
,entar las bases para una demostraci'n y depuraci'n sistem!ticas.
%.2.- Co e+presar una especificacin
Las observaciones informales anteriores se pueden convertir en una notaci'n matem!tica simple,
tomada de la teora de la verificaci'n formal de programas, y muy valiosa para raonar sobre la
correcci'n de los elementos soft)are.
,ea A un cierto elemento soft)are de un sistema soft)are, como por ejemplo un mtodo o inclusive
una #nica instrucci'n. 9na frmula de correccin, tambin denominada Tripleta de #oare, es una
e/presi'n de la forma:
$%& A $'&
que denota la propiedad siguiente, que puede ser cierta o no:
(na ejecucin de A que comience en un estado de ejecucin en el que se cumple % terminar
en un estado de ejecucin en el que se cumple ')
Las f'rmulas de correcci'n son una notaci'n matem!tica, no forman parte de un lenguaje de
programaci'n, sino que s'lo est!n dise+adas para ayudarnos a e/presar las propiedades sem!nticas
de los elementos soft)are.
9n estado de ejecucin de un sistema soft)are es el conjunto formado por los valores de todas las
entidades alcanables de dic$o sistema soft)are en un momento dado de su ejecuci'n.
P y 6 son aserciones. 9na asercin es una e/presi'n booleana que involucra algunas entidades de
un sistema soft)are y que establece una propiedad l'gica que dic$as entidades deben satisfacer en
uno o m!s estados de ejecuci'n. 9na tpica aserci'n puede ser la que e/presa que un entero es
positivo o la que e/presa que una referencia no es vaca. Catem!ticamente, el concepto m!s
cercano es el de predicado. De las dos aserciones, P se denomina precondicin y 6 postcondicin.
,i un estado de ejecuci'n cumple una aserci'n, se dice que dic$o estado de ejecuci'n satisface
dic$a aserci'n. 9na aserci'n *
6
implica otra aserci'n *
B
o, lo que es lo mismo, una aserci'n *
B
es
consecuencia l'gica de otra aserci'n *
6
si y s'lo si todo estado de ejecuci'n que satisface *
6
tambin satisface *
B
. De forma semejante, dos aserciones son equivalentes si las satisfacen los
mismos estados de ejecuci'n.
*$ora bien, en lugar de $ablar de los estados de ejecuci'n que satisfacen una aserci'n, podemos
$ablar de forma completamente equivalente de los estados de ejecuci'n definidos por una aserci'n,
de modo tal que toda aserci'n define un conjunto de estados de ejecuci'n formado por todos
aquellos estados que la satisfacen.
De este modo, la propiedad denotada por la f'rmula de correcci'n, que puede ser cierta o no, es
interpretada del siguiente modo:
(na ejecucin de A que comience en un estado de ejecucin definido por % terminar en un
estado de ejecucin definido por ')
* partir de esta segunda interpretaci'n de una f'rmula de correcci'n, es inmediato que se puede
considerar que, en una ;ripleta de 7oare, un elemento soft)are A implementa una relaci'n parcial r
del conjunto de posibles estados de entrada E en el conjunto de estados de salida S, tal que:
La precondici'n especifica el dominio D+m de r, o sea, el subconjunto de E en el cual se
garantia que r devuelve un resultado.
La postcondici'n especifica, para cada elemento ( de D+m, un subconjunto de S K
"esultad+s&()1, tal que r&() "esultad+s&(). "ste subconjunto puede tener m!s de un
elemento, ya que una postcondici'n no tiene por qu definir el resultado unvocamente8 as,
un estado de salida puede no ser #nico para un estado de entrada v!lido. "n este caso, A
cumple la especificaci'n si termina en cualquiera de los estados permitidos o, incluso, si es
no determinista y termina aleatoriamente en cualquiera de ellos.
Auanto mayor sea el conjunto de estados que define una aserci'n, diremos que m!s dbil es dic$a
aserci'n. * la inversa, cuanto menor sea el conjunto de estados que define, diremos que m!s fuerte
es la aserci'n.
,e dice que la aserci'n *
6
es m!s fuerte que otra aserci'n *
B
o, lo que es lo mismo, una aserci'n *
B
es m!s dbil que otra aserci'n *
6
si y s'lo si el conjunto de estados definido por *
6
est! incluido en
el conjunto de estados definido por *
B
.
Fbviamente, la aserci'n *
6
es m!s fuerte que la aserci'n *
B
si y s'lo si *
6
implica *
B
8 de forma
semejante, la aserci'n *
B
es m!s dbil que la aserci'n *
6
si *
B
es consecuencia l'gica de *
6
.
(or todo ello, la aserci'n Fals+ es la m!s fuerte posible ya que define el conjunto vaco de estados
o, lo que es equivalente, implica cualquier otra aserci'n8 de forma semejante, la aserci'n ,erdader+
es la m!s dbil posible ya que define el conjunto de todos los estados posibles o, lo que es
equivalente, es consecuencia l'gica de cualquier otra aserci'n.
*s, la f'rmula de correcci'n
7Fals+8 A 768 ' para cual1uier 6
es la panacea perfecta para quien tiene que desarrollar A. La postcondici'n se $a dejado sin
concretar porque no importa cu!l sea. "n general, una precondici'n fuerte es una buena noticia para
el desarrollador de A, ya que significa que s'lo $ay que trabajar con un conjunto limitado de
situaciones. Auanto m!s fuerte sea la precondici'n, mejor para el desarrollador de A. *$ora bien, la
precondici'n Fals+ es la aserci'n m!s fuerte posible, ya que nunca se satisface. Aualquier solicitud
de ejecutar A ser! incorrecta y la responsabilidad recae, no en el proveedor 1es decir, el
desarrollador de A1, sino en el cliente 1es decir, el que invoca a A1, ya que ste no $a cumplido la
precondici'n requerida, por la sencilla ra'n de que en este caso es imposible de cumplir. Lo que
$aga A o deje de $acer puede ser in#til pero es siempre correcto 1en el sentido, definido
anteriormente, de ser consistente con la especificaci'n1.
(ara la postcondici'n, la situaci'n se invierte. 9na postcondici'n fuerte es una mala noticia para el
desarrollador de A, ya que se restringe el conjunto de estados de salida v!lidos aumentando el
n#mero de propiedades especficas que tienen que cumplir dic$os estados. (or tanto, cuanto m!s
dbil sea la postcondici'n, mejor para el desarrollador de A. De $ec$o, la segunda panacea mejor
del mundo para el desarrollador de A es la siguiente f'rmula de correcci'n:
7P8 A 7,erdader+8 ' para cual1uier P
La precondici'n se $a dejado de concretar porque no importa cu!l sea. La postcondici'n ,erdader+
es la aserci'n m!s dbil posible ya que se satisface en todos los estados. *$ora bien, -por qu esta
panacea es solamente la segunda mejor0 La ra'n tiene que ver con un detalle que se puede $aber
observado en la definici'n del significado de una f'rmula de correcci'n: la terminaci'n. La
definici'n establece que la ejecuci'n debe terminar en un estado que satisfaga 6 siempre que se
comience en un estado que satisfaga P. Aon la primera panacea no $ay un estado que satisfaga P,
por lo que no importa lo que $aga A, aun cuando sea un te/to de programa cuya ejecuci'n provoque
un bucle infinito o provoque un fallo en el computador. Aualquier A va a ser correcto con respecto a
esa especificaci'n, ya que la precondici'n Fals+ implica que nunca se tendr! que $acer el trabajo.
,in embargo, con la segunda panacea se debe por lo menos llegar a un estado final que, aunque no
necesite satisfacer ninguna propiedad especfica, debe e/istir. Desde el punto de vista de lo que A
debe $acer quiere decir que: no es necesario $acer nada, pero se debe $acer en un tiempo finito.
"sto es as porque la ;ripleta de 7oare $a sido definida para denotar la correccin total, que
implica que, si el elemento soft)are empiea su ejecuci'n cumplindose la precondici'n, terminar!
de ejecutarse verificando la postcondici'n. *$ora bien, la propiedad de que un elemento soft)are
satisfaga su especificaci'n s'lo si termina se denomina correccin parcial8 es decir, un elemento
soft)are que es correcto parcialmente no est! obligado a terminar su ejecuci'n pero si lo $ace debe
satisfacer su especificaci'n o, dic$o de otro modo, un elemento soft)are parcialmente correcto que
empiea su ejecuci'n cumplindose la precondici'n puede no terminar pero si lo $ace terminar! de
ejecutarse verificando la postcondici'n.
,.- Co utili-ar en la pr#ctica el Diseo por Contrato
,.1.- .a cone+in entre TAD y DpC
9na clase, como ya $emos dic$o varias veces, es una implementaci'n de un tipo abstracto de datos,
bien sea especificado formalmente 1que sera lo ideal1 o bien como ocurre en muc$os casos tan s'lo
comprendido implcitamente. Las aserciones se pueden ver como una forma de reintroducir en la
clase las propiedades sem!nticas del ;*D subyacente. :amos a perfeccionar la comprensi'n de los
conceptos de las aserciones aclarando la cone/i'n de stas con los componentes de la especificaci'n
de un tipo abstracto de datos.
,eg#n establecimos, la especificaci'n de un ;*D est! formada por cuatro elementos: los p!rrafos
;H(F,, J9NAHFN",, *LHFC*, y (M"AFNDHAHFN",. Aon frecuencia se suelen pasar por alto
los dos #ltimos elementos, lo que quita muc$o atractivo al enfoque ya que las precondiciones y los
a/iomas e/presan las propiedades sem!nticas de las funciones. ,i se omiten los a/iomas y las
precondiciones, la noci'n de un ;*D concreto pasa a ser un capara'n vaco, sin otra sem!ntica que
la que sugieren los nombres de las operaciones. "ste riesgo se traslada a la programaci'n en un
lenguaje orientado a objetos: los mtodos que deberan implementar las operaciones de los tipos
abstractos de datos correspondientes podran en principio efectuar casi cualquier operaci'n. Las
aserciones son las que impiden este riesgo al volver a aportar la sem!ntica.
(ara entender la relaci'n entre las aserciones y los ;*D es necesario establecer primero la relaci'n
entre las caractersticas de las clases y sus equivalentes en los ;*D, las funciones. *nteriormente
distinguamos tres categoras de funciones en un ;*D: constructoras, consultas y 'rdenes. (ues
bien, a una funci'n constructora de un ;*D le corresponde un constructor de la clase. * una funci'n
de consulta de un ;*D le corresponde un mtodo de consulta 1tambin llamado mtodo de acceso1
de la clase. * una funci'n de orden de un ;*D le corresponde un mtodo modificador 1tambin
llamado mtodo de modificaci'n1 de la clase.
9na ve establecida la correspondencia entre las funciones de los ;*D y las caractersticas de la
clase, veamos la correspondencia entre las propiedades sem!nticas de los ;*D y las aserciones de
la clase:
9na precondici'n para una funci'n del ;*D reaparece como cl!usula de precondici'n para
el mtodo correspondiente.
9n a/ioma que involucra a una funci'n de orden, posiblemente con una o m!s funciones de
consulta m!s e/ternas en la ecuaci'n, reaparece como cl!usula de postcondici'n del mtodo
modificador correspondiente.
Los a/iomas que involucran s'lo a funciones de consulta reaparecen como postcondiciones
de los mtodos de consulta correspondientes o, especialmente si $ay m!s de una funci'n de
consulta involucrada en el a/ioma o si al menos una de las funciones de consulta se
implementa mediante un mtodo de consulta que devuelve directamente un atributo privado
de la clase, como cl!usulas del invariante de la clase.
Los a/iomas que involucran a funciones constructoras reaparecen en la postcondici'n del
constructor correspondiente de la clase.
,.2.- /recondiciones y postcondiciones
"l primer uso de las aserciones es la especificaci'n sem!ntica de los mtodos. 9n mtodo no es
solamente un troo de c'digo8 como implementaci'n de alguna funci'n de la especificaci'n de un
;*D debera realiar alguna tarea #til. "s necesario e/presar esta tarea con precisi'n, como ayuda
para el dise+o 1no se puede aspirar a asegurar que un mtodo sea correcto a menos que se $aya
especificado lo que se supone que $ace1 y como ayuda para la comprensi'n posterior del te/to. ,e
puede especificar la tarea que lleva a cabo un mtodo mediante dos aserciones asociadas al mtodo:
una precondici'n y una postcondici'n.
La precondici'n establece las propiedades que se tienen que cumplir cada ve que se llame al
mtodo, es decir, e/presa las restricciones bajo las que un mtodo funcionar! correctamente. La
precondici'n se aplica a todas las llamadas al mtodo, tanto desde dentro de la clase como desde los
clientes. 9n sistema correcto nunca ejecutar! una llamada en un estado en que no se satisfaga la
precondici'n del mtodo al que se llama.
La postcondici'n establece las propiedades que debe garantiar el mtodo cuando retorne, es decir,
e/presa propiedades del estado resultante de la ejecuci'n de un mtodo. La presencia de una
postcondici'n en un mtodo e/presa una garanta por parte de quien implementa el mtodo de que
ste producir! un estado en el que se satisfagan ciertas propiedades si se supone que ste $a sido
invocado satisfacindose la precondici'n.
Definir una precondici'n y una postcondici'n para un mtodo es una forma de definir un contrato
que liga al mtodo con quienes lo llaman.
*l asociar una precondici'n pre y una postcondici'n p+st con un mtodo m la clase le est! diciendo
a sus clientes:
*+i usted me promete llamar a m con pre satisfec,o entonces -o le prometo entregar un estado
final en el que post es satisfec,o).
9n par pre1postcondici'n de un mtodo describe el contrato que el mtodo 1el proveedor de un
cierto servicio1 define para los que lo llaman 1los clientes del servicio1. 9n buen contrato entra+a
tanto obligaciones como beneficios para ambas partes, ya que lo que es una obligaci'n para uno se
convierte en un beneficio para el otro. *s:
La precondici'n compromete al cliente: define las condiciones bajo las cuales es legtima la
llamada a un mtodo. "s una obligaci'n para el cliente y un beneficio para el proveedor.
La postcondici'n compromete a la clase: define las condiciones que debe asegurar el
mtodo al retornar. "sto es un beneficio para el cliente y una obligaci'n para el proveedor.
Los beneficios son para el cliente la garanta de que ciertas propiedades se van a cumplir despus de
la llamada, y para el proveedor que se puede suponer que determinados presupuestos se van a
cumplir cada ve que se llame a la rutina.
Las obligaciones para los clientes son satisfacer los requisitos que establecen las precondiciones y
para los proveedores cumplir con la tarea que establecen las postcondiciones.
La precondici'n es un beneficio para el proveedor porque si la parte del cliente no se cumple, es
decir, si la llamada no satisface la precondici'n, entonces la clase no est! obligada a cumplir la
postcondici'n. "n este caso, el mtodo puede $acer lo que quiera: retornar cualquier valor, caer en
un bucle infinito sin retornar valor alguno o incluso acabar con la ejecuci'n de una manera dr!stica.
Gste es el caso en el cual %el cliente est! equivocado&.
La primera ventaja de esta convenci'n es que simplifica considerablemente el estilo de
programaci'n. 7abiendo especificado como precondici'n las restricciones bajo las cuales se puede
llamar a un mtodo, el que desarrolla la clase puede suponer, cuando escribe el cuerpo del mtodo,
que las restricciones se satisfacen, por lo que no es necesario verificar stas en el cuerpo del
mtodo8 de $ec$o, el dise+o por contrato va m!s all!: no solamente es innecesario, sino que es
inaceptable. "s lo que se conoce como principio de no redundancia:
/ajo ninguna circunstancia debe el cuerpo del mtodo verificar el cumplimiento de la
precondicin del mtodo)
"sta regla es contraria a lo que se conoce a menudo con el nombre de pr+2ramaci4n de0ensiva. Gsta
establece que para obtener soft)are fiable $ay que dise+ar componentes que se protejan a s mismos
lo m!s posible. "s mejor comprobar demasiado, seg#n este enfoque, que demasiado poco: uno
nunca es demasiado cuidadoso cuando tiene que tratar con e/tra+os. 9na comprobaci'n redundante
puede no ayudar, pero al menos no $ace da+o.
"l dise+o por contrato proviene de la observaci'n opuesta: las comprobaciones redundantes pueden
$acer da+o. (or supuesto que esto al principio puede parecer raro: la reacci'n natural es la de pensar
que una comprobaci'n adicional, como por ejemplo una instrucci'n condicional para comprobar si
el argumento de un mtodo es un n#mero negativo, pudiera ser in#til, pero posiblemente no cause
ning#n da+o. ,in embargo, un comentario como ste proviene de una comprensi'n microsc'pica de
lo que es fiabilidad, que se centra en los elementos individuales de soft)are. ,i se restringe el
panorama al estrec$o mundo de un #nico mtodo, entonces puede parecer que dic$o mtodo es m!s
robusto con una comprobaci'n adicional que sin ella. (ero el mundo de un sistema soft)are no est!
restringido a un mtodo: contiene una multitud de mtodos en una multitud de clases. (ara obtener
sistemas soft)are fiables, se debe pasar del enfoque microsc'pico a una visi'n macrosc'pica que
considere la arquitectura completa.
,i se considera esta visi'n global, la sencille se convierte en un criterio crucial. Aomo ya se sabe,
la complejidad es el mayor enemigo de la calidad. Auando se tiene esto en cuenta, las posibles
comprobaciones redundantes >ya no aparecen tan inocuas? "/trapoladas a miles de mtodos de un
sistema soft)are de tama+o medio 1o decenas o cientos de miles de mtodos en uno muy grande1, la
comprobaci'n adicional anterior basada en una #nica instrucci'n condicional, que es inocua a
primera vista, comiena a parecer un monstruo de complejidad in#til. *l a+adir comprobaciones
posiblemente redundantes se a+ade m!s soft)are, m!s soft)are significa m!s complejidad y en
particular m!s fuentes de condiciones que pueden ser err'neas8 de aqu la necesidad de m!s
comprobaciones, lo que significa m!s soft)are y as $asta el infinito. ,i arrancamos en este camino
s'lo una cosa es cierta: nunca se obtendr! fiabilidad. Auanto m!s se escriba, m!s se tendr! que
escribir.
(ara evitar esta persecuci'n infinita, >nunca se debera empear? "l dise+o por contrato invita a
identificar las condiciones de consistencia que son necesarias para el funcionamiento correcto de
cada cooperaci'n cliente1proveedor 1es decir, cada contrato1 y a especificar, para cada una de estas
condiciones, de quin es la responsabilidad de asegurar la misma: del cliente o del proveedor. 9na
ve que se $a tomado una decisi'n, $ay que basarse en ella: si en una prec+ndici4n aparece un
re1uisit+ de c+rrecci4n' l+ cual indica 1ue el re1uisit+ es parte de la resp+nsabilidad del cliente' n+
debe 9aber una c+mpr+baci4n c+rresp+ndiente en el m:t+d+; y si n+ est< en una prec+ndici4n'
ent+nces el m:t+d+ debe c+mpr+bar el re1uisit+.
,eg#n se acaba de decir, la idea que se e/presa como principio de no redundancia indica que, para
cualquier condici'n de consistencia que pudiera $acer peligrar el funcionamiento apropiado del
mtodo, se le debe asignar el asegurar esta condici'n a una sola de las dos partes del contrato. -*
cu!l de las dos0 La respuesta puede variar, y es en parte un asunto de estilo de dise+o. 7ay dos
posibilidades obvias:
F se le asigna la responsabilidad a los clientes, en cuyo caso la condici'n aparecer! como
parte de la precondici'n del mtodo, y recibe el nombre de dise!o exigente de las
precondiciones.
F se le pasa al proveedor en cuyo caso la condici'n aparecer! en una instrucci'n
condicional en el cuerpo del mtodo, y recibe el nombre de dise!o tolerante de las
precondiciones.
-Au!l es el mejor estilo0 7asta cierto punto es un asunto de criterio personal, al contrario que el
principio de no redundancia, que es absoluto cuando establece que nunca es aceptable tratar una
condici'n de correcci'n desde ambos lados, el del cliente y el del proveedor. *rgumentos fuertes
pudieran tenerse, sin embargo, para el estilo e/igente, especialmente en el caso de que se quiera que
el soft)are sea reutiliable, y en el desarrollo orientado a objetos siempre se debiera escribir el
soft)are con el objetivo final de $acerlo reutiliable.
* primera vista el estilo tolerante pudiera parecer mejor tanto para la reutiliaci'n como para la
fiabilidad8 despus de todo el enfoque e/igente parece pasar m!s responsabilidad a los clientes y
tpicamente $ay muc$os clientes para un mismo proveedor, incluso m!s en el caso de una clase
reutiliable. -No es preferible entonces dejar que sea el proveedor el que se ocupe de las
condiciones de correcci'n de una ve por todas, en lugar de estar requirindole a cada cliente que lo
$aga por s mismo0
,i se mira m!s de cerca esta cuesti'n, este raonamiento no se cumple. Las condiciones de
correcci'n describen lo que requieren las rutinas para ser capaces de $acer su trabajo correctamente.
:eamos un contraejemplo. Hmaginemos un mtodo desapila tolerante para una clase que
implementa las pilas: -qu puede $acer un pobre mtodo para quitar un elemento de la pila si sta
est! vaca0 Gsta puede $acer un intento rebelde de dar como salida un mensaje de error, pero esto es
claramente inadecuado: un m'dulo cliente especialiado tal como un manejador de pila no $ace
nada con un mensaje al usuario. ,e debiera tratar de $acer algo m!s sofisticado, pero simplemente
desapila no se encuentra en el conte/to apropiado para ello8 el foco de la clase que implementa las
pilas es demasiado estrec$o para determinar qu $acer en caso de una pila vaca. ,'lo el cliente 1un
m'dulo que est! usando pilas en alguna aplicaci'n1 tiene suficiente informaci'n para decidir qu es
lo que significa realmente un intento de quitar un elemento si la pila est! vaca: -es sta una
solicitud normal aunque in#til que simplemente se debiera ignorar ejecutando una operaci'n nula0
-F por el contrario es un error y por tanto $ay que tratarlo: lanar una e/cepci'n, corregir la
situaci'n antes de intentarlo de nuevo o 1la respuesta menos probable1 dar como salida un mensaje
de error visible para el usuario0
"n el espritu del dise+o por contrato, el enfoque e/igente en el dise+o de la precondici'n no intenta
producir mtodos que $agan todas las cosas para todos los clientes. "n lugar de esto, se insiste en
que cada mtodo realice una tarea bien definida y la $aga bien <correctamente, eficientemente, lo
suficientemente general para que sea reutiliable por muc$os clientes...= y que se especifique
claramente cu!les son los casos que el mtodo no puede manejar. De $ec$o no se puede esperar que
el mtodo $aga bien su trabajo a menos que se $aya circunscrito cuidadosamente su misi'n. 9n
mtodo fact'tum, que quiera $acer un c!lculo, verificar los casos anormales y tomar acciones
correctivas, notificar a los clientes y a su ve producir de todas maneras un resultado, tiene grandes
posibilidades de no llegar a satisfacer correctamente ninguno de estos objetivos.
"l autor de un mtodo no tiene que ser m!s listo que los clientes8 si no est! seguro de lo que tiene
que $acer el mtodo en una cierta situaci'n anormal, debe e/cluir sta e/plcitamente en la
precondici'n.
*$ora bien, el dise+o e/igente de las precondiciones s'lo es aplicable si las precondiciones se
mantienen raonables. -Qu es lo que significa %raonable& para la precondici'n de un mtodo0 *
continuaci'n se da una caracteriaci'n m!s precisa, mediante el principio de la precondicin
razonable:
0a precondicin de todo mtodo en el dise!o exigente de las precondiciones debe satisfacer los
siguientes requisitos1
0a precondicin aparece en la documentacin oficial distribuida a los autores de los
mdulos clientes)
2s posible justificar la necesidad de una precondicin exclusivamente en trminos de la
especificacin)
"l segundo requisito e/cluye restricciones que sean s'lo para conveniencia del proveedor al
implementar el mtodo. (or ejemplo, cuando se quiere quitar un elemento de una pila la
precondici'n que e/ige que la pila no est vaca es un requisito l'gico que puede ser justificado en
trminos de la especificaci'n solamente, mediante la simple observaci'n de que en una pila vaca
no $ay nada que quitar8 y, por ejemplo, cuando se computa la ra cuadrada de un n#mero real, la
precondici'n que e/ige que el n#mero sea mayor o igual que cero es un resultado directo de la
propiedad matem!tica de que los n#meros reales negativos no tienen races cuadradas reales.
*lgunas restricciones pueden surgir debido a la forma general de implementaci'n que se seleccione.
(or ejemplo, utiliar un array para implementar las pilas tendr! como conscuencia que el mtodo
apila tenga una precondici'n que e/ija que la pila no est llena. (ero un caso como ste no viola el
principio porque la naturalea acotada de dic$a implementaci'n se $ace parte de la especificaci'n:
la clase no se anunciar! para representar pilas arbitrarias, sino s'lo pilas de una capacidad m!/ima
finita. "l tipo abstracto de datos que sirve de especificaci'n a esta clase no es la noci'n m!s general
de pila, sino la noci'n de pila acotada.
"s importante $acer notar que los contratos que aqu se discuten ocurren entre un mtodo 1el
proveedor1 y otro mtodo 1el cliente que lo llama18 lo que nos concierne es la comunicaci'n de
soft)are con soft)are, no la comunicaci'n de soft)are con $umano ni la comunicaci'n de soft)are
con mundo e/terior. 9na precondici'n no se ocupa de corregir la entrada del usuario. "n este caso
no $ay sustituto para las estructuras condicionales $abituales de verificaci'n de condiciones. Las
aserciones no tienen ning#n papel que jugar en la soluci'n del problema de la validaci'n de la
entrada del mundo e/terior 1de sensores, de entradas del usuario, de una red...1, de modo que en la
obtenci'n de informaci'n del mundo e/terno no se puede basar uno en precondiciones. "n este
conte/to, el dise+o tolerante de las precondiciones es #til para los elementos soft)are que tienen
que ver no con otros elementos soft)are sino con datos que provienen del mundo e/terior, tales
como entradas del usuario o datos provenientes de un sensor8 sin embargo, para m'dulos cuyos
clientes son otros m'dulos soft)are, el dise+o e/igente de las precondiciones suele ser el adecuado.
9na confusi'n com#n es pensar en las aserciones como estructuras de control para manejar casos
especiales. Debe quedar claro que ste no es su papel. ,i se quiere escribir un mtodo que calcule la
ra cuadrada de un n#mero real y trate los argumentos negativos de cierta manera y los argumentos
no negativos de otra manera, entonces no se necesita una precondici'n sino las cl!sicas estructuras
de control condicionales.
Las aserciones son otra cosa. "/presan las condiciones de correcci'n. ,i dic$o mtodo que calcula
la ra cuadrada de un n#mero real tiene una precondici'n que e/ige que el argumento sea mayor o
igual que cero, una llamada a dic$o mtodo con un argumento negativo no es un caso especial: es
un error simple y llano. 2 dada la visi'n de las aserciones como contrato, podemos enunciar la
regla de violacin de las aserciones:
0a violacin en tiempo de ejecucin de una asercin es la manifestacin de un error en
el softare)
0a violacin de una precondicin es la manifestacin de un error en el cliente)
0a violacin de una postcondicin es la manifestacin de un error en el proveedor)
9na violaci'n de una precondici'n significa que el mtodo que llama, aunque est! obligado por el
contrato a satisfacer un cierto requisito, no lo $a $ec$o. "sto es un error del cliente como tal, la
rutina a la que se llama no tiene la culpa. 9n observador e/terno pudiera por supuesto criticar un
contrato porque e/ige demasiado, pero es demasaido tarde para argumentar en contra del contrato:
ste es el contrato y el cliente no $a cumplido su parte del trato. (or tanto, $ay un mecanismo para
monitoriar las aserciones durante la ejecuci'n y si ste detecta una violaci'n de la precondici'n, el
mtodo no se ejecutar!. ,e $an establecido las condiciones bajo las cuales puede funcionar y estas
condiciones no se $an cumplido: tratar de ejecutar el mtodo no tendra sentido.
La violaci'n de una postcondici'n significa que el mtodo, presumiblemente invocado en
condiciones correctas, no $a sido capa de cumplir con su contrato. *qu tambin est! clara la
distribuci'n de la culpa y la inocencia, aunque es la inversa de lo anterior: el error est! en el
mtodo, el que llama es el inocente.
,.3.- *nvariantes de clase
Las precondiciones y las postcondiciones describen las propiedades sem!nticas de los mtodos
individuales. ;ambin es necesario e/presar las propiedades sem!nticas globales de todas las
instancias de una clase, que deben ser preservadas por todos los mtodos. ;ales propiedades
sem!nticas constituyen el invariante de la clase y capturan las restricciones de integridad que
caracterian a una clase.
9n invariante de clase es una aserci'n que e/presa restricciones de consistencia generales que se
aplican a cada instancia de la clase como un todo8 por tanto, es diferente de las precondiciones y las
postcondiciones, que caracterian a mtodos individuales.
9n invariante de una clase es una aserci'n que debe satisfacer cada instancia de la clase en todos los
momentos estables. Los momentos estables de una instancia de una clase son aquellos en los que el
objeto es observable desde fuera, en el sentido de que un cliente le puede aplicar una caracterstica.
"stos momentos estables son:
"l estado resultante de la creaci'n del objeto.
"l estado inmediatamente antes y despus de una llamada ejecutada por un cliente a un
mtodo de la clase de ese objeto.
(ese a su nombre, el invariante no tiene que satisfacerse en todo momento. "s perfectamente
aceptable que un mtodo empiece a intentar alcanar su objetivo 1es decir, su postcondici'n1 y que
durante ese proceso destruya el invariante8 de este modo, en algunas etapas intermedias el
invariante no se cumplir!, lo que est! bien siempre y cuando el mtodo restableca el invariante
antes de terminar su ejecuci'n.
La obligaci'n de mantener el invariante s'lo se aplica al cuerpo de los mtodos que se e/portan, ya
que estos mtodos que se ejecutan por parte de un cliente siempre deben partir de un estado que
satisfaga al invariante y terminar en un estado que tambin satisfaga al invariante. 9n mtodo
privado o secreto 1y que, por tanto, no est! disponible para ning#n cliente1 no est! afectado por el
invariante, ya que estos mtodos no son ejecutados directamente por los clientes sino que sirven
s'lo como $erramientas au/iliares para llevar a cabo las necesidades de los mtodos e/portados.
*$ora podemos preguntarnos: -qu significara que un invariante se viole durante la ejecuci'n de
un sistema soft)are0 La respuesta es la de considerar a los invariantes en el mismo caso que las
postcondiciones: la violaci'n de un invariante es la manifestaci'n de un error en el proveedor.
9na ve que ya sabemos qu son las precondiciones, las postcondiciones y los invariantes, podemos
definir lo que significa que una clase sea correcta. La base de la respuesta ya $a sido estudiada: una
clase, como cualquier otro elemento soft)are, es correcta o incorrecta no por s misma sino con
respecto a una especificaci'n. Hntroduciendo las precondiciones, postcondiciones e invariantes se
tiene una forma de incluir la especificaci'n en el propio te/to de la clase. "sto proporciona una base
para precisar la correcci'n: la clase es correcta si y s'lo si su implementaci'n, seg#n se da en los
cuerpos de los mtodos, es consistente con las precondiciones, las postcondiciones y los invariantes.
,ea C una clase e inv el invariante de la clase. (ara cada mtodo m de la clase, se llamar! pre
m
&(
m
) y
p+st
m
&(
m
) a su precondici'n y su postcondici'n respectivamente, donde (
m
denota a los posibles
argumentos de m, a los cuales se pueden referir tanto la precondici'n como la postcondici'n. ,i la
precondici'n o la postcondici'n no aparecen en el te/to del mtodo quiere decir que pre
m
o p+st
m
son ,erdader+. Llamemos Cuerp+
m
al cuerpo del mtodo m. (or #ltimo, sea P+r=de0ect+
C
la
aserci'n que e/presa que los atributos de C tienen los valores por defecto de sus tipos respectivos.
Aon estas notaciones podemos definir la regla de correccin de una clase:
(na clase es correcta con respecto a sus aserciones si - slo si1
%ara cada conjunto vlido de argumentos x
p
de un constructor p1
$%or3defecto
"
and pre
p
4x
p
5& "uerpo
p
$post
p
4x
p
5 and inv&
%ara cada mtodo exportado r - cualquier conjunto x
r
de argumentos vlidos1
$pre
r
4x
r
5 and inv& "uerpo
r
$post
r
4x
r
5 and inv&
:amos a estudiar con detenimiento esta regla:
"l estado de un objeto est! definido por los valores de los atributos de la clase para esta
instancia en particular. "l estado inicial de un objeto es el estado que tiene dic$o objeto
inmediatamente antes de una llamada ejecutada por un cliente a un mtodo e/portado por la
clase de ese objeto. "l estado final de un objeto es el estado que tiene dic$o objeto
inmediatamente despus de una llamada ejecutada por un cliente a un mtodo e/portado por
la clase de ese objeto.
,e considera que toda clase tiene al menos un constructor. ,i ning#n constructor $a sido
definido e/plcitamente, se puede considerar que la clase tiene un constructor
predeterminado implcito que tiene un cuerpo vaco. *plicar la primera condici'n al
constructor predeterminado significa entonces que los valores por defecto de los atributos de
la clase deben satisfacer el invariante. (or otra parte, para cualquier constructor que se
defina e/plcitamente, la primera condici'n establece que cuando se llama con argumentos
que satisfacen su precondici'n y en un estado inicial donde los atributos tienen sus valores
por defecto, produce un estado final que satisface el invariante de la clase y la postcondici'n
del constructor.
La precondici'n de un mtodo puede involucrar al estado inicial y a los argumentos de ese
mtodo. La postcondici'n puede involucrar al estado final, al estado inicial y, en el caso de
que el mtodo devuelva un valor, al valor proporcionado por el mtodo. "l invariante s'lo
puede involucrar el estado del objeto.
La segunda condici'n de la regla establece que todo mtodo e/portado de la clase, cuando
se llama con argumentos que satisfacen su precondici'n y en un estado inicial que satisface
tanto el invariante como la precondici'n del mtodo, termina y produce un estado final que
satisface el invariante y la postcondici'n del mtodo.
Aomo ya $emos visto, las f'rmulas de correcci'n no comprometen al elemento soft)are de
ninguna forma en los casos en lo que la precondici'n no se satisface con antelaci'n. *s, el
contrato no es vinculante para el mtodo si el cliente fall' al cumplir con su parte del trato.
De acuerdo con esto, la definici'n de correcci'n de una clase deja a los mtodos de la clase
la libertad de $acer lo que quieran en una llamada que viole la precondici'n o el invariante.
,eg#n esta regla de correcci'n, se puede considerar el invariante como una aserci'n que se a+ade
implcitamente a la precondici'n y a la postcondici'n de cada mtodo que se e/porte. De modo que
en principio la noci'n de invariante es superflua: se puede pasar sin l si se enriquecen las
precondiciones y las postcondiciones de todos los mtodos de la clase.
9na transformaci'n como sta, por supuesto, no es deseable. Aomplicara los te/tos de los mtodos
y, lo que es m!s importante, se perdera el significado m!s profundo de los invariantes, que
trasciende a los mtodos individuales y se aplica a la clase como un todo. ,e podra considerar de
$ec$o que el invariante se aplica no s'lo a los mtodos que est!n escritos realmente en la clase, sino
a todo lo que se pueda a+adir m!s tarde, de modo que servira como control sobre la evoluci'n
futura de la clase.
"n el desarrollo del soft)are el cambio es inevitable e intentamos controlarlo. Aabe esperar que
algunos aspectos de los sistemas soft)are y de sus componentes individuales 1las clases1 cambien
m!s r!pidamente que otros. "n particular a+adir, quitar o cambiar caractersticas de de una clase es
un suceso frecuente y normal. "n este proceso desearemos basarnos en aquellas propiedades que,
aunque pudieran cambiar tambin, cambiar!n con muc$a menos frecuencia. Los invariantes, debido
a que capturan las restricciones fundamentales que se aplican a una clase, juegan este papel.
Aomo $emos visto, desde el punto de vista l'gico se puede considerar al invariante como algo
a+adido a toda precondici'n y a toda postcondici'n de todo mtodo e/portado. :amos a reproducir
la segunda condici'n de la regla de una manera simplificada. ,ea cuerp+ el cuerpo de un mtodo,
pre su precondici'n, p+st su postcondici'n e inv el invariante de la clase. "l requisito de correcci'n
de un mtodo se puede e/presar mediante la siguiente f'rmula de correcci'n:
7inv and pre8 cuerp+ 7inv and p+st8
"sta f'rmula de correcci'n significa que cualquier ejecuci'n de cuerp+ que comience en un estado
inicial en el cual inv y pre se cumplen, terminar! en un estado final en el que inv y p+st se cumplen.
Lo que queremos preguntarnos a$ora es: para el proveedor 1la persona que escribe cuerp+1 -el
invariante es una buena o una mala noticia, es decir, le $ace la tarea m!s f!cil o m!s difcil0 La
respuesta es: ambas cosas. *l a+adir inv se fortalece tanto a la pre como a la postcondici'n ya que,
de las reglas de la l'gica, a and b implica siempre a, es decir, a and b es m!s fuerte que a. (or
tanto, si se est! a cargo de implementar el cuerpo, el invariante:
Jacilita esta tarea: adicionalmente a la precondici'n oficial pre se puede suponer que el
estado inicial satisface inv, lo que restringe m!s el conjunto de casos que $ay que manejar.
Dificulta la tarea: adicionalmente a la postcondici'n oficial p+st, $ay que asegurar a$ora
tambin que el estado final satisface inv.
"stas observaciones son consistentes con el punto de vista de que el invariante es una condici'n
general de consistencia que se aplica a la clase como un todo y por consiguiente a todos sus
mtodos. Aomo autor de uno de estos mtodos, uno se beneficia de poder suponer que esta
condici'n se cumple al comieno del mtodo, pero se tiene la obligaci'n de asegurar que se siga
satisfaciendo al terminar el mtodo, de modo que el pr'/imo mtodo que sea aplicado al mismo
objeto pueda dar por supuesto su cumplimiento.
"stas refle/iones sobre los invariantes producen tambin una mejor comprensi'n de los
constructores. 9n invariante de clase e/presa el conjunto de propiedades que los objetos 1las
instancias de la clase1 deben satisfacer en lo que se $a denominado momentos estables de su
e/istencia. "n particular, estas propiedades se debn cumplir despus de crearse la instancia.
"l mecanismo est!ndar de asignaci'n de objetos en memoria inicialia los atributos d!ndoles los
valores por defecto de los tipos correspondientes de los atributos8 a$ora bien, estos valores pueden o
no satisfacer el invariante. ,i no lo satisfacen, se requiere un constructor e/plcito que debe dar
valores a los atributos de modo que se satisfaga el invariante. *s que el papel de un constructor
debe verse coomo el medio para asegurar que una instancia de una clase, cuando comiena su vida,
ya satisface la regla fundamental de su casta 1 el invariante de su clase. De este modo, la
construcci'n debe verse como la operaci'n que asegura que todas las instancias de una clase
comienan sus vidas de modo correcto 1uno en el que se cumple el invariante de la clase.
"l mtodo orientado a objetos utilia un modelo de ejecuci'n que es muy fle/ible porque $ace un
uso e/tensivo de las referencias. Desafortunadamente, este modelo de ejecuci'n puede ocasionar
conflictos cuando se junta con la noci'n de invariante de clase. ,i ( e y son referencias a objetos e y
es no vaco, la asignaci'n ( > y da lugar a que tanto ( como y estn conectados al mismo objeto8 es
decir, el resultado es ligar ( e y de una forma duradera, $asta que se produca alguna asignaci'n
posterior a cualquiera de ellos. La cone/i'n de ( al mismo objeto que y produce una compartici'n
de estructura y se conoce como alias dinmico 1en ingls dynamic aliasin21: alias porque la
asignaci'n $ace que se pueda acceder a un objeto a travs de dos referencias, y din!mico porque el
alias ocurre en tiempo de ejecuci'n. *s, realiar la llamada (?0&), donde 0 es un mtodo de la clase
correspondiente, tendr! el mismo efecto que y?0&) puesto que afectan al mismo objeto. "s decir, (?0&)
afecta a y a#n a pesar de que y es una entidad a la cual no $ace referencia.
"l problema es que, debido al alias din!mico, no es posible comprobar la correcci'n de una clase
sobre la base de la clase solamente. ,e $a visto la correcci'n de una clase en trminos de dos
condiciones que e/presan 1concentr!ndonos en el invariante inv e ignorando las precondiciones y
las postcondiciones que no juegan un papel directo aqu1: la primera, (6, que cada constructor
produce objetos que satisfacen inv y la segunda, (B, que cada mtodo e/portado preserva inv.
"stas dos condiciones parecen suficientes para garantiar que inv es realmente invariante. La prueba
es aparentemente trivial: puesto que inv ser! satisfec$o inicialmente y preservado por cada llamada
a un mtodo e/portado, por inducci'n debera satisfacerse en todos los momentos estables. ,in
embargo, esta prueba informal no es v!lida en presencia de alias din!micos. "l problema es que un
atributo de un objeto podra ser modificado por una operaci'n sobre otro objeto. De modo que aun
cuando todas las operaciones a?r preserven inv sobre el objeto OA de la clase A conectado con a, las
propiedades de * pueden involucrar instancias de otras clases 1por ejemplo, de la clase D1 y la
prueba de correcci'n anterior no dice nada sobre el efecto de estas caractersticas de otras clases
sobre el invariante de * de modo que una cierta operaci'n b?s 1para un b conectado a otro objeto
O* de la clase *1 podra destruir el invariante inv de OA. De modo que aun cumplindose las
condiciones (6 y (B, inv pudiera no ser un invariante.
"ste problema tiene un nombre: 2fecto 6ndirecto del 6nvariante. (uede aparecer tan pronto como
se permitan los alias din!micos, mediante los cuales una operaci'n podra modificar un objeto aun
sin involucrar a ninguna entidad asociada a l mediante una referencia.
(or ello, si se desea monitoriar las aserciones en tiempo de ejecuci'n para garantiar que se
cumplen, es necesario comprobar que se cumple el invariante de clase al entrar y al salir de un
mtodo e/portado. -(or qu al entrar y al salir0 ,in el efecto indirecto del invariante sera suficiente
comprobar el invariante s'lo al salir de las llamadas a constructores y a mtodos e/portados. (ero
a$ora $ay que ser m!s cuidadoso, ya que entre la culminaci'n de una llamada y el comieno de otra
llamada aplicada al mismo objeto, otra llamada pudiera $aber afectado a dic$o objeto aun cuando el
receptor $aya sido otro objeto distinto.
"s tambin responsabilidad del proveedor tener en cuenta el alias din!mico para garantiar que el
invariante de clase se satisface a la entrada del mtodo y no s'lo a la salida. (or ello, la violaci'n
del invariante es responsabilidad suya y no del cliente.
,.$.- Epleo del DpC en 0ava
9na ve establecidos los principios b!sicos de c'mo aplicar en la pr!ctica el DpA, es necesario que
los pongamos en pr!ctica abordando el estudio de un caso pr!ctico para conocer y resolver las
dificultades que se puedan presentar.
Aomo ya comentamos en su momento, vamos a usar Iava como lenguaje de programaci'n
orientado a objetos. Iava no tiene directamente integrado de forma nativa el DpA, as que
simularemos ste mediante los mecanismos del lenguaje.
"l objetivo es desarrollar una clase que implemente el ;*D Pila[G] que se especific'
formalmente con anterioridad. La clase ser! genrica, bajo la forma:
pac/a0e or012omave0er1d3c4
566
6
6 7a$"8or 2omave0er
6 93r: 93r:
6 7descrip"ion Pilas: $na es"r$c"$ra dispensadora con pol"ica ;<(=: el
6 >l"imo elemen"o en en"rar es el primero en salir1 ?ienen capacidad
6 ilimi"ada1
65
p$3lic class Pila9G: +
111
,
Los puntos suspensivos indican que completaremos lo que falta despus.
7agamos una observaci'n sobre las clases genricas. ,eg#n $emos visto, una clase es un tipo de
datos. Desde un punto de vista formal, se puede afirmar que, con la genericidad, esta afirmaci'n no
es literalmente verdadera, aunque la diferencia sea peque+a. 9na clase genrica C@$A es, en lugar
de un tipo de datos, un patr'n de tipos de datos que abarca un conjunto infinito de posibles tipos de
datos8 se puede obtener uno de estos tipos de datos al proporcionar un par!metro genrico real o
actual 1que es a su ve un tipo de datos1 que corresponde a $. "sto es completamente an!logo a lo
que se e/plic' en su momento sobre ;*Ds genricos.
;odo esto nos lleva a una noci'n m!s general y fle/ible. (ero para ganar en potencia $ay que pagar
un peque+o precio en sencille: s'lo mediante un peque+o abuso del lenguaje se puede seguir
$ablando, si ( se $a declarado de tipo T, de las %caractersticas de T& o de los %clientes de T&8 m!s
que una clase, T puede ser a$ora un tipo C@UA derivado genricamente de alguna clase genrica C
y alg#n tipo U. (or supuesto que sigue estando involucrada una clase 1la clase C1, por lo que este
abuso del lenguaje es aceptable.
Auando se necesite ser riguroso la terminologa debe ser la siguiente. ;odo tipo T est! asociado con
una clase, la clase base de T, de modo que siempre es correcto $ablar de las caractersticas o los
clientes de la clase base de T. ,i T es una clase no genrica, entonces ; es su propia clase base. ,i T
es una derivaci'n genrica de la forma C@UA entonces la clase base de T es C.
No obstante, esta e/plicaci'n, que desde un punto de vista formal es correcta, no es aplicable a Iava
porque en este lenguaje la genericidad se implementa mediante borrado de tipos 1en ingls type
erasure1, de modo que para la m!quina virtual todos los objetos pertenecen a clases no genricas,
por lo que e/iste un #nico tipo de datos asociado a una clase genrica8 en este caso, una clase s que
es siempre un tipo de datos y nunca es realmente un patr'n de tipos de datos. Auando en Iava se
define una clase genrica, se proporciona autom!ticamente su tipo de datos asociado, que se
denomina tipo de datos puro, y cuyo nombre es simplemente el nombre de la clase genrica
despus de eliminar los par!metros genricos formales.
Aontinuemos con nuestra clase genrica. *ntes de considerar cuestiones de implementaci'n es
importante observar que los mtodos est!n caracteriados por fuertes propiedades sem!nticas que
son independientes de una representaci'n especfica. (or ejemplo:
Los mtodos desapila y cima s'lo son aplicables si la pila no est! vaca.
"l mtodo apila $ace que la pila deje de estar vaca en caso de que lo estuviera antes de
aplicar el mtodo.
;ales propiedades son parte de la especificaci'n de un tipo abstracto de datos e incluso la gente que
no use ning#n enfoque remotamente tan formal como los ;*Ds las contempla implcitamente8 pero
en los enfoques m!s comunes de construcci'n de soft)are los te/tos soft)are no revelan rastro de
ellas. Cediante las precondiciones y postcondiciones de los mtodos se puede convertirlas en
elementos e/plcitos del soft)are.
(artiendo de la especificaci'n del ;*D desarrollada con anterioridad, es evidente que a la funci'n
constructora crea le corresponder! un mtodo constructor, a cada una de las funciones de consulta
cima y vaca les corresponder! un mtodo de acceso con el mismo nombre y a cada una de las
funciones de orden apila y desapila les corresponder! un mtodo de modificaci'n con el mismo
nombre.
*$ora bien, imaginemos que encontramos #til a+adir una nueva operaci'n a la clase, que se llama
cuenta, que devuelve el n#mero de elementos que est!n actualmente apilados en la pila. -"s esto un
problema0 Fbviamente no. La adici'n de m!s operaciones a la clase no es una diferencia
importante debido a que pueden especificarse algebraicamente y, por tanto, pueden incluirse en la
especificaci'n del tipo abstracto de datos. *s, la operaci'n cuenta se especificara mediante los
siguientes a/iomas:
c$en"a: Pila[G] @n"ero
Para c$al%$ier &:G, p:Pila[G],
c$en"a(crea) # 0
c$en"a(apila(p, &)) # ! A c$en"a(p)
"stos a/iomas son bastante evidentes. "l primero afirma que el n#mero de elementos actualmente
apilados en una pila vaca es cero. "l segundo a/ioma afirma que el n#mero de elementos
actualmente apilados en una pila es uno 1el que corresponde a la cima de la pila1 m!s el n#mero de
elementos apilados en esa pila $abindosele quitado la cima puesto que sta ya $a sido contada.
:eamos a continuaci'n la clase completamente implementada:
pac/a0e or012omave0er1d3c4
impor" 2ava1io1BB"eCrraB<np$"D"ream4
impor" 2ava1io1BB"eCrraB=$"p$"D"ream4
impor" 2ava1io1=32ec"<np$"D"ream4
impor" 2ava1io1=32ec"=$"p$"D"ream4
impor" 2ava1$"il1CrraB;is"4
566
6
6 7a$"8or 2omave0er
6 93r: 93r:
6 7descrip"ion Pilas: $na es"r$c"$ra dispensadora con pol"ica
6 ;<(=: el >l"imo elemen"o en en"rar es el primero en salir1
6 ?ienen capacidad ilimi"ada1
6 93r: 93r:
6 7invarian"
6 c$en"a() :) 0
6 93r:93r:
6 7invarian"Priva"e
6 c$en"a() )) represen"a"ion1siEe() 93r:
6 (c$en"a() : 0) implies (represen"a"ion10e"(c$en"a() - !) )) cima())
65
p$3lic class Pila9G: +
priva"e CrraB;is"9G: represen"a"ion4
priva"e 3oolean 0$arda ) False4
priva"e void invarian"() +
"8is10$arda ) "r$e4
asser" ("8is1c$en"a() :) 0) GG
("8is1c$en"a() )) "8is1represen"a"ion1siEe()) GG
(H("8is1c$en"a() : 0) II
"8is1represen"a"ion10e"("8is1c$en"a() - !) )) "8is1cima()) :
J'iolaciKn del <nvarian"e de la LlaseJ4
"8is10$arda ) False4
,

566
6 Lrea $na pila vaca
6
6 7pos"
6 vacia() 93r:
6 c$en"a() )) 0
6 93r:93r:
6 7pos"Priva"e
6 represen"a"ion H) n$ll
65
p$3lic Pila() +
"8is1represen"a"ion ) neM CrraB;is"9G:()4
iF(H"8is10$arda) +
"8is1pos"Npila()4
"8is1invarian"()4
,
,
priva"e void pos"Npila() +
"8is10$arda ) "r$e4
asser" "8is1vacia() GG ("8is1c$en"a() )) 0) GG
("8is1represen"a"ion H) n$ll) :
J'iolaciKn de la Pos"condiciKnJ4
"8is10$arda ) False4
,
566
6 OPaB elemen"os en la pilaQ
6
6 7pos" res$l" )) (c$en"a() )) 0)
65
p$3lic 3oolean vacia() +
iF(H"8is10$arda) +
"8is1invarian"()4
,
3oolean res$l" ) "8is1c$en"a() )) 04
iF(H"8is10$arda) +
"8is1pos"Nvacia()4
"8is1invarian"()4
,

re"$rn res$l"4
,
priva"e void pos"Nvacia() +
"8is10$arda ) "r$e4
asser" "8is1c$en"a() )) 0 : J'iolaciKn de la Pos"condiciKnJ4
"8is10$arda ) False4
,

566
6 Rev$elve el elemen"o %$e es"S en la cima
6
6 7pre Hvacia()
6
65
p$3lic G cima() +
iF(H"8is10$arda) +
"8is1invarian"()4
"8is1preNcima()4
,

G res$l" )
"8is1represen"a"ion10e"("8is1represen"a"ion1siEe() - !)4
iF(H"8is10$arda) +
"8is1invarian"()4
,
re"$rn res$l"4
,
priva"e void preNcima() +
"8is10$arda ) "r$e4
asser" H"8is1vacia() : J'iolaciKn de la PrecondiciKn: J A
JTo se p$ede cons$l"ar la cima de $na pila vacaJ4
"8is10$arda ) False4
,
566
6 U$i"a el elemen"o %$e es"S en la cima
6
6 7pre Hvacia()
6 7pos" c$en"a() )) old c$en"a() - !
6
65
p$3lic void desapila() +
in" oldNc$en"a ) 04
iF(H"8is10$arda) +
"8is1invarian"()4
"8is1preNdesapila()4
oldNc$en"a ) "8is1c$en"a()4
,

"8is1represen"a"ion1remove("8is1represen"a"ion1siEe() - !)4
iF(H"8is10$arda) +
"8is1pos"Ndesapila(oldNc$en"a)4
"8is1invarian"()4
,
,
priva"e void preNdesapila() +
"8is10$arda ) "r$e4
asser" H"8is1vacia() : J'iolaciKn de la PrecondiciKn: J A
JTo se p$ede desapilar de $na pila vacaJ4
"8is10$arda ) False4
,
priva"e void pos"Ndesapila(in" oldNc$en"a) +
"8is10$arda ) "r$e4
asser" "8is1c$en"a() )) oldNc$en"a - ! :
J'iolaciKn de la Pos"condiciKnJ4
"8is10$arda ) False4
,
566
6 CVade $n elemen"o a la cima
6
6 7pos"
6 cima() )) i"em 93r:
6 Hvacia() 93r:
6 c$en"a() )) old c$en"a() A ! 93r:
6 93r:93r:
6 7pos"Priva"e
6 represen"a"ion10e"(c$en"a() - !) )) i"em 93r:
6 c8ec/NliFo(old "8is)
6
65
p$3lic void apila(G i"em) +
in" oldNc$en"a ) 04
Pila9G: oldN"8is ) n$ll4
iF(H"8is10$arda) +
"8is1invarian"()4
oldNc$en"a ) "8is1c$en"a()4
oldN"8is ) "8is1clone()4
,

"8is1represen"a"ion1add(i"em)4
iF(H"8is10$arda) +
"8is1pos"Napila(i"em, oldNc$en"a, oldN"8is)4
"8is1invarian"()4
,
,
priva"e 3oolean c8ec/NliFo(Pila9G: oldN"8is) +
Pila9G: copBN"8is ) "8is1clone()4
copBN"8is1desapila()4
re"$rn copBN"8is1e%$als(oldN"8is)4
,
priva"e void pos"Napila(G i"em, in" oldNc$en"a, Pila9G: oldN"8is) +
"8is10$arda ) "r$e4
asser" ("8is1cima() )) i"em) GG H"8is1vacia() GG
("8is1c$en"a() )) oldNc$en"a A !) GG
"8is1c8ec/NliFo(oldN"8is) :
J'iolaciKn de la Pos"condiciKnJ4
"8is10$arda ) False4
,
566
6 Rev$elve el n>mero de elemen"os %$e 8aB en la pila
65
p$3lic in" c$en"a() +
re"$rn "8is1represen"a"ion1siEe()4
,

566
6 Lompara en proF$ndidad si el o32e"o ac"$al es i0$al al o32e"o %$e
6 reci3e como parSme"ro real1
65
7=verride
p$3lic 3oolean e%$als(=32ec" o32) +
iF (o32 )) n$ll) +
re"$rn False4
,
iF (0e"Llass() H) o3210e"Llass()) +
re"$rn False4
,
Final Pila9G: o"8er ) (Pila9G:) o324
re"$rn "8is1represen"a"ion1e%$als(o"8er1represen"a"ion)4
,
566
6 Rev$elve el cKdi0o de dispersiKn del o32e"o ac"$al
65
7=verride
p$3lic in" 8as8Lode() +
in" res$l" ) !.4
res$l" ) 3! 6 res$l" A "8is1represen"a"ion18as8Lode()4
re"$rn res$l"4
,
566
6 WealiEa $na copia en proF$ndidad del o32e"o ac"$al1
65
7=verride
p$3lic Pila9G: clone() +
"rB +
BB"eCrraB=$"p$"D"ream 3o$" ) neM BB"eCrraB=$"p$"D"ream()4
=32ec"=$"p$"D"ream o$" ) neM =32ec"=$"p$"D"ream(3o$")4
o$"1Mri"e=32ec"("8is)4
o$"1close()4
BB"eCrraB<np$"D"ream 3in ) neM
BB"eCrraB<np$"D"ream(3o$"1"oBB"eCrraB())4
=32ec"<np$"D"ream in ) neM =32ec"<np$"D"ream(3in)4
Pila9G: res$l" ) (Pila9G:) in1read=32ec"()4
in1close()4
re"$rn res$l"4
,
ca"c8 (@&cep"ion e) +
re"$rn n$ll4
,
,
,
La etiqueta descripti+n se $a utiliado para $acer una descripci'n en lenguaje natural del prop'sito
general que tiene la clase. ,'lo es necesario pasar a la $erramienta Bavad+c el argumento Cta2
descripti+n para que dic$a etiqueta sea procesada por dic$a $erramienta y apareca, por tanto, en la
documentaci'n de la clase.
Las precondiciones, postcondiciones e invariante de clase se e/presan como cl!usulas introducidas
por las etiquetas pre 1precondici'n1, pos" 1postcondici'n1 e invarian" 1invariante1,
respectivamente, en la secci'n de comentarios Bavad+c de los mtodos. De nuevo, s'lo es necesario
pasar a la $erramienta Bavad+c los argumentos Cta2 pre Cta2 p+st Cta2 invariant para que las citadas
cl!usulas aparecan en la documentaci'n generada por dic$a $erramienta.
La etiqueta pre es opcional, de modo que puede $aber mtodos que no tengan precondiciones 1o
m!s precisamente, que tengan "r$e como precondici'n1. ;ambin es opcional la etiqueta pos", de
modo que puede $aber mtodos que no tengan postcondiciones: entonces estos mtodos tienen
"r$e como postcondici'n, lo que no implica ausencia de obligaciones dado que tienen que
satisfacer el invariante.
,int!cticamente, las aserciones son simplemente e/presiones l'gias escritas en Iava con unas pocas
e/tensiones.
Auando las cl!usulas aparecen en lneas separadas, se debe considerar que e/iste un and implcito
entre lneas sucesivas de cl!usulas, de modo que se facilita la identificaci'n de los componentes
individuales de una aserci'n.
:amos a analiar la clase, los detalles de implementaci'n y tambin cada una de las aserciones, qu
e/presan, c'mo lo e/presan y c'mo se relacionan con la especificaci'n del ;*D subyacente.
"mpecemos por el mtodo cima(), el cual devuelve el elemento que est! en la cima. ,u
precondici'n es:
7pre Hvacia()
que establece, como es l'gico, que el mtodo no se puede invocar a menos que la pila no est vaca,
dado que si est! vaca no e/iste la cima. "sta precondici'n se corresponde directamente con la
precondici'n siguiente de la especificaci'n del ;*D:
cima(p:Pila[G]) require vaca(p) ) (also
,igamos con el mtodo desapila(), el cual quita el elemento que est! en la cima. De forma
semejante al caso anterior, su precondici'n es:
7pre Hvacia()
que establece, como es l'gico, que el mtodo no se puede invocar a menos que la pila no est vaca,
dado que si est! vaca no $ay elemento en la cima que se pueda desapilar. "sta precondici'n se
corresponde directamente con la precondici'n siguiente de la especificaci'n del ;*D:
desapila(p:Pila[G]) require vaca(p) ) (also
La postcondici'n del mtodo desapila() es:
7pos" c$en"a() )) old c$en"a() - !
la cual presenta una notaci'n especial, old. Los mtodos la utilian para e/presar cambios8 as, en
este caso, el mtodo desapila() la utilia para e/presar los cambios de c$en"a(). La notaci'n
old e, en donde e es una e/presi'n, denota el valor de e antes de entrar en el mtodo. "n una
postcondici'n toda aparici'n de e que no est precedida por old denota el valor de esa e/presi'n al
salir del mtodo.
Dic$o esto, est! claro que esta postcondici'n no se corresponde directamente con ninguna ecuaci'n
de la especificaci'n. Hntuitivamente, su certea es evidente puesto que, si la especificaci'n de la
funci'n cuenta nos dice que apilar un nuevo elemento en una pila incrementa en uno el valor de
cuenta, parece raonable concluir que desapilar un elemento de la pila decrementar! en uno dic$o
valor. *$ora bien, -se puede demostrar que es cierta0 La respuesta es que s. :eamos c'mo.
;odo ;*D tiene propiedades que se deducen de su especificaci'n pero que no coinciden
directamente con una de las ecuaciones. 7ay dos tipos de propiedades distintas, que e/igen
demostraciones tambin distintas:
Pr+piedades ecuaci+nales: son nuevas ecuaciones que se deducen de las ecuaciones de la
especificaci'n mediante el c!lculo ecuacional, del cual ya $ablamos en su momento.
Pr+piedades inductivas: son nuevas ecuaciones que se demuestran aplicando el principio de
inducci'n estructural sobre los valores del ;*D. "s estructural el principio de inducci'n
aplicado debido a que, dado que los valores del ;*D son generados por trminos
construidos a partir de un conjunto finito de operaciones generadoras, se realia una
inducci'n sobre la estructura de dic$os trminos. "l principio de inducci'n se aplica del
modo siguiente:
*ase de la inducci4n: se demuestra la propiedad para los valores b!sicos del ;*D, que
son los generados por las operaciones generadoras constantes o por generadoras en
cuyos argumentos no figuran valores del ;*D.
Dip4tesis de inducci4n: para cada valor no b!sico, cuyo patr'n tiene como operaci'n
m!s e/terna una generadora con argumentos del ;*D, se supondr! que dic$os
argumentos satisfacen la propiedad.
Pas+ de inducci4n: para cada valor no b!sico, se demostrar! que satisface la propiedad.
:amos a demostrar que la postcondici'n es correcta demostrando que la siguiente ecuaci'n es
cierta:
Para "oda pila p:Pila[G] no vaca,
c$en"a(desapila(p)) # c$en"a(p) !
(ara ello, se aplica el principio de inducci'n estructural:
Base de la ind$cciKn Dea p # apila(crea, &)
Xna Forma de ac"$ar es compro3ar, dado el valor de p an"erior B
aplicando cSlc$lo ec$acional, %$e los dos lados de la ec$aciKn %$e
se %$iere demos"rar son e%$ivalen"es al mismo valor1 Cs:

al"$ra(desapila(p)) # al"$ra(desapila(apila(crea, &) #
al"$ra(crea) # 0
al"$ra(p) ! # al"$ra(apila(crea, &)) ! # al"$ra(crea) A ! !
# 0 A! ! # 0
PipK"esis de ind$cciKn
Dea p # apila(%, &) donde % no es vaca, se p$ede aFirmar %$e
c$en"a(desapila(%)) # c$en"a(%) !
Paso de ind$cciKn Dea p # apila(%, &)
Re n$evo, $na Forma de ac"$ar es compro3ar, dado el valor de p
an"erior B aplicando cSlc$lo ec$acional, %$e los dos lados de la
ec$aciKn %$e se %$iere demos"rar son e%$ivalen"es al mismo valor1
Cs:
al"$ra(desapila(p)) # al"$ra(desapila(apila(%, &) # al"$ra(%)
al"$ra(p) ! # al"$ra(apila(%, &)) ! # ! A al"$ra(%) ! #
al"$ra(%)
(or tanto, queda demostrada que la postcondici'n es correcta puesto que se corresponde con una
ecuaci'n deducida de la especificaci'n del ;*D mediante inducci'n.
,igamos con el mtodo vacia(), el cual informa si la pila est! vaca o no. La postcondici'n del
mtodo vacia() es:
7pos" res$l" )) (c$en"a() )) 0)
la cual presenta una notaci'n especial, res$l", que $ace referencia al resultado proporcionado por
el mtodo.
"n este caso, de nuevo nos encontramos con una postcondici'n no se corresponde directamente con
ninguna ecuaci'n de la especificaci'n. Hntuitivamente, su certea es evidente puesto que la pila est!
vaca si y s'lo si su n#mero de elementos es cero. *$ora bien, -se puede demostrar que esto es
cierto0 La respuesta de nuevo es que s. :eamos c'mo aplicando de nuevo el principio de inducci'n
estructural. :amos a demostrar que la postcondici'n es correcta demostrando que la siguiente
ecuaci'n es cierta:
Para "oda pila p:Pila[G],
vacia(p) # c$en"a(p) ) 0
Base de la ind$cciKn Dea p # crea
Xna Forma de ac"$ar es compro3ar, dado el valor de p an"erior B
aplicando cSlc$lo ec$acional, %$e los dos lados de la ec$aciKn %$e
se %$iere demos"rar son e%$ivalen"es al mismo valor1 Cs:
vacia(crea) # 'erdadero
c$en"a(crea) ) 0 # 0 ) 0 # 'erdadero
PipK"esis de ind$cciKn
Dea p # apila(%, &), se p$ede aFirmar %$e
vacia(%) # c$en"a(%) ) 0
Paso de ind$cciKn Dea p # apila(%, &)
Re n$evo, $na Forma de ac"$ar es compro3ar, dado el valor de p
an"erior B aplicando cSlc$lo ec$acional, %$e los dos lados de la
ec$aciKn %$e se %$iere demos"rar son e%$ivalen"es al mismo valor1
Cs:
vacia(p) # vacia(apila(%, &)) # (also
c$en"a(p) ) 0 # c$en"a(apila(%, &)) ) 0 # ! A c$en"a(%) ) 0 #
(also
(or tanto, queda demostrada que la postcondici'n es correcta puesto que se corresponde con una
ecuaci'n deducida de la especificaci'n del ;*D mediante inducci'n.
Las aserciones ilustran un concepto fundamental: la diferencia entre el punto de vista imperativo y
el aplicativo. Mecordemos la postcondici'n de vacia():
7pos" res$l" )) (c$en"a() )) 0)
y a$ora la instrucci'n del cuerpo del mtodo que computa el valor requerido:
3oolean res$l" ) "8is1c$en"a() )) 04
(udiera uno preguntarse cu!l es la ra'n de esta postcondici'n si en el cuerpo del mtodo se tiene
e/actamente lo mismo, con la #nica diferencia de que en ste se usa el operador de asignaci'n
mientras que en la postcondici'n se usa el operador de igualdad. -No es redundante la
postcondici'n0
Mealmente $ay una gran diferencia entre las dos construcciones y no $ay ninguna redundancia. La
instrucci'n del cuerpo del mtodo es una orden que se le da al computador virtual <la m!quina
$ard)are1soft)are= para cambiar su estado de una cierta manera y llevar a cabo una acci'n. La
aserci'n no $ace nada: especifica una propiedad del estado final esperado y que es visible al mtodo
que llama.
La instrucci'n es prescriptiva y la aserci'n es descriptiva. La instrucci'n describe el c4m+ y la
aserci'n describe el 1u:. La instrucci'n es parte de la implementaci'n8 la aserci'n es un elemento
de especificaci'n. La instrucci'n es imperativa8 la aserci'n es aplicativa.
Que esas dos notaciones sean tan parecidas no debe oscurecer su diferencia fundamental. La
aserci'n describe la intenci'n de un resultado y la instrucci'n 1el cuerpo de la rutina1 describe una
forma particular de alcanar dic$o resultado. *lguien que est usando una clase para escribir una
clase cliente estar! interesado tpicamente en la aserci'n pero no en la implementaci'n.
La ra'n de la similitud entre las notaciones de la asignaci'n y de la igualdad es que la asignaci'n
es en muc$os casos la forma elemental de lograr la igualdad. (or tanto, la presencia de los
elementos respectivos en el cuerpo y la postcondici'n no es una evidencia de redundancia, sino que
es una evidencia de la consistencia entre la implementaci'n y la especificaci'n 1es decir, de la
correcci'n tal y como fue definido este concepto anteriormente.
,igamos con el mtodo apila(), el cual a+ade un elemento a la cima de la pila. Dado que no
tiene precondici'n e/plcitamente definida, esto quiere decir que su precondici'n es "r$e, como ya
se e/plic' anteriormente.
La postcondici'n de este mtodo presenta una caracterstica especial. 7ay dos etiquetas en este
mtodo que definen la postcondici'n, la etiqueta 7pos" que ya conocemos, formada por varias
cl!usulas, y la etiqueta 7pos"Priva"e. :amos a estudiar en primer lugar esta #ltima antes de
analiar las cl!usulas de la primera.
La etiqueta 7pos"Priva"e define una postcondici'n privada, en concreto:
7pos"Priva"e
represen"a"ion10e"(c$en"a() - !) )) i"em
c8ec/NliFo(old "8is)
-Qu es una postcondici'n privada0 D!sicamente, una postcondici'n que no aparece en la
documentaci'n p#blica de la clase que se entrega a los autores de las clases clientes. Dien, $ay dos
raones posibles por las que una postcondici'n puede ser privada. "studiemos la primera de ellas.
"/iste un requisito suplementario para las precondiciones que no figura en el principio de la
precondici'n raonable: para que una precondici'n pueda ser satisfec$a por un cliente, la
precondici'n no debe utiliar caractersticas de la clase que debido a restricciones de e/portaci'n
estn ocultas a los clientes. Llegamos as a la regla de disponibilidad de la precondicin:
Toda caracterstica que aparezca en la precondicin de un mtodo debe estar disponible para
cualquier cliente para el que est disponible dic,o mtodo)
Aon esta regla todo cliente que est en situaci'n de llamar a una caracterstica tambin estar! en
posici'n de verificar su precondici'n, lo cual es l'gico: no tiene sentido incluir en la precondici'n
de un mtodo, por ejemplo, caractersticas secretas de la clase que ning#n cliente puede utiliar para
saber si est! en condiciones de invocar correctamente a dic$o mtodo.
,in embargo, no $ay una regla similar para las postcondiciones. No es un error el que algunas
cl!usulas de una cl!usula de postcondici'n se refieran a caractersticas secretas, o a caractersticas
que no se e/porten con tanta amplitud como el mtodo al que pertenecen dic$as cl!usulas8 esto
significa simplemente que se est!n e/presando propiedades del efecto del mtodo que no son
utiliables directamente por los clientes. Gste es el caso de la primera cl!usula de la postcondici'n
privada del mtodo apila() que nos ocupa:
represen"a"ion10e"(c$en"a() - !) )) i"em
"sta cl!usula indica que el elemento que se acaba de a+adir a la pila est! situado al final del
CrraB;is" represen"a"ion. ,e trata de una propiedad de implementaci'n. Las propiedades
de implementaci'n no se corresponden directamente con ecuaci'n alguna de la especificaci'n del
;*D, ni tampoco se corresponden con una ecuaci'n que sea una propiedad ecuacional o inductiva
obtenida a partir de la especificaci'n del ;*D. *s, aun cuando apila() es p#blico y por tanto se
e/porta a todo el mundo, el atributo represen"a"ion es secreto. (ero no $ay nada incorrecto
con esta postcondici'n8 se limita a a+adir, a las otras propiedades que son #tiles para los clientes y
que vienen e/presadas en la etiqueta 7pos", una que s'lo es significativa para alguien que lea el
te/to de la clase completa. ;ales cl!usulas que forman parte de postcondiciones privadas no
aparecer!n en la documentaci'n de la clase que se pone a disposici'n de los autores de las clases
cliente.
"n este punto, es conveniente remarcar algo. Aomo es l'gico y se $a e/plicado, a los
desarrolladores se les entrega #nicamente la documentaci'n de la clase que necesitan para escribir
las clases clientes, ya que no es necesario proporcionarles informaci'n e/tra que los sumerja en un
mar de detalles que para ellos son innecesarios y a la larga les pueda $acer m!s difcil su trabajo. No
obstante, la ocultaci'n de la informaci'n no versa sobre ocultar el c'digo fuente al cliente 1es decir,
al autor de las clases cliente1, sino sobre que ste no pueda escribir su c'digo bas!ndose en
caractersticas secretas, incluyendo entre ellas la representaci'n interna de la clase. (or ello, las
precondiciones deben usar siempre caractersticas p#blicas, que son visibles para el cliente, de
modo que ste pueda comprobar que se cumplen.
,in embargo, las postcondiciones 1y los invariantes, como veremos pronto1 no tienen que cumplir
este requisito: en este caso no es un error incluir caractersticas secretas porque ello no causa
problemas al cliente. "n cualquier caso, las aserciones informan al cliente qu $ace la clase pero no
le informan de los detalles de c'mo lo $ace aun cuando las postcondiciones y el invariante puedan
eventualmente mostrar caractersticas secretas. *unque el cliente pueda leer las cl!usulas de las
postcondiciones y del invariante que muestran propiedades de implementaci'n de la clase, del
mismo modo que aunque el cliente pueda leer el te/to fuente completo de la clase, no se viola la
ocultaci'n de la informaci'n porque al cliente no se le permite escribir una clase cliente bas!ndose
en esas caractersticas secretas, incluida entre ellas la representaci'n interna de la clase, por la
simple ra'n de que no puede acceder a ellas: el cliente s'lo puede acceder a las caractersticas
p#blicas para escribir el c'digo de sus clases cliente, que es al fin y al cabo el objetivo perseguido
por la ocultaci'n de la informaci'n. (or ello, una ve m!s remarcamos que ocultar las propiedades
de implementaci'n de la clase al cliente tiene como #nico objetivo no despistarle con informaci'n
innecesaria para su trabajo y as proporcionarle s'lo la informaci'n que necesita de verdad para
escribir sus clases clientes.
(or tanto, la primera ra'n posible para que una postcondici'n sea privada es que e/prese una
propiedad de implementaci'n. *$ora vamos a ver la segunda ra'n por la que una postcondici'n
puede ser privada. "sta segunda ra'n se presenta en la segunda cl!usula de la postcondici'n
privada del mtodo apila() que nos ocupa:
c8ec/NliFo(old "8is)
"sta cl!usula se corresponde con el siguiente a/ioma de la especificaci'n del ;*D:
desapila(apila(p, &)) # p
No obstante, es f!cil ver que la correspondencia en este caso no es directa, debido a que no $ay una
manera directa de e/presar mediante una aserci'n dic$o a/ioma. -(or qu0
"l lenguaje de aserciones que se $a utiliado es esencialmente el lenguaje de las e/presiones
booleanas, e/tendido con unos pocos conceptos tales como old. Aomo resultado, puede resultar
e/cesivamente restrictivo cuando se quieren incluir en las clases algunas de las propiedades que
eran f!ciles de e/presar en la notaci'n matem!tica de los tipos abstractos de datos. *$ora bien, la
limitaci'n no es tan estricta como puede parecer a simple vista, debido a que en las e/presiones
booleanas puede $aber llamadas a funciones 1naturalmente, cuando $ablamos de funciones nos
referimos a mtodos que proporcionan un resultado1. De $ec$o, lo que $ace la aserci'n de esta
#ltima cl!usula es precisamente eso: invocar a una funci'n privada que comprobar! que la pila
verifica la poltica LHJF que la caracteria, que es al fin y al cabo lo que e/presa dic$o a/ioma que
no puede e/presarse directamente mediante una aserci'n.
(or tanto, debido a una limitaci'n en el lenguaje de aserciones, se $a necesitado definir una funci'n
privada para as poder definir una aserci'n8 dado que esa funci'n privada no aporta nada al cliente,
dic$a aserci'n forma parte de una postcondici'n privada y, por tanto, no aparecer! en la
documentaci'n de la clase que se le proporcionar! al autor de las clases clientes de la nuestra. Aomo
es l'gico, si la funci'n no fuera privada, como ya $emos visto en otras aserciones, s que aparecera
la aserci'n en la documentaci'n p#blica de la clase.
Mesumiendo: tenemos dos raones distintas para $acer que una postcondici'n sea privada y que por
tanto no apareca en la documentaci'n p#blica de la clase, para as no despistar con detalles
innecesarios al autor de las clases clientes de aquella clase.
@racias a las funciones, que nos dan la posibilidad de computar un valor booleano en la forma que
se quiera, podemos e/presar conceptos que antes no nos era posible enunciar con la frrea disciplina
del c!lculo proposicional de nuestro lenguaje de aserciones. *dem!s, utiliar funciones es una
forma evidente de obtener aserciones m!s abstractas.
No obstante, $ay un riesgo: tan pronto como se permitan funciones en las aserciones, se est!n
introduciendo elementos potencialmente imperativos en el mundo puramente aplicativo de las
aserciones. (or ello, cualquier funci'n que se utilice en una aserci'n para especificar las
propiedades de un elemento soft)are debe ser imperativamente intac$able, es decir, no debe causar
ning#n cambio permanente en el estado del objeto8 por ello, como se puede ver en la
implementaci'n de la funci'n c8ec/NliFo(), se trabaja con copias idnticas en profundidad de
los objetos de modo que el objeto actual no se vea modificado de ninguna forma.
De $ec$o, la e/istencia del mtodo c8ec/NliFo() es la ra'n de que se $ayan implementado
clone() y e%$als(), y debido a que se implementa este #ltimo mtodo se $a implementado
tambien 8as8Lode(). "n concreto, clone() implementa una clonaci'n profunda utiliando
serialiaci'n, que es una tcnica lenta pero simple y efica. Aomo se $a comentado,
c8ec/NliFo() trabaja con clones para evitar modificar el objeto actual dado que nuestra clase
no es inmutable. *s, lo que $ace este mtodo es comprobar que, al desapilar un clon del objeto
actual, obtenemos un objeto que es igual al clon del objeto que e/ista antes de sufrir el apilamiento
del nuevo elemento. Lo cual como es l'gico permite verificar que la clase cumple la propiedad lifo.
7ay un asunto tcnico que puede $aber llamado la atenci'n. 9na funci'n 0 utiliada en una aserci'n
para un mtodo m 1o utiliada en el invariante de la clase que contiene a m1 puede en s misma tener
aserciones. "sto plantea un problema potencial en el control de las aserciones en tiempo de
ejecuci'n: si como parte de una llamada a m se eval#a una aserci'n y esto causa una llamada a 0, no
se quiere que la llamada eval#e ninguna aserci'n que 0 a su ve pueda tener. (or una parte, es f!cil
construir ejemplos que podran causar una recursividad infinita. (ero incluso sin este riesgo sera
incorrecto evaluar las aserciones de 0. "sto significara que se tratan como iguales los mtodos para
computar los servicios propios de la clase, tales como m, y las funciones de sus aserciones, tales
como 0 1lo que contradice la regla de que las aserciones debieran estar en un plano m!s alto que el
soft)are que protegen y que su correcci'n debe ser tan clara como el agua1. La regla entonces es
simple y se llama regla de evaluacin de aserciones:
Durante el proceso de evaluacin de una asercin en tiempo de ejecucin7 las llamadas a
mtodos deben ejecutarse sin evaluar las aserciones asociadas)
,i una llamada a 0 se produce como parte de una comprobaci'n de aserciones para m, es muy tarde
para preguntar si 0 satisface sus aserciones. "l momento adecuado para $acer esto es cuando se
decide utiliar a 0 en las aserciones aplicables a m.
,e puede utiliar una analoga. (iense en 0 como en un guarda de seguridad a la entrada de una
planta nuclear, a cargo de inspeccionar las credenciales de los visitantes. ;ambin puede $aber
requisitos sobre los guardas. (ero stos $abr! que comprobarlos con antelaci'n, no mientras estn
controlando las credenciales de los visitantes.
:olviendo al c'digo de nuestra clase, se puede ver en el te/to que cada precondici'n de un mtodo
p#blico tiene asociado un mtodo privado que verifica el cumplimiento de la precondici'n
empleando para dic$a verificaci'n la instrucci'n assert, la cual lana una e/cepci'n que detiene la
ejecuci'n del programa si la e/presi'n booleana e/aminada no es cierta. De igual modo se $ace
para cada postcondici'n de un mtodo p#blico. *dem!s, e/iste un mtodo privado que verifica que
se cumple el invariante de la clase. Aomo se puede comprobar en el c'digo, el invariante se verifica
tanto a la entrada como a la salida de cada mtodo p#blico.
;al y como $emos implementado en nuestra clase el control de aserciones en tiempo de ejecuci'n,
es muy simple $acer que se cumpla la regla de evaluaci'n de aserciones. (ara garantiar que se
cumple dic$a regla, la primera tarea que realia cada mtodo privado encargado de verificar una
aserci'n es poner a true un atributo de la clase llamado 2uarda. * continuaci'n, se verifica si se
cumple o no la aserci'n. "n dic$a verificaci'n, cualquier mtodo invocado comprueba en primer
lugar el valor del atributo 2uarda, de modo que si dic$o valor es true no verifica sus aserciones
asociadas. 9na ve que el mtodo privado $a terminado de verificar la aserci'n correspondiente,
pone a 0alse el atributo 2uarda, de modo que cuando un cliente invoque un mtodo p#blico de la
clase, ste comprobar! que 2uarda tiene valor 0alse y por tanto verificar! sus aserciones.
9na ve e/plicado el concepto de postcondici'n privada, recordemos cu!les son las cl!usulas de la
postcondici'n p#blica de apila(). La cl!usula
cima() )) i"em
se corresponde directamente con la ecuaci'n siguiente de la especificaci'n del ;*D:
cima(apila(p, &)) # &
La cl!usula
Hvacia()
se corresponde directamente con la ecuaci'n siguiente de la especificaci'n del ;*D:
vaca(apila(p, &)) # (also
La cl!usula
c$en"a() )) old c$en"a() A !
se corresponde directamente con la ecuaci'n siguiente de la especificaci'n del ;*D:
c$en"a(apila(p, &)) ) ! A c$en"a(p)
,igamos con el mtodo constructor pila(), el cual crea una pila vaca. Nos encontramos de
nuevo con que la postcondici'n de este mtodo presenta una parte p#blica y una parte privada. La
cl!usula de la postcondici'n privada es:
7pos"Priva"e represen"a"ion H) n$ll
"sta cl!usula indica que el atributo privado represen"a"ion $a sido inicialiado a un valor no
nulo. ,e trata, como corresponde a una postcondici'n privada, de una propiedad de implementaci'n
que, por tanto, no se corresponde con ecuaci'n alguna de la especificaci'n del ;*D. *nalicemos
a$ora el resto de cl!usulas de la postcondici'n, las que corresponden a la postcondici'n p#blica. La
cl!usula
vacia()
se corresponde directamente con la ecuaci'n siguiente de la especificaci'n del ;*D:
vacia(crea) # 'erdadero
2 la cl!usula
c$en"a() ) 0
se corresponde directamente con la ecuaci'n siguiente de la especificaci'n del ;*D:
c$en"a(crea) # 0
(or #ltimo, nos queda analiar el invariante de la clase. "l invariante de la clase presenta una parte
p#blica y una parte privada. La cl!usula que constituye el invariante p#blico, que es visible a los
autores de las clases clientes, es:
7invarian" c$en"a() :) 0
la cual no se corresponde directamente con ninguna ecuaci'n de la especificaci'n del ;*D.
Hntuitivamente, su certea es evidente puesto que el n#mero de elementos de la pila siempre $a de
ser mayor o igual que cero. *$ora bien, -se puede demostrar que esto es cierto0 (ues de nuevo la
respuesta es que s, aplicando otra ve el principio de inducci'n estructural. :amos a demostrar que
esta cl!usula es correcta demostrando que la siguiente ecuaci'n es cierta:
Para "oda pila p:Pila[G],
c$en"a(p) Y 0 # 'erdadero
Base de la ind$cciKn Dea p # crea
c$en"a(crea) Y 0 # 0 Y 0 # 'erdadero
PipK"esis de ind$cciKn
Dea p # apila(%, &), se p$ede aFirmar %$e
c$en"a(%) Y 0 # 'erdadero
Paso de ind$cciKn Dea p # apila(%, &)
c$en"a(p) Y 0 # c$en"a(apila(%, &)) Y 0 # ! A c$en"a(%) Y 0 #
'erdadero
(or tanto, queda demostrada que la cl!usula es correcta puesto que se corresponde con una ecuaci'n
deducida de la especificaci'n del ;*D mediante inducci'n.
*nalicemos a$ora el invariante privado, que es:
7invarian"Priva"e
c$en"a() )) represen"a"ion1siEe()
(c$en"a() : 0) implies (represen"a"ion10e"(c$en"a() - !) ))
cima())
La primera cl!usula e/presa que el n#mero de elementos apilados en la pila, que es el resultado que
devuelve el mtodo c$en"a(), se corresponde con el resultado que devuelve el mtodo siEe()
del atributo privado represen"a"ion.
La segunda cl!usula establece que el $ec$o de que el n#mero de elementos apilados en la pila sea
mayor que cero implica que el elemento que se $aya en la cima de la pila es el que est! situado al
final del atributo privado CrraB;is" represen"a"ion. "n esta segunda cl!usula, la notaci'n
implies describe la implicaci'n definida en la l'gica matem!tica8 as: a implies 3 se define
como no" a or 3.
*l igual que ocurre con las postcondiciones privadas, ciertas aserciones aparecen en el invariante de
clase aunque no se corresponden directamente con ecuaci'n alguna de la especificaci'n del ;*D, ni
tampoco se corresponden con una ecuaci'n que sea una propiedad ecuacional o inductiva obtenida a
partir de la especificaci'n del ;*D. "stas aserciones son propiedades de implementaci'n que
involucran atributos secretos que por definici'n no seran significativos en el tipo abstracto de
datos. Aomo ejemplos tenemos las dos cl!usulas anteriores del invariante privado. "l invariante
privado, al igual que las postcondiciones privadas, no aparece en la documentaci'n p#blica que se
entrega a los autores de las clases cliente.
,in embargo, lo m!s importante, y que qui! el lector ya $aya supuesto, es que el invariante de la
clase es el invariante de implementaci'n o invariante de representaci'n, del que $ablamos largo y
tendido en su momento. Las aserciones del invariante de clase sirven para e/presar la consistencia
de la representaci'n escogida en la clase en consonancia con el tipo abstracto de datos
correspondiente. *lgunas de ellas ser!n visibles al cliente y otras 1las que involucran atributos
secretos1 no lo ser!n.
*$ora es el momento de enfrentarnos en su totalidad a la pregunta %-cu!l es el efecto de las
aserciones en tiempo de ejecuci'n0&. ,i el control de aserciones en tiempo de ejecuci'n est!
activado al nivel m!s alto 1como en el c'digo fuente de nuestra clase1, no tiene efecto visible 1salvo
en los ciclos de A(9 que son necesarios para evaluarlas1 mientras las aserciones controladas tengan
el valor verdadero. (ero el que un aserci'n tome el valor falso al evaluarse es un suceso bastante
serio que normalmente conducir! a terminar la ejecuci'n. Aomo ya se $a comentado anteriormente,
en realidad se disparar! una e/cepci'n pero, a menos que se $ayan tomado medidas especiales para
capturar la e/cepci'n, todo se detendr!.
-Qu nivel de seguimiento de las aserciones se debe activar0 La respuesta es un compromiso entre
las consideraciones siguientes: cu!nto se debe confiar en la correcci'n del soft)are8 qu crucial es
obtener la m!/ima eficiencia8 qu consecuencias serias puede tener un error no detectado durante la
ejecuci'n. "n los casos e/tremos la situaci'n est! clara:
Auando se est! depurando un sistema, o m!s generalmente cuando se est! probando antes de
su distribuci'n, se debe activar el control de las aserciones al nivel m!s alto.
,i se tiene un sistema completamente fiable en un !rea de aplicaci'n en la que sea crucial la
eficiencia 1del tipo en que cada microsegundo cuenta1 se puede considerar quitar todos los
controles. "n este caso, se convertiran en comentarios todas aquellas lneas del c'digo
fuente dedicadas solamente a controlar aserciones.
"sta #ltima sugerencia es en parte parad'jica ya que no suele ser posible confiar plenamente en un
sistema salvo que se controlen sus aserciones. Gste es un caso especial de una observaci'n general
efectuada con su elocuencia caracterstica por A.*.M. 7oare:
Es absurd+ 9acer c+mpr+baci+nes elab+radas en las eBecuci+nes de depuraci4n' cuand+ nadie
c+n0a en l+s resultad+s y lue2+ 1uitarlas en las eBecuci+nes de pr+ducci4n' en las 1ue un resultad+
err4ne+ p+dra ser c+st+s+ y desastr+s+? 36u: pensaram+s de un mariner+ entusiasta 1ue se
pusiera el c9alec+ salvavidas cuand+ entrenase en tierra 0irme per+ se l+ 1uitase al 9acerse a la
mar5
9na soluci'n de compromiso interesante es verificar en tiempo de ejecuci'n #nicamente las
precondiciones. "n este caso, se convertiran en comentarios todas aquellas lneas del c'digo fuente
dedicadas solamente a controlar postcondiciones e invariantes. "n ejecuciones del soft)are en
producci'n 1es decir, pasado la depuraci'n y el control de calidad1 esto tiene la ventaja de evitar
cat!strofes que podran producirse por llamadas no detectadas a rutinas sin cumplir sus requisitos, al
tiempo que cuesta significativamente menos durante la ejecuci'n que comprobar tambin que se
verifican las postcondiciones y los invariantes.
(ara terminar, veamos c'mo queda, medianta la $erramienta Bavad+c, la documentaci'n que recibe
el autor de las clases cliente de la nuestra:
org)jomaveger)dbc
"lass %ila89:
java.lang.Object
|_ org.jomaveger.dbc.Pila<G>
public class Pila<G>
extends java.lang.Object
Aut,or1
jomaveger
Description1
(ilas: una estructura dispensadora con poltica LHJF: el #ltimo
elemento en entrar es el primero en salir. ;ienen capacidad ilimitada.
6nvariant1
cuenta<= NO 4
"onstructor +ummar-
Pila()
Area una pila vaca
;et,od +ummar-
void apila(G item)
*+ade un elemento a la cima
G cima()
Devuelve el elemento que est! en la cima
Pila<G> clone()
Mealia una copia en profundidad del objeto actual.
int cuenta()
Devuelve el n#mero de elementos que $ay en la
pila
void desapila()
Quita el elemento que est! en la cima
boolean equals(java.lang.Object obj)
Aompara en profundidad si el objeto actual es igual
al objeto que recibe como par!metro real.
int hashCode()
Devuelve el c'digo de dispersi'n del objeto actual
boolean vacia()
-7ay elementos en la pila0
;et,ods in,erited from class java)lang)<bject
finalize, getClass, notify, notifyAll, toString,
wait, wait, wait
"onstructor Detail

%ila
public Pila()
Area una pila vaca
%ost1
vacia<=
cuenta<= OO 4
;et,od Detail
vacia
public boolean vacia()
-7ay elementos en la pila0
%ost1
result OO <cuenta<= OO 4=
cima
public G cima()
Devuelve el elemento que est! en la cima
%re1
?vacia<=
desapila
public void desapila()
Quita el elemento que est! en la cima
%re1
?vacia<=
%ost1
cuenta<= OO old cuenta<= 1 6
apila
public void apila(G item)
*+ade un elemento a la cima
%ost1
cima<= OO item
?vacia<=
cuenta<= OO old cuenta<= P 6
cuenta
public int cuenta()
Devuelve el n#mero de elementos que $ay en la pila
equals
public boolean equals(java.lang.Object obj)
Aompara en profundidad si el objeto actual es igual al objeto
que recibe como par!metro real.
<verrides1
equals in class java.lang.Object
,as,"ode
public int hashCode()
Devuelve el c'digo de dispersi'n del objeto actual
<verrides1
hashCode in class java.lang.Object
clone
public Pila<G> clone()
Mealia una copia en profundidad del objeto actual.
<verrides1
clone in class java.lang.Object
Agradecimientos1
* D. Micardo (e+a Car, Aatedr!tico de Lenguajes y ,istemas Hnform!ticos de la
9niversidad Aomplutense de Cadrid, por sus encomiables paciencia y atenci'n a la $ora de
resolver mis dudas.
* D. Dertrand Ceyer, creador del lenguaje "iffel, por su generosa dedicaci'n a la $ora de
contestar mis preguntas, lo que apareci' reflejado en este documento.
/ibliografa1
C+nstrucci4n de S+0tEare Orientad+ a ObBet+s, Dertrand Ceyer, "d. (renctice 7all, BQ
"dici'n, 6RRR.
DiseF+ de Pr+2ramasG F+rmalism+ y Abstracci4n, Micardo (e+a Car, "d. (rentice 7all K
(earson "ducaci'n, SQ "dici'n, B44T
C+re Hava . ,+l? - I Fundament+s, Aay 7orstmann U @ary Aornell, "d. (rentice 7all 1
(earson "ducaci'n, 3Q "dici'n, B44T.
ObBectCOriented Pr+2rammin2 in Ei00el, (ete ;$omas U May Veedom, "d. *ddison1Vesley,
BQ "dici'n, 6RRW.
Pr+2ramaci4n met4dica, Ios Luis Dalc!ar, "d. Cc@ra)17ill, 6RRS.
Estructuras de dat+s y m:t+d+s al2+rtmic+s I EBercici+s resuelt+s, Narciso Cart Fliet U
2olanda Frtega Calln U Ios *lberto :erdejo L'pe, "d. (rentice 7all K (earson
"ducaci'n, B44S.
Desi2n by C+ntract' by E(ample, Mic$ard Citc$ell U Iim CcXim, "d. *ddison1Vesley,
B44B.
Data Structures And S+0tEare Devel+pment In An ObBectCOriented D+main I Hava Editi+n,
Iean1(aul ;remblay U @rant *. A$eston, "d. (rentice 7all, B44S
Data Structures And S+0tEare Devel+pment In An ObBectCOriented D+main I Ei00el Editi+n,
Iean1(aul ;remblay U @rant *. A$eston, "d. (rentice 7all, B446
Jos Mara Vegas Gertrudix

Das könnte Ihnen auch gefallen