(Este artículo forma parte del Curso de Programación en C)
Los programas de ordenador son productos realmente complejos (y caros) de diseñar y construir. Al principio, con los primeros ordenadores de la historia, esto no era así. Aquellos ordenadores eran tan elementales que sus programas no podían ser demasiado complicados, y podían ser desarrollados por cualquiera con algunos conocimientos del funcionamiento del ordenador.
Pero, a lo largo de los años 70, el avance de la tecnología provocó que los ordenadores tuvieran cada vez más capacidad de cálculo y, por lo tanto, que los programas fueran cada vez más complejos. Llegó un momento en el que se hizo evidente que ningún ser humano era capaz de hacer un programa tan complejo que aprovechase todas las posibilidades de hardware de los ordenadores de esa época. A esto se le llamó la crisis del software, y estancó la industria informática durante varios años.
El problema era que, hasta entonces, se programaba sin método ni planificación. A nadie se le ocurriría, por ejemplo, construir un avión sin haber hecho antes, cuidadosamente, multitud de cálculos, estudios, planos, diseños, esquemas, etc. Pues bien, un programa de ordenador puede ser tan complejo, o más, que un avión o cualquier otro artefacto industrial, y, por lo tanto, es necesario construirlo con los mismos procesos de ingeniería.
Surgió así el concepto de ingeniería del software. No me gustan las definiciones, pero a veces son inevitables. Ahí va una:
La ingeniería del software es el conjunto de procedimientos y técnicas encaminadas a diseñar y desarrollar – con economía, prontitud, elegancia y cumpliendo los estándares de calidad – programas informáticos, documentación y procedimientos operativos mediante los cuales los ordenadores puedan ser útiles al ser humano.
Actualmente, los procesos de la ingeniería del software (que son muchos y variados) se aplican en todas las empresas y organismos en los que se desarrolla software de forma profesional y rigurosa, porque no hay otro modo de asegurar que el producto se va a terminar dentro de los plazos y costes previstos, y que éste va a funcionar correctamente y se va a ajustar a los niveles de calidad que el mercado exige.
El ciclo de vida clásico
Una de las primeras enseñanzas de la ingeniería del software fue que, al ser el proceso de producción de software tan complicado, debía descomponerse en varias etapas para poder abordarlo.
El conjunto de estas etapas, o fases, junto con las reglas para pasar de una a otra, constituyen lo que se denomina el ciclo de vida del software.
Dependiendo de diversos factores (como el tipo de software que se va a desarrollar, el sistema en el que va a funcionar, o las propias preferencias de los ingenieros o de la empresa desarrolladora), se puede elegir entre varios tipos de ciclos de vida que han demostrado su eficacia a lo largo de los años. Pero la mayoría de ellos, con ligeras variaciones, constan de las siguiente fases:
- Análisis del problema
- Diseño de una solución
- Especificación de los módulos
- Codificación
- Pruebas
- Mantenimiento
Análisis del problema
La fase de análisis consiste en averiguar QUÉ problema vamos a resolver. Parece una obviedad, pero la experiencia demuestra que no sólo no es así, sino que el análisis suele ser la etapa que más problemas causa y a la que más tiempo se le debería dedicar.
Es imprescindible partir de una especificación de requisitos lo más exacta y detallada posible. El resultado debe ser un modelo preciso del entorno del problema, de los datos y del objetivo que se pretende alcanzar. Pero expliquémoslo todo con más detenimiento:
El mundo real, por definición, es muy complejo. Cuando pretendemos traspasar una parte de ese mundo a un ordenador es necesario extraer sólo los aspectos esenciales del problema, es decir, lo que realmente afecta a esa parte del mundo, desechando todo lo demás. El proceso de comprensión y simplificación del mundo real se denomina análisis del problema, y la simplificación obtenida como resultado del análisis se llama modelo.
Por ejemplo, si lo que prentedemos es realizar un programa que calcule la trayectoria de un proyectil lanzado por un cañón de artillería (el clásico problema del tiro oblicuo, ¿recuerdan sus clases de física?), lo lógico es que simplifiquemos el problema suponiendo que el proyectil es lanzado en el vacío (por lo que no hay resistencia del aire) y que la fuerza de la gravedad es constante. El resultado será muy aproximado al real, aunque no exacto. Esto es así porque nos hemos quedado con los aspectos esenciales del problema (la masa del proyectil, su velocidad, etc), desechando los menos importantes (la resistencia del aire, la variación de la gravedad). Es decir, hemos realizado un modelo del mundo real.
En este ejemplo, el modelo del tiro oblícuo es muy fácil de construir ya que se basa en fórmulas matemáticas perfectamente conocidas. Necesitamos conocer algunos datos previos para que el modelo funcione: la velocidad del proyectil, su masa y su ángulo de salida. Con eso, nuestro programa podría calcular fácilmente la altura y la distancia que el proyectil alcanzará. Sin embargo, las áreas de aplicación de la Informática van más allá de la Física, por lo que la modelización suele ser bastante más difícil de hacer que en este problema.
Por ejemplo, en el programa de facturación de una empresa: ¿qué datos previos necesitamos conocer? ¿Qué fórmulas o cáculos matemáticos debemos realizar con ellos? ¿Qué resultado se espera del programa? Estas cuestiones deben quedar muy claras antes de la modelización porque, de lo contrario, el modelo no será adecuado para resolver el problema y todo el proceso de programación posterior dará como fruto un programa que no funciona o no hace lo que se esperaba de él.
Para que el modelo sea acertado, por lo tanto, es necesario tener muy clara la naturaleza del problema y de los datos que le afectan. A este respecto, es imprescindible establecer lo que se denomina una especificación de requisitos, que no es más que una definición lo más exacta posible del problema y su entorno. Sin una especificación detallada, es imposible comprender adecuadamente el problema y, por lo tanto, también es imposible hacer bien el análisis y construir un modelo que sea válido.
Diseño de soluciones
Una vez establecido el modelo del mundo real, y suponiendo que el problema sea computable, es necesario decidir CÓMO se va a resolver el problema, es decir, crear una estructura de hardware y software que lo resuelva.
Diseñar una solución para un modelo no es una tarea sencilla y sólo se aprende a hacerlo con la práctica. Típicamente, el diseño se resuelve mediante la técnica del diseño descendente (top-down), que consiste en dividir el problema en subproblemas más simples, y estos a su vez en otros más simples, y así sucesivamente hasta llegar a problemas lo bastante sencillos como para ser resueltos con facilidad.
Especificación y codificación de módulos
Para cada subproblema planteado en el diseño hay que inventarse una solución lo más eficiente posible, es decir, crear un algoritmo. Cada algoritmo que resuelve un subproblema se llama módulo.
Posteriormente, cada módulo debe ser traducido a un lenguaje comprensible por el ordenador, tecleado y almacenado. Estos lenguajes se llaman lenguajes de programación.
Los lenguajes de programación son conjuntos de símbolos y de reglas sintácticas especialmente diseñados para transmitir órdenes al ordenador. Existen multitud de lenguajes para hacer esto: C/C++, Pascal, Cobol, Fortran, Visual Basic, Java, PHP, etc.
Pruebas
Una vez que el programa está introducido en la memoria del ordenador, es necesario depurar posibles errores. La experiencia demuestra que hasta el programa más sencillo contiene errores y, por lo tanto, este es un paso de vital importancia.
Los errores más frecuentes son los sintácticos o de escritura, por habernos equivocado durante la codificación. Para corregirlos, basta con localizar el error (que generalmente nos marcará el propio ordenador) y subsanarlo.
Más peliagudos son los errores de análisis o diseño. Un error en fases tan tempranas dará lugar a un programa que, aunque corre en la máquina, no hace lo que se esperaba de él y, por lo tanto, no funciona. Estos errores obligan a revisar el análisis y el diseño y, en consecuencia, a rehacer todo el trabajo de especificación, codificación y pruebas. La mejor forma de evitarlos es realizar un análisis y un diseño concienzudos antes de lanzarnos a teclear código como posesos.
Existen varias técnicas, relacionadas con los controles de calidad, para generar software libre de errores y diseñar baterías de prueba que revisen los programas hasta el límite de lo posible, pero que quede claro: ningún programa complejo está libre de errores al 100% por más esfuerzos que se hayan invertido en ello.
Mantenimiento
Cuando el programa está en uso, y sobre todo si se trata de software comercial, suele ser preciso realizar un mantenimiento. El mantenimiento puede ser de varios tipos: correctivo (para enmendar errores que no se hubieran detectado en la fase de pruebas), perfectivo (para mejorar el rendimiento o añadir más funciones) o adaptativo (para adaptar el programa a otros entornos).
El coste de la fase de mantenimiento ha experimentado un fuerte incremento en los últimos años. Así, se estima que la mayoría de las empresas de software que dedican alrededor del 60% de sus recursos exclusivamente a mantener el software que ya tienen funcionando, empleando el 40% restante en otras tareas, entre las que se incluye el desarrollo de programas nuevos. Esto es una consecuencia lógica del elevado coste de desarrollo del software.
¿Y cuál es el papel del programador en todo esto?
La figura del programador artesanal que, poseído por una idea feliz repentina se lanza a teclear como un poseso y, tras algunas horas de pura inspiración, consigue componer un programa para acceder, digamos, a las bases de datos de la CIA, es, digámoslo claro, pura fantasía romántica. El programador de ordenadores es una pieza más, junto con los analistas, diseñadores, jefes de proyecto, usuarios, etc., del complejo engranaje de la ingeniería del software.
Como es lógico, toda la maquinaria de esta ingeniería es excesiva si lo que pretendemos es realizar programas pequeños y sencillos, del mismo modo que no tomamos un avión para ir a comprar el pan a la esquina.
El programador, pues, debe estar capacitado para elaborar programas relativamente sencillos basándose en las especificaciones de los analistas y diseñadores. Esto no quiere decir que un programador no pueda ser, a la vez, analista, diseñador o implantador. En realidad, a menudo ejerce varias de estas funciones, dependiendo de su experiencia y capacidad y de la organización de la empresa en la que trabaje.
Últimos comentarios