Técnicas de Diseño de Programas

Por J. F. Díaz (jfdiaz98@hotmail.com)
Lic. en Ciencias de la Computación

Existen en la programación varias metodologías para el diseño de software. Algunas de ellas, como la de programación monolítica, han demostrado ser contraproducentes para el desarrollo de software a gran escala y han sido reemplazadas por nuevas propuestas, más versátiles y eficientes. Otras en cambio siguen vigentes bajo nuevas formas de expresión y filosofías de programación, tal es el caso de la programación modular y su aplicación en la Programación Orientada a Objetos.

En particular, estas dos metodologías, la monolítica y la modular, son el tema de este artículo. Al final se presentan además algunas sencillas técnicas de programación basadas en la programación modular que pueden serte de utilidad en tu aprendizaje del Arte de la Programación. ¡Que las aprovoches!

Contenido
Enfoque Monolítico o Programación No Estructurada
Programación Procedimiental
Programación Modular
Técnicas de Diseño Modular
   Método Descendente (Top-Down)
   Método Ascendente (Bottom-Up)
Otras Técnicas de Diseño
   Método de la Línea Recta
   Enfoque E-P-S
   Programación Orientada a Objetos (POO)

Enfoque Monolítico o Programación No Estructurada

Este era el método de diseño de facto en los primeros días de la programación, cuando no existían grandes adelantos en la teoría de desarrollo de software, y es la forma como se empieza a aprender a programar. Consiste en organizar secuencialmente bloques de instrucciones y llamadas a otros bloques según la lógica de solución del problema, accesando y modificando datos globales a todo el programa. Aquí, el uso de instrucciones de salto condicionales e incondicionales para llamar a ejecución a un bloque de instrucciones y su correspondiente retorno al punto de llamada era la norma. A este estilo de codificación (más bien al código resultante) se le denomina espaguetti.

Figura 1: Programación No Estructurada.
El código completo del programa opera directamente sobre datos globales.

Enfoque Monolítico

Muchos lenguajes de programación no ofrecen mecanismos para el diseño estructurado de programas y la única forma posible de desarrollo de software es haciendo uso de las instrucciones de salto (p. ej. Ensamblador, COBOL y BASIC). Por otro lado, los lenguajes modernos que proveen instrucciones de salto como herramientas alternativas o por compatibilidad con versiones previas tienen una amplia base de usuarios que continua creando código espaguetti aun cuando el lenguaje les ofrece mecanismos para la programación estructurada. En particular los usuarios del popular Visual Basic, en su mayoría ex usuarios de COBOL y Clipper, abusan de las instrucciones de salto en sus aplicaciones puesto que ese fue el modo en que aprendieron a programar, lo que incide directamente en la lectura, prueba, depuración y mantenimiento del código.

Con el advenimiento de las modernas técnicas de programación este método de programación se volvió obsoleto, y en la actualidad apenas es utilizado en la programación de drivers (manejadores de dispositivos) y chips de ROM, el llamado firmware.

Esta técnica de programación ofrece tremendas desventajas una vez que el programa se hace suficientemente grande. Por ejemplo, si la misma secuencia de instrucciones se necesita en diferentes situaciones dentro del programa, la secuencia debe ser repetida. Esto ha conducido a la idea de extraer estas secuencias, darles un nombre y ofrecer una técnica para llamarlas y regresar desde estos procedimientos.

Programación Procedimiental

Es una de las más importantes técnicas de programación jamás inventada. Es uno de lo métodos de diseño más flexibles y potentes para mejorar la productividad en la programación. Se fundamenta en una serie de descomposiciones sucesivas del problema inicial, y está inspirado en la técnica "Divide y Vencerás" que usaba el conquistador Alejandro Magno para derrotar a sus enemigos. Su utilización tiene muchos beneficios, entre los que se encuentran la facilidad en la escritura, lectura y comprensión de los programas y el permitir ahorrar espacio que de otro modo estaría ocupado por código duplicado.

Con la programación procedimental se pueden combinar las secuencias de instrucciones repetibles en un solo lugar. Una llamada de procedimiento se utiliza para invocar al procedimiento. Después de que la secuencia es procesada, el flujo de control regresa al punto de llamada para proseguir con la ejecución de la instrucción ubicada inmediatamente después de la que hizo la llamada.

Figura 2: Programación Procedimental.
El código completo del programa opera directamente sobre datos globales.

Enfoque Estructurado

Al introducir parámetros así como procedimientos de procedimientos (subprocedimientos) los programas ahora pueden ser escritos en forma más estructurada y libres de errores. Por ejemplo, si un procedimiento ya es correcto, cada vez que es usado produce resultados correctos. Por consecuencia, en caso de errores, se puede reducir la búsqueda a aquellos lugares que todavía no han sido revisados.

De este modo, un programa puede ser visto como una secuencia de llamadas a procedimientos . El programa principal es responsable de pasar los datos a las llamadas individuales y actúa como un director, los datos son procesados por los procedimientos y, una vez que el programa ha terminado, los datos resultantes son presentados. Así, el flujo de datos puede ser ilustrado como una gráfica jerárquica, un árbol, como se muestra en la Figura 3 para un programa sin subprocedimientos.

Figura 3: Programación Procedimental.
El programa principal coordina las llamadas a procedimientos y pasa los datos apropiados en forma de parámetros.

Enfoque Estructurado

Con esta metodología el programa se divide en partes independientes, cada una de las cuales ejecuta una única actividad o tarea y se codifican independientemente de los demás. Cada una de ellas se analiza, codifica y ponen a punto por separado. Siguiendo un método ascendente o descendente de desarrollo se llegará a la descomposición final del problema en módulos en forma jerárquica. Las descomposiciones resultantes reciben luego el refinamiento progresivo del repertorio de instrucciones que van a formar parte de cada pieza del programa.

Si la tarea asignada a cada procedimiento es demasiado compleja, éste deberá descomponerse en otros procedimientos más pequeños. Este proceso de subdivisión sucesiva continúa hasta que cada procedimiento tenga solamente una tarea específica que realizar. Esta tarea puede ser entrada, salida, procesamiento de datos, control de otros procedimientos o una combinación de estos.

Un procedimiento puede tranferir temporalmente el control (bifurcación) a otro. Sin embargo, cada procedimiento debe eventualmente devolver el control al procedimiento del que lo recibió. Sin embargo, los procedimientos son independientes en el sentido de que ninguno puede tener acceso directo a otro, excepto al módulo al que llama y a sus propios submódulos. No obstante, los resultados producidos por un procedimiento pueden ser utilizados por cualquier otro cuando se transfiera el control a ellos.

Dado que los procedimientos son independientes, diferentes programadores pueden trabajar simultáneamente en diferentes partes del mismo programa. Esto reducirá el tiempo de diseño del algoritmo y posterior codificación. Además un procedimiento se puede modificar radicalmente sin afectar a los demás, incluso sin alterar su función principal.

Resumiendo: se tiene ahora un programa único dividido en pequeñas piezas llamadas procedimientos que interactuan entre si, fácilmente comprensible, modificable y flexible. Para posibilitar el uso de procedimientos generales o grupos de procedimientos también en otros programas, aquéllos deben estar disponibles en forma separada. Por esa razón, la programación modular permite el agrupamiento de procedimientos dentro de módulos.

Programación Modular

La programación modular es una generalización de la programación procedimental. Aquí los procedimientos con una funcionalidad común son agrupados en módulos separados. Un programa por consiguiente, ya no consiste solamente de una sección. Ahora está dividido en varias secciones más pequeñas que interactúan a través de llamadas a procedimientos y que integran el programa en su totalidad.

Figura 4: Programación Modular.
El programa principal coordina las llamadas a procedimientos en módulos separados y pasa los datos apropiados en forma de parámetros.

Enfoque Modular

Cada módulo puede contener sus propios datos. Esto permite que cada módulo maneje un estado interno que es modificado por las llamadas a procedimientos de ese módulo. Sin embargo, solamente hay un estado por módulo y cada módulo existe cuando más una vez en todo el programa.

Técnicas de Diseño Modular

Las siguientes técnicas se derivan directamente de la Programación Modular.

Método Descendente (Top-Down)

También conocido como de arriba a abajo consiste en establecer una serie de niveles de mayor a menor complejidad que den solución al problema. Luego se crea una relación entre las etapas de la estructuración de forma que una etapa jerárquica y su inmediato inferior se relacionen mediante una interfaz claramente definida de entradas y salidas de información.

El Top-Down es muy popular por ser metodológico para la enseñanza de la programación, por favorecer la rápida creación de una estructura de diseño inicial flexible y fácil de comprender y por ser muy útil en la solución de problemas complejos.

Método Ascendente (Bottom-Up)

El diseño ascendente se refiere a la identificación de aquellos procesos que necesitan computarizarse conforme vayan apareciendo, su análisis como sistema y su codificación, o bien, la adquisición de paquetes de software para satisfacer el problema inmediato.

Cuando la programación se realiza internamente y se hace un enfoque ascendente, es difícil llegar a integrar los subsistemas al grado tal de que el desempeño global sea fluido. Los problemas de integración entre los subsistemas son sumamente costosos y muchos de ellos no se solucionan hasta que la programación alcanza la fecha límite para la integración total del sistema. En esta fecha, ya se cuenta con muy poco tiempo, presupuesto o paciencia de los usuarios, como para corregir aquellas delicadas interfaces, que en un principio, se ignoran.

Aunque cada subsistema parece ofrecer lo que se requiere, cuando se contempla al sistema como una entidad global, éste padece de ciertas limitaciones por haber tomado un enfoque ascendente. Una de ellas es la duplicación de esfuerzos para accesar el software y más aún al introducir los datos. Otro es que se introducen al sistema muchos datos carentes de valor. Un tercero y tal vez el más serio inconveniente del enfoque ascendente, es que los objetivos globales de la organización no fueron considerados y en consecuencia no se satisfacen. Sobra decir que esta técnica de diseño es la menos usada por sus múltiples inconvenientes.

Otras Técnicas de Diseño

Las siguientes técnicas de diseño pueden conjugarse con las técnicas de diseño modular antes mencionadas, tanto para el diseño de los módulos como para estructurar la rutina principal del programa.

Método de la Línea Recta

Este método es excelente para diseñar programas pequeños, programas complejos o para utilizarse como complemento a la modularización. Consiste en estructurar el flujo del programa para el caso de la solución más simple y fácil del problema, sin tomar en cuenta casos especiales, validaciones ni decisiones que provoquen bifurcaciones. De esta manera se construye un diseño inicial fácil de comprender y verificar.

Una vez completado este diseño inicial y comprobada su correctitud, se procede a agregar por pasos las rutas alternas que representan las diferentes condiciones del planteamiento, lo cual significa añadir flujos de control adicionales y se prueba iterativamente el programa con cada nueva bifurcación que se añada para asegurar que se mantiene la correctitud. Cuando todas las condiciones se han integrado al diseño, se proceden a agregar uno a uno los casos especiales que se espera maneje el programa, probando también cada nueva adición para continuar garantizando la fiabilidad de la estructura.

Por último se añaden las validaciones a los datos de entrada, las de los datos intermedios producidos a lo interno para utilizarse en la generación de los datos de salida, y los datos de salida mismos, por supuesto. Estas validaciones se integran también de manera incremental, procurando no alterar el estado del diseño alcanzado en las operaciones anteriores. Al final de todo este proceso se obtendrá un diseño final completo, confiable y seguro. Aunque el método implica tiempo y esfuerzo adicional, es muy adecuado para principiantes y para la solución de problemas complejos que requieran un diseño fino y bien organizado.

Enfoque E-P-S

Este enfoque se fundamenta en el método de diseño Top-Down. Con este enfoque el programa se divide en 3 módulos bien diferenciados: el de Entrada, el de Procesamiento y el de Salida. De ahí su nombre. Todos los módulos se desarrollan y prueban de manera independiente, lo que permite al programador concentrarse en las funciones específicas de cada uno y evitar la carga mental de pensar en la solución total del problema y la ofuscación en el diseño e implementación del programa completo.

Programación Orientada a Objetos (POO)

En contraste con las anteriores técnicas de programación, ahora tenemos una telaraña de objetos interactuantes, cada uno de los cuáles manteniendo su propio estado al interactuar con los demás mediante mensajes.

Figura 3: Programación Orientada a Objetos.
Los objetos del programa interactúan mandando mensajes unos a otros.

Enfoque Orientado a Objetos

La POO resuelve problemas importantes de la programación modular. Entre ellos tenemos los siguientes:
  • Ahora los datos no deben crearse y destruirse explícitamente, sino de manera automática
  • Los datos y las operaciones no están desacoplados, conduciendo a una estructura centrada en los datos en lugar de centrada en los procedimientos (o los algoritmos)
  • Mayor protección y seguridad de los datos y operaciones de los objetos, tanto de accesos externos como internos
Aunque aparentemente la POO parece una técnica más elegante de programación modular, no lo es. Sus características adicionales particulares a la orientación a objetos hacen de la POO una técnica novedosa de programación, aplicable a problemas y entornos específicos.-


Ir al inicio de este artículo | Versión imprimible
Ir a la Página Principal de NeoProgramadores

Lecturas Relacionadas

Métodos de Prueba de Programas

Técnicas de Prueba de Programas

Las Fases de la Programación

La Importancia de la Prueba del Software

Cómo Ser un Buen Codificador de Software


¡Mándame un mensaje!