Programación Orientada a Objetos
INTRODUCCION
Actualmente una de las áreas más candentes en la industria y en el
ámbito académico es la orientación a objetos. La orientación a objetos promete
mejoras de amplio alcance en la forma de diseño, desarrollo y mantenimiento del
software ofreciendo una solución a largo plazo a los problemas y preocupaciones
que han existido desde el comienzo en el desarrollo de software: la falta de
portabilidad del código y reusabilidad, código que es difícil de modificar,
ciclos de desarrollo largos y técnicas de codificación no intuitivas.
Un lenguaje orientado a objetos ataca estos problemas. Tiene tres
características básicas: debe estar basado en objetos, basado en clases y capaz
de tener herencia de clases. Muchos lenguajes cumplen uno o dos de estos
puntos; muchos menos cumplen los tres. La barrera más difícil de sortear es
usualmente la herencia.
El concepto de programación orientada a objetos (OOP) no es nuevo,
lenguajes clásicos como SmallTalk se basan en ella. Dado que la OOP. Se basa en
la idea natural de la existencia de un mundo lleno de objetos y que la
resolución del problema se realiza en términos de objetos, un lenguaje se dice
que está basado en objetos si soporta objetos como una característica fundamental
del mismo.
El elemento fundamental de la OOP es, como su nombre lo indica, el objeto.
Podemos definir un objeto como un conjunto complejo de datos y programas que
poseen estructura y forman parte de una organización.
Esta definición especifica varias propiedades importantes de los
objetos. En primer lugar, un objeto no es un dato simple, sino que contiene en
su interior cierto número de componentes bien estructurados. En segundo lugar,
cada objeto no es un ente aislado, sino que forma parte de una organización
jerárquica o de otro tipo.
ESTRUCTURA DE UN OBJETO
Un objeto puede considerarse como una especie de cápsula dividida
en tres partes:
1 - RELACIONES
2 - PROPIEDADES
3 - METODOS
Cada uno de estos componentes desempeña un papel totalmente
independiente:
Las relaciones permiten que el objeto se inserte en la
organización y están formadas esencialmente por punteros a otros objetos.
Las propiedades distinguen un objeto determinado de los
restantes que forman parte de la misma organización y tiene valores que
dependen de la propiedad de que se trate. Las propiedades de un objeto pueden
ser heredadas a sus descendientes en la organización.
Los métodos son las operaciones que pueden realizarse sobre
el objeto, que normalmente estarán incorporados en forma de programas (código)
que el objeto es capaz de ejecutar y que también pone a disposición de sus
descendientes a través de la herencia.
Encapsulamiento y ocultación
Como hemos visto, cada objeto es una estructura compleja en cuyo
interior hay datos y programas, todos ellos relacionados entre sí, como si
estuvieran encerrados conjuntamente en una cápsula. Esta propiedad (encapsulamiento),
es una de las características fundamentales en la OOP.
Los objetos son inaccesibles, e impiden que otros objetos, los
usuarios, o incluso los programadores conozcan cómo está distribuida la
información o qué información hay disponible. Esta propiedad de los objetos se
denomina ocultación de la información.
Esto no quiere decir, sin embargo, que sea imposible conocer lo
necesario respecto a un objeto y a lo que contiene. Si así fuera no se podría
hacer gran cosa con él. Lo que sucede es que las peticiones de información a un
objeto. Deben realizarse a través de mensajes dirigidos a él, con la
orden de realizar la operación pertinente. La respuesta a estas órdenes será la
información requerida, siempre que el objeto considere que quien envía el
mensaje está autorizado para obtenerla.
El hecho de que cada objeto sea una cápsula facilita enormemente
que un objeto determinado pueda ser transportado a otro punto de la
organización, o incluso a otra organización totalmente diferente que precise de
él. Si el objeto ha sido bien construido, sus métodos seguirán
funcionando en el nuevo entorno sin problemas. Esta cualidad hace que la OOP
sea muy apta para la reutilización de programas.
Organización de los objetos
En principio, los objetos forman siempre una organización
jerárquica, en el sentido de que ciertos objetos son superiores a otros de
cierto modo.
Existen varios tipos de jerarquías: serán simples cuando su
estructura pueda ser representada por medio de un "árbol". En otros
casos puede ser más compleja.
En cualquier caso, sea la estructura simple o compleja, podrán
distinguirse en ella tres niveles de objetos.
-La raíz de la jerarquía. Se trata de un objeto único
y especial. Este se caracteriza por estar en el nivel más alto de la estructura
y suele recibir un nombre muy genérico, que indica su categoría especial, como
por ejemplo objeto madre, Raíz o Entidad.
-Los objetos intermedios. Son aquellos que descienden
directamente de la raíz y que a su vez tienen descendientes. Representan
conjuntos o clases de objetos, que pueden ser muy generales o muy
especializados, según la aplicación. Normalmente reciben nombres genéricos que
denotan al conjunto de objetos que representan, por ejemplo, VENTANA, CUENTA,
FICHERO. En un conjunto reciben el nombre de clases o tipos si
descienden de otra clase o subclase.
-Los objetos terminales. Son todos aquellos que descienden
de una clase o subclase y no tienen descendientes. Suelen llamarse casos
particulares, instancias o ítems porque representan los elementos
del conjunto representado por la clase o subclase a la que pertenecen.
Veamos ahora en detalle los tres elementos mencionados en
"Estructura de un Objeto".
1. RELACIONES
Las relaciones entre objetos son, precisamente, los enlaces que
permiten a un objeto relacionarse con aquellos que forman parte de la misma
organización.
Las hay de dos tipos fundamentales:
-Relaciones jerárquicas. Son esenciales para la existencia misma
de la aplicación porque la construyen. Son bidireccionales, es decir, un objeto
es padre de otro cuando el primer objeto se encuentra situado inmediatamente
encima del segundo en la organización en la que ambos forman parte; asimismo,
si un objeto es padre de otro, el segundo es hijo del primero (en la Fig. 2, B
es padre de D,E y F, es decir, D,E y F son hijos de B; en la Fig. 3, los
objetos B y C son padres de F, que a su vez es hijo de ambos).
Una organización jerárquica simple puede definirse como aquella en
la que un objeto puede tener un solo padre, mientras que en una organización
jerárquica compleja un hijo puede tener varios padres).
-Relaciones semánticas. Se refieren a las relaciones que no
tienen nada que ver con la organización de la que forman parte los objetos que
las establecen. Sus propiedades y consecuencia solo dependen de los objetos en
sí mismos (de su significado) y no de su posición en la organización.
Se puede ver mejor con un ejemplo: supongamos que vamos a construir
un diccionario informatizado que permita al usuario obtener la definición de
una palabra cualquiera. Supongamos que, en dicho diccionario, las palabras son
objetos y que la organización jerárquica es la que proviene de forma natural de
la estructura de nuestros conocimientos sobre el mundo.
La raíz del diccionario podría llamarse TEMAS. De éste término
genérico descenderán tres grandes ramas de objetos llamadas VIDA, MUNDO y
HOMBRE. El primero (vida) comprenderá las ciencias biológicas: Biología y
Medicina. El segundo (mundo), las ciencias de la naturaleza inerte: las
Matemáticas, la Física, la Química y la Geología. El tercero (hombre)
comprenderá las ciencias humanas: la Geografía, la Historia, etc.
Veamos un ejemplo: estableceremos la relación trabajo entre
los objetos NEWTON y OPTICA y la interpretaremos diciendo que significa que
Newton trabajó en óptica (véase la Fig. 4). La relación es,
evidentemente, semántica, pues no establece ninguna connotación jerárquica
entre NEWTON y OPTICA y su interpretación depende exclusivamente del significado
de ambos objetos.
La existencia de esta relación nos permitirá responder a preguntas
como:
¿Quién trabajó en óptica?
¿En qué trabajó Newton?
¿Quien trabajó en Física?
Las dos primeras se deducen inmediatamente de la existencia de la
relación trabajo. Para la tercera observamos que si Newton trabajó en
óptica automáticamente sabemos que trabajó en Física, por ser óptica una rama
de la Física (en nuestro diccionario, el objeto OPTICA es hijo del objeto
FISICA). Entonces gracias a la OOP podemos responder a la tercera pregunta sin
necesidad de establecer una relación entre NEWTON y FISICA, apoyándonos sólo en
la relación definida entre NEWTON y OPTICA y en que OPTICA es hijo de FISICA. De
este modo se elimina toda redundancia innecesaria y la cantidad de información
que tendremos que definir para todo el diccionario será mínima.
2. PROPIEDADES
Todo objeto puede tener cierto número de propiedades, cada una de
las cuales tendrá, a su vez, uno o varios valores. En OOP, las propiedades
corresponden a las clásicas "variables" de la programación
estructurada. Son, por lo tanto, datos encapsulados dentro del objeto, junto
con los métodos (programas) y las relaciones (punteros a otros objetos). Las
propiedades de un objeto pueden tener un valor único o pueden contener un
conjunto de valores más o menos estructurados (matrices, vectores, listas,
etc.). Además, los valores pueden ser de cualquier tipo (numérico, alfabético,
etc.) si el sistema de programación lo permite.
Pero existe una diferencia con las "variables", y es que
las propiedades se pueden heredar de unos objetos a otros. En consecuencia, un
objeto puede tener una propiedad de maneras diferentes:
-Propiedades propias. Están formadas dentro de la cápsula del
objeto.
-Propiedades heredadas. Están definidas en un objeto diferente,
antepasado de éste (padre,"abuelo", etc.). A veces estas propiedades
se llaman propiedades miembro porque el objeto las posee por el mero
hecho de ser miembro de una clase.
3. METODOS
Una operación que realiza acceso a los datos. Podemos definir
método como un programa procedimental o procedural escrito en cualquier
lenguaje, que está asociado a un objeto determinado y cuya ejecución sólo puede
desencadenarse a través de un mensaje recibido por éste o por sus
descendientes.
Son sinónimos de 'método' todos aquellos términos que se han
aplicado tradicionalmente a los programas, como procedimiento, función, rutina,
etc. Sin embargo, es conveniente utilizar el término 'método' para que se
distingan claramente las propiedades especiales que adquiere un programa en el
entorno OOP, que afectan fundamentalmente a la forma de invocarlo (únicamente a
través de un mensaje) y a su campo de acción, limitado a un objeto y a sus
descendientes, aunque posiblemente no a todos.
Si los métodos son programas, se deduce que podrían tener
argumentos, o parámetros. Puesto que los métodos pueden heredarse de unos
objetos a otros, un objeto puede disponer de un método de dos maneras diferentes:
-Métodos propios. Están incluidos dentro de la cápsula del
objeto.
-Métodos heredados. Están definidos en un objeto diferente,
antepasado de éste (padre,"abuelo", etc.). A veces estos métodos se
llaman métodos miembro porque el objeto los posee por el mero hecho de
ser miembro de una clase.
Polimorfismo
Una de las características fundamentales de la OOP es el
polimorfismo, que no es otra cosa que la posibilidad de construir varios
métodos con el mismo nombre, pero con relación a la clase a la que pertenece
cada uno, con comportamientos diferentes. Esto conlleva la habilidad de enviar
un mismo mensaje a objetos de clases diferentes. Estos objetos recibirían el
mismo mensaje global pero responderían a él de formas diferentes; por ejemplo,
un mensaje "+" a un objeto ENTERO significaría suma, mientras que
para un objeto STRING significaría concatenación ("pegar" strings uno
seguido al otro)
Demonios
Es un tipo especial de métodos, relativamente poco frecuente en los
sistemas de OOP, que se activa automáticamente cuando sucede algo especial. Es
decir, es un programa, como los métodos ordinarios, pero se diferencia de estos
porque su ejecución no se activa con un mensaje, sino que se desencadena
automáticamente cuando ocurre un suceso determinado: la asignación de un valor
a una propiedad de un objeto, la lectura de un valor determinado, etc.
Los demonios, cuando existen, se diferencian de otros métodos por
que no son heredables y porque a veces están ligados a una de las propiedades
de un objeto, mas que al objeto entero.
CONSIDERACIONES FINALES
Beneficios que se obtienen del desarrollo con OOP
Día a día los costos del Hardware decrecen. Así surgen nuevas áreas
de aplicación cotidianamente: procesamiento de imágenes y sonido, bases de
datos multimediales, automatización de oficinas, ambientes de ingeniería de
software, etc. Aún en las aplicaciones tradicionales encontramos que
definir interfases hombre-máquina "a-la-Windows" suele ser bastante
conveniente.
Lamentablemente, los costos de producción de software siguen
aumentando; el mantenimiento y la modificación de sistemas complejos suele ser
una tarea trabajosa; cada aplicación, (aunque tenga aspectos similares a otra)
suele encararse como un proyecto nuevo, etc.
Todos estos problemas aún no han sido solucionados en forma
completa. Pero como los objetos son portables (teóricamente) mientras que la
herencia permite la reusabilidad del código orientado a objetos, es más
sencillo modificar código existente porque los objetos no interaccionan excepto
a través de mensajes; en consecuencia un cambio en la codificación de un objeto
no afectará la operación con otro objeto siempre que los métodos respectivos
permanezcan intactos. La introducción de tecnología de objetos como una
herramienta conceptual para analizar, diseñar e implementar aplicaciones
permite obtener aplicaciones más modificables, fácilmente extendibles y a
partir de componentes reusables. Esta reusabilidad del código disminuye el
tiempo que se utiliza en el desarrollo y hace que el desarrollo del software
sea más intuitivo porque la gente piensa naturalmente en términos de objetos
más que en términos de algoritmos de software.
Problemas derivados de la utilización de OOP en la actualidad
Un sistema orientado a objetos, por lo visto, puede parecer un
paraíso virtual. El problema sin embargo surge en la implementación de
tal sistema. Muchas compañías oyen acerca de los beneficios de un sistema
orientado a objetos e invierten gran cantidad de recursos luego comienzan a
darse cuenta que han impuesto una nueva cultura que es ajena a los
programadores actuales. Específicamente los siguientes temas suelen aparecer
repetidamente:
Curvas de aprendizaje largas. Un sistema orientado a
objetos ve al mundo en una forma única. Involucra la conceptualización de todos
los elementos de un programa, desde subsistemas a los datos, en la forma de
objetos. Toda la comunicación entre los objetos debe realizarse en la forma de
mensajes. Esta no es la forma en que están escritos los programas orientados a
objetos actualmente; al hacer la transición a un sistema orientado a objetos la
mayoría de los programadores deben capacitarse nuevamente antes de poder
usarlo.
Dependencia del lenguaje. A pesar de la portabilidad conceptual de
los objetos en un sistema orientado a objetos, en la práctica existen muchas
dependencias. Muchos lenguajes orientados a objetos están compitiendo
actualmente para dominar el mercado. Cambiar el lenguaje de implementación de
un sistema orientado a objetos no es una tarea sencilla; por ejemplo C++
soporta el concepto de herencia múltiple mientras que SmallTalk no lo soporta;
en consecuencia la elección de un lenguaje tiene ramificaciones de diseño muy
importantes.
Determinación de las clases. Una clase es un molde que se utiliza
para crear nuevos objetos. En consecuencia es importante crear el conjunto de
clases adecuado para un proyecto. Desafortunadamente la definición de las
clases es más un arte que una ciencia. Si bien hay muchas jerarquías de clase
predefinidas usualmente se deben crear clases específicas para la aplicación
que se este desarrollando. Luego, en 6 meses ó 1 año se da cuenta que las
clases que se establecieron no son posibles; en ese caso será necesario
reestructurar la jerarquía de clases devastando totalmente la planificación
original.
Performance. En un sistema donde todo es un objeto y toda
interacción es a través de mensajes, el tráfico de mensajes afecta la
performance. A medida que la tecnología avanza y la velocidad de
microprocesamiento, potencia y tamaño de la memoria aumentan, la situación
mejorará; pero en la situación actual, un diseño de una aplicación orientada a
objetos que no tiene en cuenta la performance no será viable comercialmente.
Idealmente, habría una forma de atacar estos problemas eficientemente
al mismo tiempo que se obtienen los beneficios del desarrollo de una estrategia
orientada a objetos. Debería existir una metodología fácil de aprender e
independiente del lenguaje, y fácil de reestructurar que no drene la
performance del sistema.