Cómo se fabrica el Software

¿Qué es el Software?¿Cómo funciona?¿Cómo se produce? En este artículo encontrará, tal vez no la respuesta, pero sí una primera aproximación a esas cuestiones.




Armando Acosta  (01-06-2003)

Cuando digo "software" me refiero al componente incorpóreo de la computadora, aquello que no se puede ver ni tocar, que no es "hardware"; en tal caso tendríamos bajo esa denominación a las "aplicaciones" (como Microsoft Word) y también a los "datos" (documentos, imagenes, sonidos etc), pero en realidad el término "software" se refiere solamente a lo primero, o sea, a los programas ejecutables, los cuales realizan la acción sobre los datos.

En términos generales, un programa no es más que un conjunto detallado de instrucciones que el CPU (Unidad Central de Procesamiento) de la computadora ejecuta en un determinado orden. Esa lista de instrucciones está contenida en un fichero que se dice "ejecutable", normalmente con extensión COM, EXE, SYS ó DLL, y codificada de forma que el CPU pueda entender directamente. Este tipo de codificación se llama "código nativo" ó "código de máquina".

En los años 50s, los programadores escribían sus programas directamente en código de máquina; es una tarea difícil, tediosa y que consume mucho tiempo, pues estos codigos de máquina son en realidad números, de modo que un programa viene a ser en realidad una lista de numeros cuyo significado es difícil de captar a simple vista. La solución a este problema fue la invensión de los lenguajes de programación.

Lenguajes de programación

El lenguaje de programación más simple es el "Ensamblador". A cada instrucción de máquina se le asocia un "mnemotécnico", es decir una especie de abreviatura de la instrucción que representa, por ejemplo SUM para una instrucción que suma dos numeros. El programador escribe su programa usando estos mnemotécnicos de modo que al final su programa tiene la forma de una lista que puede ser leida y comprendida por él mismo a simple vista. Esta lista es luego traducida a código de máquina usando un programa especial que recibe el nombre de "ensamblador".

Esto resuelve parte del problema, pero está muy lejos de ser la solución definitiva. Y es que las instrucciones que el CPU puede ejectuar son de muy bajo nivel, como sumar, restar, dividir y multiplicar dos numeros binarios, o mover valores binarios de un lugar a otro de la memoria. Para completar tareas más complejas como escribir un carácter en la pantalla del monitor o producir un sonido, se necesitan largas secuencias de instrucciones de máquina. Aún usando lenguaje ensamblador para escribir esos programas, la lista definitiva resulta demaciado intrincada y difícil de comprender por un humano. La solución a este problema fue la invensión de los llamados "lenguajes de alto nivel" o "superlenguajes".

Ejemplos de superlenguajes son PL/1, ALGOR, FORTRAN, COBOL, BASIC, PASCAL, C, C++, Java, Visual Basic, Delphi y un largo etc. - El gran aporte de estos lenguajes consiste basicamente en dos aspectos: (1) Cada instrucción se traduce en un gran numero de instrucciones de máquina. (2) Las instrucciones del lenguaje son "abstractas" en el sentido de que no están diseñadas para un CPU específico, sino que un mismo programa puede funcionar en computadoras con CPUs muy diferentes.

Por ejemplo, la siguiente instrucción en C:

       printf("Hello World");

provocará que el mensaje "Hello World" se escriba en la pantalla del monitor. Para lograr esto, el CPU tuvo que leer y ejecutar un gran numero de instrucciones en código de máquina, de modo que, en efecto, el uso de un lenguaje de alto nivel como C, representa un alto nivel de abstracción a la hora de programar.

Un programa escrito en superlenguaje tiene la forma de una lista mucho mejor estructurada, mucho más lejible y compresible por un ser humano, más orientada al problema concreto que se está resolviendo y mucho más abstracta, separada del hardware. El programador no piensa en términos del CPU sino en términos del sistema operativo, se programa para un sistema operativo determinado, y muchas veces hasta para varios (es lo que se llama "portabilidad del código", o sea, la habilidad que tiene un mismo programa de funcionar en más de un sistema operativo).

Pero una lista así no puede ser comprendida directamente por el CPU, sino que ha de ser traducida a lenguaje nativo, o como se dice en el argot informático, "compilada". Para ello se usa un programa especial llamado "compilador". La lista que el programador escribe directamente en superlenguaje se llama "código fuente" y normalmente recide en un fichero texto con una extensión que es alegórica al lenguaje en que está escrita, por ejemplo C para lenguaje C, PAS para lenguaje PASCAL, BAS para lenguaje BASIC, etc. Una vez compilado el programa fuente, se obtiene un fichero ejecutable con extensión COM, EXE etc, según sea el caso. Este último ya contiene las correspondientes instrucciones de máquina y puede ser ejectuado directamente por el CPU.

La historia del desarrollo de los superlenguajes se remonta a los finales de los 50s, y aún continúa en nuestros dias. A lo largo de tan extenso período, los lenguajes de programación han sufrido cambios profundos. Los primeros, como FORTRAN y PL/1, aunque más abstractos que sus predecedores los ensambladores, conservaban una estructura lineal, los programas seguían siendo una lista de instrucciones inamobibles, aunque de más alto nivel.

El segundo paso fue la llamada "programación estructurada", donde C y Pascal fueron los definitivos triunfadores. Este tipo de programación permite al programador crear sus propias instrucciones (que en realidad se llaman "funciones" y/o "procedimientos"), con lo cual se gana un nivel más de abstacción a la hora de programar. Asi mismo, el código fuente no tiene por qué recidir en un solo fichero sino que un proyecto extenso puede distribuirse en varios ficheros; la ventaja no es solo una mejor organización del proyecto sino además (y sobre todo) una mejor "reusabilidad" del código: aquellos módulos que han sido suficientemente depurados de errores, se compilan por separado no hacia código de máquina sino hacia un código intermedio llamado "código objeto", normalmente en ficheros con extensión OBJ. Al final, todos los ficheros OBJ se enlazan usando un programa especial llamado "linker" para conformar el fichero ejectutable definitivo. También se puden agrupar varios OBJs dentro de un solo fichero para formar lo que se llama una "librería" (normalmente con extension LIB) que también puede ser enlazada con otros OBJs para formar el ejecutable definitivo. Todos estos avances surgieron durante el desarrollo de la programación estructurada.

El siguiente paso fue la llamada "programación orientada o objeto" (OOP), con lenguajes como C++ y Java. Estos lenguajes permiten al programador crear estructuras llamadas "objetos" donde los datos se mezclan con las instrucciones que actuan sobre ellos, conformando así un ente armónico de fácil manejo en el resto del programa; también se permite la cobinación (herencia) de objetos para formar objetos más complejos. La meta de este tipo de programación es modelar los problemas de una forma más cercana a la naturaleza real de los problemas mismos; por ejemplo, en la práctica observamos que efectivamente existen objetos como mamíferos, que tienen determinadas propiedades y actitudes, y observamos otros objetos más específicos como perros y gatos, ambos mamíferos, pero diferentes entre sí.

Con el surgimiento de sistemas operativos gráficos como Windows, la programación tropezó con una gran dificultad: la comunicación con el usuario dejó de ser tan simple como recibir caracteres desde el teclado e imprimir caracteres alfanuméricos en la pantalla; ahora el usuario necesita una comunicación gráfica y para esto se requiere un gran esfuerzo de programación. La solución fue la llamada "programación visual", un concepto introducido por Visual Basic y que ahora es prácticamente obligatorio para cualquier lenguaje de programación orientado a sistemas operativos gráficos como Windows o Mac/OS. Ejemplos de estos nuevos lenguajes son Visual Basic, Visual C++, Visual Fox Pro y Delphi, casi siempre versiones "visuales" de lenguajes anteriores (Delphi es una versión visual y orientada a objeto de PASCAL).

En este nuevo tipo de programación, el programa deja de ser una lista de instrucciones, estructuras ú objetos... simplemente deja de ser una lista. Ahora es más bien un conjunto de pequeñas listas, una por cada "evento" que pueda ocurrir. Estos eventos pueden ser acciones del usuario con el mouse, entradas de caracteres del teclado, entrada de datos desde un puerto USB, etc. El programa simplemente espera a que algo ocurra, y para cada cosa que ocurra, hay un segmento de programa que se ejectuará como respuesta a ese evento. El otro gran aporte de la programación visual es el uso de editores gráficos como parte de la herramienta de programación: el programador no tiene que escribir la larga lista de instrucciones necesarias para dibujar un elemento gráfico, sino que la dibuja directamente utilizando el editor gráfico; el compilador se encarga de hacer la traducción correspondiente directamente desde el editor.

Más allá de los lenjuajes de programación

Una aplicación típica de nuestros dias, opera en un entorno multi-usuario a través de una red y contempla el acceso a una base de datos.

Hasta principios de los 90's, las herramientas de programación más populares para escribir sistemas de bases de datos eran dBASE, Clipper y Fox Pro, sistemas estos que incluían sus propios lenguajes de programación como parte de su infraestructura. Un sistema creado, por ejemplo con Clipper, tenía la forma de un fichero ejecutable (con extension EXE) y un conjunto de ficheros con extension DBF donde recidían los datos. El programa ejecutable se encargaba de toda la funcionalidad del sistema, desde la comunicación con el usuario, hasta la manipulación de los ficheros DBF.

Los ficheros DBF se colocaban normalmente en un servidor de ficheros, mientras que los ejectutables eran copiados en cada máquina cliente. El hecho de que los ficheros DBF fueran manipulados directamente por los ejecutables desde las máquinas clientes, generaba un intenso tráfico en la red, disminuyendo notablemente el rendimiento del sistema a medida que el número de usuarios crecía.

La solución a este problema fue la adopción de una arquitectura Cliente/Servidor. En el lado servidor se coloca, no solo los ficheros que contienen los datos, sino el programa que los manipula directamente. Del lado cliente, se coloca el programa que interactúa con el usuario. Ambos programas se comunican a través de la red, pero ahora el tráfico es mucho menos intenso, pues solo hay que transmitir comandos de alto nivel; por ejemplo, si un usuario ordena poner la fecha de hoy en cuatro mil records, eso constituye una simple orden que es enviada a través de la red desde el programa cliente hasta el programa servidor; este último (que recide en la misma máquina donde están los ficheros de datos) se encarga de actualizar todos los records uno por uno, sin que ello acarrée tráfico adicional a través de la red.

La introducción de esta arquitectura condujo a estandarizar la comunicación entre el programa servidor y el programa cliente, surgiendo así un "lenguaje de interrogación de bases de datos" llamado SQL (Structured Query Language, ó Lenguaje Estructurado de Interrogación de baseses de datos). También surgieron sistemas comernciales de bases de datos muy sofisticados como DB2, Oracle y Microsoft SQL Server, que se instalan en el lado del servidor y pueden comunicarse con cualquier programa cliente que esté diseñado para entender el lenguaje SQL.

Esto dá tremenda flexibilidad a los programadores de sistema de bases de datos. Por una parte no tendrán que lidiar con los detalles de la manipulación directa de los ficheros de datos, y por otra parte, pueden escribir sus sistemas usando cualquier lenguaje de programación (Visual Basic, Delphi, C++, Java etc)... basta con instrumentar la comunicación con una base de datos comercial como Oracle ó Microsoft SQL Server, usando para ello el lenguaje de interrogación SQL.

Lo curioso, sin embargo, es que ahora un programador no puede conformarse con conocer un lenguaje de programación, sino que además, debe conocer un lenguaje de interrogación de bases de datos, es decir, SQL. Si el sistema se escribe para la Web, entonces el programador también debe conocer el "lenguaje de presentación" que se usa en la Web, que es HTML, y muy probablemente otros lenguajes que se usan en este entorno como javacript y vbscript.

En resumen, un programador de aplicaciones hoy en dia, trabaja a un alto nivel de abstracción respecto al hardware, pero al mismo tiempo tiene que ser experto no en uno, sino en varios lenguajes.

La producción (industrial) de Software

Una aplicación de software moderna, es un producto industrial y se produce de forma similar a como se construye un edificio o se produce una lata de chorizos.

El ciclo de producción involucra varias fases: (1) Analisis (2) Implementación (3) Puesta a punto (4) Instalación.

Normalmente hay un equipo de trabajo compuesto, digamos por cuatro programdores y un jefe de proyecto. Probablemente este último es quien lleva a cabo la primera fase, o sea, el analisis o diseño del sistema. En esta fase se diseña la estructura de la base de datos, se decide qué arquitectura va a tener el sistema, si va a ser una aplicación tipo Web a través de un intranet o la internet, o si en cambio va a ser una aplicación normal de Windows, y otros muchísimos detalles de diseño. Finalmente se escribe una especificación detallada del producto final. Esta face fuede prolongarse por varias semanas o incluso meses.

Entonces comienza la etapa de implementación. Los programadores son instruidos y el trabajo repartido entre ellos. Cada cual escribe una parte del programa, que normalmente es largo y comprende muchos ficheros de código fuente. Cada programador hace pruebas elementales de su parte, pero la prueba definitiva tiene que ser cuando todas las partes estén terminadas.

Cuando todo está listo, las diferentes partes se integran para conformar un todo, que se compila entonces para dar lugar al producto definitivo... por ahora.

El resultado de la compilación (lo que se llama un "built") se entrega entonces a otro equipo de trabajo: QA (Quality Assurance, Control de Calidad); estos son profesionales llamados "testers" que están entrenados para encontrar "bugs" (defectos) en los programas. Al cabo de varias horas, o tal vez días, los testers entregan de vuelta una lista con los defectos encontrados. El jefe del proyecto reparte los "bugs" a los programadores y estos tratan de corregirlos. Este círculo prueba-depuración se repite hasta que el producto esté satisfactoriamente depurado. Hay que decir que ningún producto de software llega a estar totalmente excento de errores, pero sí puede estar suficientemente depurado como para que sea extremadamente difícil encontrar un error.

Dependiendo de la complejidad del producto, este ciclo puede prolongarse por un mes, varios meses, o tal vez un año.

Cuando un programador encuentra empleo por primera vez en una compañía, muy probablemente va a tener que enfrentarse con un proyecto que tiene varios años en el mercado. Mientras los clientes disfrutan de la última versión, los productores desarrollan y depuran la siguiente. El nuevo programador tendrá que depurar código que él no escribió; leer y entender código escrito por otra persona, es una tarea difícil y que requiere experiencia.

Otras aplicaciones de software son más complejas y requieren de manos especializadas dentro de diferentes areas de la programación. Por ejemplo, escribir un compilador de lenguaje es una especialidad dentro de la programación. También lo son la escritura de sistemas operativos, device drivers, juegos, multimedia, inteligencia artificial y otros.

Conclusión

Es obvio que la programación involucra otros muchos aspectos que no han quedado cubiertos en este artículo, y aún aquellos que lo han sido, se tocan sin profundizar demaciado. La intensión ha sido darle al lector una idea somera de cómo funciona el software, y cómo se produce.


                                                

Miami / USAmail@armandoacosta.comInicio