jueves, 1 de diciembre de 2011

Desarrollo de Programas 3/3

Aquí está el último apartado del resumen de desarrollo de programas, aquí tenéis el anterior por si queréis verlo (Desarrollo de Programas 2/3)

Usar subprogramas como técnica de abstracción

Operaciones abstractas: los subprogramas constituyen un primer paso hacia la metodología de programación basada en abstracciones. Los subprogramas permiten definir operaciones abstractas. Una abstracción es una visión simplificada de una cierta entidad, de la que sólo consideramos sus elementos esenciales, prescindiendo de los detalles. Las entidades que podemos abstraer para materializarlas como subprogramas son, en general, operaciones. Con la palabra operación englobamos tanto la idea de acción como la de función.

La visión abstracta es la que permite usar dicha operación sin más que conocer que hace dicha operación. La visión detallada es la que define cómo se hace dicha operación y permite que el procesador la ejecute.

La visión abstracta es la interfaz de la operación y la visión detallada es la implementación.

En programación la idea de función surge al aplicar el concepto de abstracción a las expresiones aritméticas. Una expresión representa un nuevo valor obtenido por cálculo a partir de ciertos valores ya conocidos que se usan como operandos.

Los operandos que intervienen en el cálculo del valor de la función y que pueden cambiar de una vez a otra se especifican como argumentos de dicha función. La función aparece así como una expresión parametrizada.

La cualidad más deseable al utilizar funciones es conseguir su transparencia referencial, que significa que la función devolverá siempre el mismo resultado cada vez que se la invoque con los mismos argumentos.

La transparencia referencial se garantiza si la realización de la función no utiliza datos exteriores a ella, es decir, si no emplea variables externas al subprograma, datos procedentes del exterior, llamadas a otras funciones o procedimientos que no posean transparencia referencial.

Las funciones que cumplen la cualidad de transparencia referencial y que no producen efectos laterales o secundarios se denominan funciones puras.

Los procedimientos pueden ser considerados como acciones abstractas, igualmente parametrizadas. Como acciones abstractas, podemos tener dos visiones de un procedimiento, la primera es la visión abstrata o especificación, formada por la cabecera del procedimiento y una descripción de qué hace dicho procedimiento y la segunda es la realización, en que se detalla codificada en el lenguaje de programación elegido, cómo se hace la acción definida como procedimiento.

Podemos recomendar que los procedimientos se escriban siempre como procedimientos puros, entendiendo por ello que no produzcan efectos laterales o secundarios. Se garantiza que un procedimiento cumple con esta cualidad si en su realización no utiliza variables externas al subprograma y llamadas a otros subprogramas que no sean procedimientos o funciones puras.

Desarrollo usando abstracciones:

          Desarrollo descendente: la estrategia de desarrollo descendente, es simplemente el desarrollo por refinamientos sucesivos, teniendo en cuenta además la posibilidad de definir operaciones abstractas. En cada etapa de refinamiento de una operación habrá que optar por una de las alternativas siguientes: considerar la operación como operación terminal, considerarla como operación compleja o considerar la operación como operación abstracta.

En general resultará ventajoso refinar una operación como operación abstracta si se consigue alguna de las ventajas siguientes: mezclar operaciones con un nivel de detalle muy diferente y evitar escribir repetidamente fragmentos de código que realicen operaciones análogas.

          Reutilización: la realización de ciertas operaciones como subprogramas independientes facilita lo que se llama reutilización de software. Si la operación identificada como operación abstracta tiene un cierto sentido en sí misma, es muy posible que resulta de utilidad en otros programas.

          Desarrollo para reutilización: para aplicara de manera eficaz las técnicas de reutilización de software es preciso pensar en las posibles aplicaciones de un cierto subprograma en el momento de especificarlo, con independencia de las necesidades particulares del programa que se está desarrollando en ese momento. La principal ventaja es que se amplía el conjunto de aplicaciones en que se podrá reutilizar más adelante el subprograma que se está desarrollando ahora. Su principal inconveniente es que será más costoso hacer el desarrollo del subprograma planteado como operación de uso general, que planteando como operación particular, hecha a medida del programa que lo utiliza en este momento.

          Desarrollo ascendente: la metodología de desarrollo ascendente consiste en ir creando subprogramas que realicen operaciones significativas de utilidad para el programa que se intenta construir, hasta que finalmente sea posible escribir el programa principal, de manera relativamente sencilla, apoyándose en los subprogramas desarrollados hasta ese momento. En este caso se trata de que la identificación de las operaciones no surja de un proceso de descomposición o refinamiento de alguna acción en particular, sino simplemente pensando en el programa que se desarrolla, casi como una más de las posibles aplicaciones futuras.

Programas robustos:

Un programa se dice que es un programa robusto si su operación se mantiene en condiciones controladas aunque se le suministren datos erróneos.

          Programación a la defensiva: la postura más cómoda desde el punto de vista del programador es declinar toda responsabilidad  en el caso de que los datos no sean válidos. Si los datos de entrada con cumplen con los requisitos previstos, el programa puede entonces hacer cualquier cosa. La llamada programación a la defensiva consiste en que cada programa o subprograma esté escrito de manera que desconfíe sistemáticamente de los datos o argumentos con que se le invoca, y devuelva siempre como resultado el resultado correcto o una indicación precisa de error.

          Tratamiento de excepciones: ante la posibilidad de errores en los datos con que se opera hay que considerar dos actividades diferentes: detección de la situación de error y corrección de la situación de error. Existen varios esquemas de programación posibles para tratamiento de errores. Un modelo recomendado es el modelo de terminación. En este modelo, si se detecta un error en una sección o bloque del programa, la acción de tratamiento del error reemplaza al resto de las acciones pendientes de dicha sección, con lo cual tras la acción correctora se da por terminado el bloque. La sentencia throw provoca la terminación del subprograma de manera semejante a una sentencia return. Sin embargo, ambas terminaciones son distintas: con return se realiza una terminación normal y con throw se realiza una terminación por excepción. La sentencia throw puede devolver cualquier tipo de resultado en excepción. Además, la sentencia throw es la encargada de indicar que se ha detectado una situación de error y lanzar el mecanismo de tratamiento de excepciones. La sentencia try agrupa el bloque de código en el que se programa el algoritmo del problema a resolver sin tener en cuenta las posibles excepciones que se pudieran producir. A continuación, la sentencia catch agrupa el código para el tratamiento de la excepción que se declara entre paréntesis.

No hay comentarios:

Publicar un comentario