PDF de programación - Clase 10. Análisis dinámico, 1ª parte

Imágen de pdf Clase 10. Análisis dinámico, 1ª parte

Clase 10. Análisis dinámico, 1ª partegráfica de visualizaciones

Publicado el 6 de Septiembre del 2017
385 visualizaciones desde el 6 de Septiembre del 2017
141,7 KB
4 paginas
Creado hace 20a (12/12/2003)
Clase 10. Análisis dinámico, 1ª parte

La mejor forma de garantizar la calidad del software que desarrolla es proyectarlo cuidadosamente desde el
principio. Las partes encajarán mejor y la funcionalidad de cada parte será más sencilla, de modo que
cometerá menos errores en la implementación. Sin embargo, es difícil que no se nos escape algún error
durante la codificación y la forma más eficaz de hallarlos es mediante técnicas dinámicas: es decir, aquellas
que suponen la ejecución del programa y la observación de su rendimiento. En contraste, las técnicas estáticas
son las que se utilizan para garantizar la calidad antes de la ejecución: evaluando el diseño y el análisis del
código (bien manualmente, o bien utilizando herramientas como un verificador de tipos).
Algunos individuos, erróneamente, confían en las técnicas dinámicas, sin apenas detenerse en la fase de
especificación y proyecto, confiando en que podrán arreglar las cosas más tarde. Este modo de actuar conlleva
dos problemas. El primero es que los problemas que surgen en la fase del proyecto, con el tiempo, se mezclan
con los problemas de implementación, con lo que es más difícil encontrarlos. El segundo es que el coste de
arreglar un problema aumenta de manera espectacular cuanto más tarde se descubre dentro del proceso de
desarrollo. En estudios recientes realizados en IBM y TRW, Barry Boehm descubrió que arreglar un error de
especificación puede llegar a costar 1.000 veces más si no se descubre hasta la fase de implementación.
Otros también se equivocan al pensar que sólo son necesarias las técnicas estáticas. Aunque se han realizado
grandes progresos tecnológicos en el análisis estático, aún estamos lejos de descubrir todos los errores con
esta técnica. Aunque disponga de pruebas matemáticas de que su programa es correcto, sería una tontería no
probarlo.
El problema fundamental que existe en la fase de prueba se expresa con un famoso aforismo de Dijkstra:

Las pruebas pueden revelar la presencia de errores pero nunca su ausencia.

La fase de prueba es, por su propia naturaleza, incompleta. Sea cauteloso a la hora de sacar conclusiones de
un programa sólo porque haya superado una gran cantidad de pruebas. De hecho, el problema de determinar
cuándo un programa informático es suficientemente fiable para que se entregue es uno de los dolores de
cabeza de los responsables de gestión, para el que además existen pocos remedios. Por tanto, es mejor
entender la fase de prueba no como un modo de tener la seguridad de que el programa es correcto, sino más
bien como fórmula para hallar errores. La diferencia entre estos dos puntos de vista es sutil pero muy
importante.



10.1 Programación defensiva
Se trata de un método para incrementar la fiabilidad de un programa mediante la inserción de comprobaciones
redundantes. Funciona de la siguiente forma: cuando escribe algún código, se imagina condiciones que deben
ser validadas y mantenidas en determinados puntos del código; en otras palabras, invariantes. Entonces, en
lugar de simplemente asumir que estas invariantes se mantienen, se someten a prueba explícitamente. Estas
pruebas se denominan certificaciones en tiempo de ejecución. Si una certificación falla –esto es, el invariante
no es validado– se informa del error y se abandona la ejecución.

10.1.1 Directrices
¿Cómo utilizar las certificaciones en tiempo de ejecución? En primer lugar, no deben utilizarse como parches
de una mala codificación. A usted le interesa que el código esté libre de errores (bugs) de la manera más
efectiva. La programación defensiva no significa escribir un código rematadamente malo y luego salpicarlo
con certificaciones. Quizá ahora no lo sepa, pero a la larga descubrirá que es menos trabajo escribir un buen
código desde el principio; a menudo, el código mal escrito supone tanto desorden que no se puede arreglar sin
empezar todo desde el principio.
¿Cuándo es aconsejable emplear las certificaciones en tiempo de ejecución? A medida que escribe el código,

no posteriormente. De cualquier modo, cuando escribe el código ya tiene invariantes en mente y escribirlos es
una buena forma de documentación. Si lo pospone, tiene menos probabilidades de hacerlo.
Las certificaciones en tiempo de ejecución tienen un coste. Pueden desordenar el código, por lo que debe
utilizarlas con sabiduría. Desde luego, lo que usted quiere es escribir las certificaciones que tengan más
probabilidad de detectar fallos. Los buenos programadores las utilizan tal y como se explica a continuación:


• Al inicio de un procedimiento, para comprobar que el estado del mismo es el adecuado –esto es, para

verificar la precondición. Esto es sensato, ya que una gran proporción de errores tienen que ver con
una mala compresión de interfaces entre procedimientos.

• Al final de un procedimiento complicado, para comprobar que el resultado es plausible –esto es, para
verificar la poscondición. En un proceso que calcula raíces cuadradas, por ejemplo, tal vez podría
escribir una certificación que calcula el cuadrado del resultado para comprobar que es
(aproximadamente) igual al argumento. Este tipo de certificación se denomina a veces
autocomprobación.

• Cuando se va a realizar una operación que conlleva efectos externos. Por ejemplo, en una máquina
para radioterapia, sería razonable, antes de encenderla, comprobar que la intensidad del rayo está
dentro de los límites adecuados.


Las certificaciones en tiempo de ejecución también pueden disminuir el rendimiento de la ejecución. Los
programadores novatos se preocupan más de lo necesario por esta causa. La práctica de escribir
certificaciones en tiempo de ejecución para probar el código y después deshabilitarlas para el lanzamiento de
la versión oficial es como quitar los asientos de seguridad en un vehículo una vez que ha superado las pruebas
de seguridad. Una buena regla de oro es que si considera que una certificación es necesaria, sólo debería
preocuparse por el coste de ejecución cuando tenga pruebas de que es realmente importante.
No obstante, no tiene sentido escribir certificaciones ridículamente caras. Supongamos, por ejemplo, que se le
da un array y un índice en el cual se ha insertado un elemento. Sería razonable comprobar que el elemento se
encuentra ahí. Pero no lo sería verificar que no está en otro lugar, buscando por todo el array de principio a
fin: eso convertiría una operación que puede ejecutarse en tiempo constante en una que se necesita tiempo
lineal (sobre el tamaño del array) para ser completada.

10.1.2 Interceptación de excepciones comunes
Como Java es un lenguaje seguro, su entorno de ejecución –máquina virtual de Java (JVM)– ya incluye
certificaciones en tiempo de ejecución para varias clases de errores importantes:

• Llamada de método en una referencia nula;
• Acceso a un array más allá de sus límites;
• Realización de una operación no válida de downcast.


Estos errores hacen que las excepciones no comprobadas sean lanzadas. Es más, las propias clases de las API
de Java lanzan excepciones en condiciones de error.
Es una buena práctica interceptar todas estas excepciones. Un modo sencillo de hacerlo es incluir un gestor en
la parte superior del programa, el método main, que finaliza el programa como es debido (por ejemplo, con un
mensaje de error dirigido al usuario intentando, a continuación, cerrar todos los archivos abiertos).
Observe que la JVM lanza algunas excepciones que no es aconsejable gestionar. Los errores de
desbordamiento por acumulación o de falta de memoria (stack overflows y out-of-memory), por ejemplo,
indican que el programa se ha quedado sin recursos. En estas circunstancias, no tiene sentido empeorar las
cosas intentando continuar la computación.

10.1.3 Comprobación del invariante Rep
Una estrategia muy útil para hallar errores en un tipo abstracto con representación compleja es codificar el
invariante Rep como una certificación en tiempo de ejecución. La mejor forma de hacerlo es escribir un
método


public void checkRep ()

que lanza una excepción no comprobada si el invariante no es válido en el momento de la llamada. Este
método se puede insertar en el código de tipo abstracto, o puede ser llamado a partir de una parte del código
externo dedicada a la verificación de los invariantes.


Verificar el invariante Rep es mucho más efectivo que comprobar la mayor parte de los otros invariantes,
porque una representación quebrada muchas veces resulta en un problema que sólo se percibe mucho después
de que la representación haya sido violada. Con el método checkRep, es probable que identifique e intercepte
el error muy próximo a su fuente. Es una buena idea invocar checkRep al inicio y al final de cada método, en
el caso de que exista una exposición de representación que cause la violación de la representación entre las
llamadas de los métodos. No olvide instrumentar, con checkRep, los métodos de tipo observadores, ya que
pueden alterar la representación (como efecto colateral benevolente).

Aunque hay mucho material sobre certificaciones en tiempo de ejecución, es curioso comprobar como, al
parecer, se conoce muy poco acerca de cómo utilizar el método repCheck en el sector.

Por lo general, la comprobación del invariante Rep será excesivamente costosa comparada con el tipo de
certificación en tiempo de ejecución que se debería dejar en el código de producción. Por lo tanto, más vale
que utilice checkRep principalmente en la fase de prueba. Para comprobaciones del código de producción,
debe tener en cuenta en qué puntos es posible que falle el código a consecuencia de la violación de un
invariante de repres
  • Links de descarga
http://lwp-l.com/pdf6807

Comentarios de: Clase 10. Análisis dinámico, 1ª parte (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad