Historia

Las ideas básicas de la orientación a objetos nacen a principios de los años 60 en la universidad de Noruega. Un equipo dirigi-do por el Dr. Nygaard se dedicaba a desarrollar sistemas infor-máticos para realizar simulaciones de sistemas físicos como simular el funcionamiento y obtener el rendimiento de un motor. La dificultad en la que se encontraban era doble. Por un lado los programas eran muy complejos y, por otro, forzosamente tenian que ser muy modificados. Este segundo punto era especialmente problemático, ya que la razón de ser de los programas era el cambio y no sólo se requerían varias iteraciones para obtener un producto con el rendimiento deseado, sino que muchas veces se querían obtener diversas alternativas viables cada una con sus ventajas e inconvenientes.

La solución que idearon fue diseñar el programa paralelamente al objeto físico. Es decir, si el objeto físico tenía cien componentes, el programa también tendría cien módulos, uno por cada pieza. Partiendo el programa de esta manera, había una total correspondencia entre el sistema físico y el sistema informático. Así, cada pieza física tenía su abstracción informática en un módulo. De la misma manera que los sistemas físicos se comunican enviándose señales, los módulos informáticos se comunicarían enviándose mensajes.

Este enfoque resolvió los dos problemas planteados. Primeramente, ofrecía una forma natural de partir un programa muy complejo y, en segundo lugar, el mantenimiento pasaba a ser controlable. El primer punto es obvio ya que, al partir el programa en unidades informáticas paralelas a las físicas, la descomposición es automática. El segundo punto también se resuelve ya que, a cada iteración de simulación, el analista querrá cambiar o bien piezas enteras o bien el comportamiento de alguna pieza. En ambos casos la localización de los cambios está perfectamente clara y su alcance se reduce a un componente, siempre y cuando el interfaz del mismo no cambie. Por ejemplo, si se estuviese simulando un motor o coche, puede que se quisiera modificar el delco utilizado en la simulación anterior. Si el nuevo delco tuviera la misma interfaz (mismos inputs y outputs) o se cambiase sólo su comportamiento interno, nada del sistema (fuera del delco) estaría afectado por el cambio.

Pero, poco a poco, fue obteniendose otro beneficio muy importante, que es la razón principal por la que la industria informática se ha abocado a la orientación a objetos. Se trata de la reusabilidad. En el proceso de construcción de un programa se obtienen piezas para futuros programas. Avanzando algunas cifras, se puede indicar que los niveles de reutilización de software pasan del 5-15% en centros no orientados a objetos, a niveles por encima del 80%.

Para implementar estas ideas lo que se hizo fue crear un lenguaje para darle soporte, Simula-67, que continua utilizándose actualmente.

El siguiente paso se da en los años 70 en los Estados Unidos. Xerox tiene un centro de investigación en Plo Alto, donde trabajan en conceptos que puedan convertirse en productos industriales al cabo de 10 a 20 años. Así pues, en aquellos años contrataron a un joven llamado Alan Kay para que llevase a término las ideas que proponía en su tesis doctoral, la propuesta de construcción de un ordenador llamado Dynabook, adecuado para ser utilizado por niños. El ordenador no tenía teclado, la pantalla era sensible al tacto y la mayor parte de la comunicación era gráfica. Al desarrollar este proyecto se inventó el 'mouse' y los entornos gráficos. Al volver a encontrarse con una progra-mación compleja y experimental, como en el caso de Nygaard, decidieron crear un entorno y lenguaje llamado Smalltalk.

Smalltalk tuvo una gran difusión y cuando en los años 80 en ATT-Bell quisieron crear un sucesor al lenguaje C, incorporaron las principales ideas de Smalltalk y de Simula, creando el lenguaje C++. Puede afirmarse que se debe a este último la gran extensión de los conceptos de la orientación a objetos.

Conviene subrayar que el desarrollo que hemos descrito se refiere sólo a la evolución que ha tenido la orientación a objetos en el mundo de la ingeniería del software. Ha existido un desarrollo paralelo de los mismos conceptos en el mundo de la inteligencia artificial, donde el lenguaje CLOS, una variante de Lisp orientada a objetos, está enormemente extendido.

Principios

La orientación a objetos se basa en tres pilares básicos: - encapsulación y ocultación de la información - abstracción y clasificación

- herencia y polimorfismo

La encapsulación significa agrupar en una sola entidad ('caja') datos y operaciones sobre esos datos. Evidentemente todo programa es una encapsulación, pero por encapsulación queremos decir algo mas preciso: en concreto, cada componente ha de tener nada más que los datos relacionados con un tema y su manipulación. Por ejemplo cualquier programa de facturación puede leer directamente un registro de artículo y modificar el 'stock' al mismo tiempo que imprime la factura y modifica el saldo del cliente. Tenemos tres activitades sobre tres entidades diferentes en un único componente ('el progra-ma'). Este programa no tiene una encapsulación adecuada.

El concepto de ocultación de la información se refiere a que cada componente sabe lo mínimo posible de los otros y proporciona la mínima información posible sobre sí mismo. Por ejemplo, si en una aplicación se puede acceder al saldo de un cliente, es innecesario saber si el saldo está almacenado como un entero o un real o si se ha de ejecutar una rutina para obtenerlo. Sólo debe preocupar como pedirle al cliente su saldo y no como está representado internamente.

Desde hace muchos años, estos principios han estado disponibles en los lenguajes de programación, aunque su uso era optativo. La diferencia es que los lenguajes orientados a objetos dan soporte sintáctico a los dos conceptos, y que su uso es obligado en muchos lenguajes puros orientados a objetos.

El siguiente pilar es el de la abstracción y clasificación. Por abstracción entendemos que los módulos, a los que aplicamos la encapsulación y la ocultación citadas, sean representaciones abstractas de los conceptos que nos interesan. Es decir, que si hacemos una aplicación para una autoescuela, deberemos crear una entidad informática, que de momento podemos llamar módulo, para abstraer los hechos más característicos de los conceptos que estamos tratando: coche, alumno, matrícula, semáforo, etc. Hasta ahora, se habían considerado solamente los datos al diseñar la base e datos. Ahora deberemos hacerlo con todas las características de las entidades de nuestro modelo o dominio. Por ejemplo, si un cliente puede tener un descuento, deberemos asociar la rutina de cálculo al cliente y no a los programas aplicativos. Es decir, que el módulo 'cliente' estará descrito no sólo por unos datos (nombre, DNI, dirección, ...) sino también por rutinas (cálculo del descuento, saldo, ...).

Desde el momento en que se realizan las abstracciones de esa forma, se están clasificando las entidades del dominio en clases. Es decir, la clase 'cliente' (la definición de la clase cliente) describe no solamente un cliente concreto sino a todos los clientes que cumplan unas características dadas. Podemos ver a 'cliente' como una fábrica de clientes, donde cada cliente concreto será una 'instancia' (un objeto) de una clase cliente.

A veces se dice que en la programación orientada a objetos se manipulan tipos de usuario. Quiere decirse que el programador (el usuario) puede definir unas entidades abstractas (como ahora cliente o entero) a partir de los datos (atributos) que le son propios y las operaciones que sean válidas (cálculo- descuento o suma) sobre la entidad. Es decir, además de unos tipos que vienen definidos por el lenguaje (enteros, reales, carácteres), el usuario puede crear otros nuevos y, a partir de éstos, crear instancias o variables de los tipos del usuario.

Además puede tenerse diferentes tipos de clientes (mayoristas, minoristas, etc.) que serán solo parcialmente diferentes. Es decir, todos tendrán nombre, DNI, dirección, etc.; pero la rutina de cálculo de descuento será diferente según el tipo de cliente y además, cada cliente tendrá una información adicional necesaria para calcular el descuento (un porcentaje, una tabla de descuentos, etc.) diferente según el tipo de cliente. Cuando esto sucede, se puede definir un cliente abstracto como lo que tienen en común todos los clientes para definir posteriormente, en cada uno de los tipos de clientes que se tienen, sólo aquello que le es particular. Es decir, cliente mayorista 'heredará' toda la descripción de cliente abstracto y le añadirá algunas de las características adicionales.

La herencia permite entonces describir entidades (clases) por diferencia entre ellas; por eso se dice que programar con orientación a objetos es programar para diferenciar. La utilidadad de la herencia es múltiple. En primer lugar hay que analizar, diseñar, codificar y poner a punto menos, ya que en cuanto se tiene un concepto definido, jamás lo repetimos. Como mucho, si el concepto nuevo es muy parecido a uno anterior, se define el nuevo como la diferencia respecto al anterior. Si surge un error en la utilización de la nueva entidad, seguro que el error está en lo que se ha añadido porque lo que se ha heredado ya se había probado.

Hay diferentes tipos de herencia: los más importantes son simple y múltiple. Con esto se quiere decir que, al contrario de la herencia biológica donde siempre se hereda de dos padres, en la orientación a objetos se puede heredar de uno, dos o más padres. La definición de cliente minorista a partir de cliente es un ejemplo de herencia simple. Y se podría definir un vehículo anfibio como una herencia (una subclase) de otras dos clases: coche y barco.

Queda como último concepto a tratar el polimorfismo. En el ejemplo anterior de los clientes se podría forzar que toda subclase de cliente tuviera una operación ('servicio' o 'método') de cálculo-descuento, definiendo una operación diferida (o virtual) en la clase abstracta cliente. Es decir, que cliente pasa a ser una especie de plantilla de todos los clientes donde hay algunas cosas definidas (nombre, DNI) y otras pendientes a definir en cada subclase (cálculo-descuento). En caso de que esto suceda, podríamos garantizar que todo cliente tendría ua operación de 'calcular descuento' asociada, sea el tipo que sea de cliente. Si nos encontramos en esta situación estaremos en disposición de usar lo que se llama polimorfismo, que simplifica mucho los programas y los hace extensibles a nuevos tipos sin necesidad siquiera de recompilar.

Por ejemplo, si quisieramos hacer un programa de listar facturas a partir de unos albaranes, podríamos ir leyendo secuencialmente los albaranes a medida que los fuesemos emparejando con clientes. En cada emparejamiento imprimi-ríamos una factura tras calcular el descuento aplicable. Como sabemos que descuento es algo que está definido en 'cliente', podríamos enviar a cliente el mensaje 'calculo_descuento' (pedirle que ejecute la rutina) con el albarán como parámetro. La instrucción sería algo parecido a:

descuento := cliente.calculo_descuento (albarán)

Esta instrucción es única para todos los clientes sean del tipo que sean. Por tanto con un mismo mensaje y según sea el recep-tor, se ejecutan diferentes rutinas (diferentes formas para un mismo mensaje = polimorfismo). Además y mientras se conti-nue cumpliendo que todo cliente tiene una operación asociada de calculo_descuento, podremos crear nuevos tipos de clientes sin necesidad ni de recompilar el programa de facturas.

El impacto de la orientación a objetos

Como veremos, el impacto de la OO en la industria del soft-ware puede ser enorme, pero repasemos antes algunas razones.

Como hemos dicho, la primera y mas importante razón es la reutilización. Hasta ahora sólo se podía obtener reutilización de dos formas: rutinas de bajo nivel (operar con datos) o subsistemas completos (la aplicación de cartera que enlaza con cualquier facturación). Esto limitaba fuertemente la reutilización, porque reaprovechar una aplicación quería decir aceptarla como era al 100%. Como mucho se podía intentar parametrizar una aplicación potencialmente reutilizable si se lograban prever futuros requerimientos al programa y se flexibilizaba su uso. El precio es complicar mucho más el programa y dificultar su mantenimiento, sin eliminar del todo la necesidad de modificar el programa cuando los reque-rimientos de los clientes no pueden conseguirse con la parametrización.

El paradigma (la forma de pensar y representar la realidad) de la orientación a objetos es mucho mas potente que el estructurado y permite obtener más reusabilidad, por dos razones. En primer lugar porque se puede tener reusabilidad por separado, tanto del análisis como del diseño y la programación; no estamos obligados a coger un paquete entero: si sólo nos interesa el análisis, lo podemos reutilizar con un diseño diferente del que se había utilizado originalmente. La segunda razón es la herencia. Si una aplicación tiene algunas partes que no se adecuan a nuestras necesidades, podemos modificarlos sin 'parchear' mediante la herencia. Es decir, la programación pasa a ser como el 'prêt-a-porter' en la industria textil. Podemos tener la mayor parte hecha industrialmente y adaptarla a cada cliente según sus necesidades.

La programación orientada a objetos también es mucho mas fiable por diversas razones. En primer lugar por el desarrollo incremental y la programación por diferencia, al poder ir añadiendo funcionalidad vía herencia. El tamaño medio de una rutina en entornos orientados a objetos es de 4 o 5 líneas; y se ha de tener en cuenta que sólo se tienen rutinas, ya que no existe el concepto de programa principal. La utilización masiva de librerias de clases garantiza la fiabilidad, ya que los componentes sólo se añaden a la libreria cuando se ha verifi-cado la corrección de su funcionamiento.

h lgunos aspectos de la verificación formal de los programas, que hasta ahora era un propuesta totalmente teórica, se han añadido por vez primera a los lenguajes de producción.

Veamos a continuación el impacto de la orientación a objetos en la ingeniería del software.

En primer lugar los lenguajes, que es por donde se inicia la orientación a objetos. Como ya hemos señalado el lenguaje mas extendido es el C++. Este permite la compatibilidad con todo el software C y, además, ANSI ha asumido su estandarización. También ANSI está añadiendo en Cobol y Fortran los conceptos de la orientación a objetos. Para Cobol ya existe el borrador que se aprobará en 1997 y también un producto (Microfocus) que incorpora parte de las extensiones propuestas por ANSI. Este nuevo Cobol permitirá mantener la compatibilidad con Cobol-85 al mismo tiempo que ofrecerá una vía de acceso a la nueva tecnología para todos los grandes centros con 'mainframes' que trabajen con Cobol. El entorno ADA también tendrá extensiones orientadas a objetos ya que se han incorporado a la nueva definición ADA/9X (ver artícº).

También es necesario tener metodologías de análisis y diseño como existían en el mundo estructurado. En cuanto a los centros que trabajan con metodologías y herramientas CASE, es impensable pasar a una nueva tecnología sin metodologías. Los autores principales de los métodos estructurados (Martin, Mellor, Yourdon) se han pasado a la orientación a objetos y han realizado propuestas de análisis y diseño orientado a objetos. Los constructores de herramientas CASE, por su parte, han desarrollado nuevas herramientas o han añadido extensiones a les herramientas anteriores.

También el mundo de las bases de datos está moviendose hacia la orientación a objetos. Por un lado se tienen las BDOO, bases de datos orientadas a objetos puras (POET, Objectstore, etc.) y por otro las relacionales. En las BDOO, la organización ODMG representa el 100% de las BDOO industriales y ha establecido un estándar de definición (ODL) y manipulación (OQL) de bases de datos equivalente a SQL. Respecto a las relacionales, todas (Oracle, Informix, etc.) estan añadiendo en mayor o menor grado algunos aspectos de la orientación a objetos. ANSI, por su parte, está definiendo un SQL-3 que incorpora muchos aspectos de la orientación a objetos. El futuro del SQL-3 es sin embargo incierto, ya que ODMG ha ofrecido a ANSI su estándar para que sirva de base para un nuevo SQL, con lo que sólo habría un único estándar de base de datos.

El grupo ODMG nació de un grupo mas grande, llamado OMG, donde están representados todas las casas con alguna influencia en el sector. Este grupo está definiendo un estándar universal por objetos. Este estándar permitirá que un objeto programado en cualquier lenguaje y sistema operativo pueda acceder a cualquier otro objeto con no importa que lenguaje y sistema operativo. Esto facilitará enormemente el desarrollo de sistemas abiertos cliente-servidor.

Como cabía esperar, los sistemas operativos también están siendo afectados por la orientación a objetos. En primer lugar ya se tiene un primer sistema operativo orientado a objetos, NextStep, que está integrado con Sun. Microsoft por su parte ha anunciado para 1996 un sistema operativo orientado a objetos llamado de momento Cairo. IBM y Apple también están creando uno nuevo, a través de la empresa Taligent, que de momento se denomina Pink y que también estará disponible a finales del 95 o principios del 96.

Epílogo

Esperemos que con esta introducción se transmita la importancia qu tiene para los profesionales reciclarse hacia la orientación a objetos. De la misma manera que ha sido inevitable aprender programación estructurada o utilizar bases de datos relacionales, el paso a la orientación a objetos es también inevitable. Por otra parte el reciclaje es absolutamente posible aunque lento. Una persona con experiencia puede formarse con un curso de un año de duración, como el que desarrollamos en la Facultat de Informática de Barcelona para profesionales, pero necesita al menos otro año para ser eficaz en su utilización y todavía un tercer año mas para cronstruirse unas librerías de clase que le proporcionen la eficacia deseada.