(OOP, Object Oriented
Programming)
- Objetos
- Diseño de
aplicaciones y elección de entorno. - Aplicaciones orientadas a
objetos - Características de los
lenguajes OOP - Panorámica de los
lenguajes OOP - Bases de datos orientadas a
objetos - Objetos y
asociaciones. - La relación de
herencia. - Bibliografía /
infografía
l término de Programación
Orientada a Objetos indica más una forma de diseño
y una metodología de desarrollo de
software que un
lenguaje de
programación, ya que en realidad se puede aplicar el
Diseño
Orientado a Objetos (En inglés
abreviado OOD, Object Oriented Design), a cualquier tipo de
lenguaje de
programación.
El desarrollo de
la OOP empieza a destacar durante la década de lo 80
tomando en cuenta la programación estructurada, a la que engloba
y dotando al programador de nuevos elementos para el análisis y desarrollo de software.
El propósito de este trabajo es explicar el
diseño orientado a objeto y no una explicación de
su programación, puesto que no nos alcanzaría toda
la currícula para hacerlo.
Básicamente la OOP permite a los programadores
escribir software, de forma que esté organizado en la
misma manera que el problema que trata de modelizar. Los lenguajes de
programación convencionales son poco más que
una lista de acciones a
realizar sobre un conjunto de datos en una
determinada secuencia. Si en algún punto del programa
modificamos la estructura de
los datos o la
acción realizada sobre ellos, el programa
cambia.
La OOP aporta un enfoque nuevo, convirtiendo la estructura de
datos en el centro sobre el que pivotan las operaciones. De
esta forma, cualquier modificación de la estructura de
datos tiene efecto inmediato sobre las acciones a
realizar sobre ella, siendo esta una de la diferencias radicales
respecto a la programación estructurada.
Para quienes no están familiarizados con la
programación estructurada diré que una de las bases
de esta escuela de
programación parte del diseño arriba – abajo.
En esta forma de diseño se descomponen los requerimientos
del programa paso a paso, hasta llegar a un nivel que permite
expresarlos mediante procedimientos y
funciones. La
OOP estructura los
datos en objetos que pueden almacenar, manipular y combinar
información.
En resumen, la programación estructurada presta
atención al conjunto de acciones que
manipulan el flujo de datos (desde la situación inicial a
la final), mientras que la programación
orientada a objetos presta atención a la interrelación que
existe entre los datos y las acciones a realizar con
ellos.
Muchos habrán oído
comentarios sobre la incidencia de la OOP sobre la
programación convencional. Se ha llegado a decir que el
cambio
introducido por la OOP es similar al producido por la
aparición del ensamblador
sobre el código
de máquina.
La OOP proporciona las siguientes ventajas sobre otros
lenguajes de
programación
Uniformidad. Ya que la representación de
los objetos lleva implica tanto el análisis como el diseño y la
codificación de los mismos.
Comprensión. Tanto los datos que componen
los objetos, como los procedimientos
que los manipulan, están agrupados en clases, que se
corresponden con las estructuras de
información que el programa
trata.
Flexibilidad. Al tener relacionados los
procedimientos que manipulan los datos con los datos a tratar,
cualquier cambio que se
realice sobre ellos quedará reflejado
automáticamente en cualquier lugar donde estos datos
aparezcan.
Estabilidad. Dado que permite un tratamiento
diferenciado de aquellos objetos que permanecen constantes en el
tiempo sobre
aquellos que cambian con frecuencia permite aislar las partes del
programa que permanecen inalterables en el tiempo.
Reusabilidad. La noción de objeto permite
que programas que
traten las mismas estructuras de
información reutilicen las definiciones de objetos
empleadas en otros programas e
incluso los procedimientos que los manipulan. De esta forma, el
desarrollo de un programa puede llegar a ser una simple
combinación de objetos ya definidos donde estos
están relacionados de una manera particular.
Uno de los puntos clave a remarcar en esta introducción es que la programación
orientada a objetos no sustituye a ninguna metodología ni lenguaje de
programación anterior. Todos los programas que se
realizan según OOD se pueden realizar igualmente mediante
programación estructurada. Su uso en la actualidad se
justifica porque el desarrollo de todas las nuevas herramientas
basadas en un interface de usuario gráfico como Windows, OS/2,
x-Windows, etc.
Es mucho más sencillo
Características de los Objetos
Identidad del Objeto
La identidad
expresa que aunque dos objetos sean exactamente iguales en sus
atributos, son distintos entre sí. De esta forma incluso
una serie de Objetos coches, recién fabricados son
distintos los unos de los otros.
La afirmación anterior, aunque parece obvia,
tiene importancia cuando descendemos al nivel de
programación. En este ámbito cada uno de los
objetos tiene un controlador pro el cual se identifica. Este
puede ser una variable, una estructura de datos, una cadena de
caracteres, etc. El controlador será distinto para cada
uno de los objeto, aunque las referencias a éstos sean
uniformes e independientes del contenido, permitiendo crear
agrupaciones de objetos con el mismo tratamiento.
Clasificación
Con la clasificación comienza la verdadera
programación orientada a objetos. Ellos nos obliga a una
abstracción del concepto de
objeto denominada clase.
Las clases permiten la agrupación de objetos que
comparten las mismas propiedades y comportamiento. Si bien clase y objeto suelen
usarse como sinónimos, no lo son.
El esfuerzo del programador ante una aplicación
orientada a objetos se centra en la identificación de las
clases, sus atributos y operaciones
asociadas
Las propiedades de cada clase deben cumplir una serie de
premisas
Las propiedades deber ser significativas dentro del
entorno de la aplicación es decir, deben servir para
identificar claramente y de una manera única (y univoca) a
cada uno de los objetos
El número de propiedades de un objeto debe ser el
mínimo para realizar todas las operaciones que requiera la
aplicación.
Definamos una clase rectángulo. Esta clase puede
tener como atributos un punto (x,y), la anchura (a) y la longitud
(l). Las operaciones a realizar son: mover, agrandar, reducir,
et. ¿Es posible realizarlas con las propiedades de la
clase?
Un análisis posterior nos indica que es posible
la realización de estas operaciones con los atributos
definidos. Pero si incluimos la operación girar , vemos
que con las propiedades definidas para la clase esta
operación no se puede realizar. Para incluir esta nueva
operación debemos redefinir las propiedades del objeto, en
este caso las coordenadas de los vértices.
Encapsulación y ocultación de
datos
La capacidad de presentación de
información dentro de un objeto se divide en dos partes
bien diferenciadas:
Interna: La información que necesita el
objeto para operar y que es innecesaria para los demás
objetos de la aplicación. Estos atributos se denominada
privados y tienen como marco de aplicación
únicamente a las operaciones asociadas al
objeto.
Externa La que necesitan el resto de los objetos
para interactuar con el objeto que definimos . Estas propiedades
se denominan públicas y corresponde a la
información que necesitan conocer los restantes objetos de
la aplicación respecto del objeto definido para poder
operar.
Podemos imaginarla encapsulación como introducir
el objeto dentro de una caja negra donde existen dos ranuras
denominadas entrada y salida. Si introducimos datos por la
entrada automáticamente obtendrá un resultado en la
salida. No necesita conocer ningún detalle del
funcionamiento interno de la caja.
El término encapsulación indica l
capacidad que tienen los objetos de construir una cápsula
a su alrededor, ocultando la información que contienen
(aquélla que es necesaria para su funcionamiento interno,
pero innecesaria para los demás objetos) a las otras
clases que componen la aplicación.
Aunque a primera vista la encapsulación puede
parecer superflua, tengamos en cuenta que existen muchas variables
utilizadas de forma temporal: contadores y variables que
contienen resultados intermedios, etc. D no ser por la
encapsulación estas variables ocuparían memoria y
podrían interferir en el funcionamiento del resto de los
objetos.
La encapsulación no es exclusiva de los lenguajes
de programación orientados a objetos. Aparece en los
lenguajes basados en procedimientos (PASCAL, C,
COBOL, ETC)
como una forma de proteger los datos que se manipulan dentro de
las funciones.
Los lenguajes OOP incorporan la posibilidad de
encapsular también las estructuras de datos que sirven
como base a las funciones. Aportan por tanto un nivel superior en
cuanto a protección de información.
La encapsulación nos permite el uso de
librerías de objetos para el desarrollo de nuestros
programas. Recordemos que las librerías son definiciones
de objetos de propósito general que se incorporan a los
programas. Al ser el objeto parcialmente independiente en su
funcionamiento del programa en donde está definido, ya que
contiene y define todo lo que necesita para poder
funcionar, es fácil utilizarlo en los mas variados tipos
de aplicaciones. Si aseguramos , depurando las propiedades y las
operaciones dentro de la clase que el objeto función
bien dentro de una aplicación, con una correcta
encapsulación el objeto podrá funcionar en
cualquier otra.
Otra de las ventajas de la encapsulación es que ,
al definir el objeto como una caja negra con entradas y salida
asociadas, en cualquier momento podemos cambiar el contenido de
las operaciones del objeto, de manera que no afecte al
funcionamiento general del programa.
La encapsulación está en el núcleo
de dos grandes pilares de la construcción de sistemas;
mantenibilidad y reusabilidad.
Mantenibilidad
Cualidad que indica que un programa o sistema debe ser
fácilmente modificable. Es decir que los cambios en las
condiciones externas (como la definición de una nueva
variable) implicarán modificaciones pequeñas en el
programa / sistema. El
concepto de
mantenibilidad implica que un programa, al igual que un ser vivo
debe ser capaz de adaptarse a un medio ambiente
siempre cambiante.
Reusabilidad
Cualidad que nos indica que partes del programa ( en
este caso objetos) pueden ser reutilizados en la
confección de otros programas. Ello implica que los
objetos definidos en un programa pueden ser extraídos del
mismo e implantados en otro sin tener que realizar modificaciones
importantes en el código
del objeto. El objeto final es que el programador construya una
librería de objetos que le permita realizar programas
basándose en la técnica de cortar y pegar. Esta
extrae (corta) código de otras aplicaciones ya realizadas
y las implementa (pega) en la aplicación a realizar donde,
tras algunos retoques, la nueva aplicación estará
lista para funcionar. Como podrá observar el concepto de
reusabilidad, permite reducir el tiempo de realización ,
ganando en claridad, mantenibilidad y productividad.
La encapsulación de datos se muestra como una
herramienta poderosa que nos permite ganar en tiempo de
desarrollo y claridad, con el único coste adicional de
definir con precisión las entradas y salida de nuestras
operaciones.
Poliformismo
El polimorfismo es una nueva característica aportada por la OOP. Esta
propiedad
indica la posibilidad de definir varias operaciones con el mismo
nombre, diferenciándolas únicamente en los
parámetros de entrada. Dependiendo del objeto que se
introduzca como parámetro de entrada, se elegirá
automáticamente cual de las operaciones se va a
realizar.
Ya está habituado al operador
<<suma>> que está presente en todos los
lenguajes de programación. Sin embargo, los operadores
<<suma de fracciones>> y <<suma de
números complejos>> no existen en casi
ningún lenguaje de
programación.
Los lenguajes OOP permiten definir un operador
<<suma>> tal que reconozca que tipo de objeto
se le está aplicando, a través de operaciones de
objetos. Previamente deberá definir la fracción y
el número complejo como una clase y la operación
suma como una operación de una clase.
Definiendo adecuadamente las operaciones suma de
fracciones y suma de números imaginarios, el
operador suma devolverá, en el caso que los operandos sean
fracciones, una fracción y , en el caso de los
números imaginarios, otros número
imaginario.
Es posible extender el concepto e incluso definir
operaciones como suma de bases de datos
El operador suma de base de datos.
Aunque a primera vista la expresión C= A+B, siendo A y B
bases de
datos, nos pudiera parecer una extraordinaria
simplificación, nos conduce a la pregunta:
¿Qué es la suma de una base d datos?
Consideremos varias posibilidades:
Introducción de registros: Lo que
exige que A y B tengan la misma estructura.
Unión de campos: Aquellos campos que aparezcan en
B pero no en A serán añadidos a C
¿Alguna de estas dos opciones es verdaderamente
una suma? Es decir ¿Cumple las propiedades conmutativa,
asociativa, de elemento neutro, etc.? ¿Qué ocurre
si sumo dos bases de datos
con estructuras distintas?
Como puede observar, la definición de un operador
sobre un tipo complejo de datos, intentando utilizar
identificadores de operadores de datos simples, puede tener
resultados impredecibles.
Una de las ventajas más importantes, sin entrar
en la redefinición de operadores es permitir la
realización de las clases que definen un programa de forma
totalmente independiente al programa donde se utilizan. Gracias a
la encapsulación y el polimorfismo, aunque se utilicen los
mismos nombre con las operaciones en dos clases distintas, el
programa reconoce a que clase se aplica durante la
ejecución.
Como se podrá observar el polimorfismo y la
encapsulación de datos están íntimamente
ligados y nos permiten un mayor grado de mantenibilidad y
reusabilidad que los lenguajes tradicionales Esta ese
precisamente una de las causas de la revolución
que ha supuesto la introducción de los lenguajes orientados a
objetos dentro de la programación.
Herencia
La herencia es la
última de las propiedades relativas a la OOP, Consiste en
la propagación de los atributos y las operaciones a
través de distintas sub-clases definidas a partir de una
clase común.
Introduce, por tanto, una posibilidad de refinamiento
sucesivo del concepto de clase. Nos permite definir una clase
principal y , a través de sucesivas aproximaciones,
cualquier característica de los objetos. A partir de
ahora definiremos como sub-clases todas aquellas clases obtenidas
mediante refinamiento de una (o varias) clases
principales.
La herencia nos
permite crear estructuras jerárquicas de clases donde es
posible la creación de sub-clases que incluyan nuevas
propiedades y atributos. Estas sub-clases admiten la
definición de nuevos atributos, así como crear,
modificar o inhabilitar propiedades.
Para pensarlo de manera más fácil podemos
abstraernos al siguiente ejemplo.
Pensemos en los distintos sub-modelo s
asociados a un modelo
básico de automóvil. A partir de este modelo
básico, los fabricantes introducen distintas
características (aire
acondicionado, ABS, distintas tapicerías , acabados,
etc.) que crean sub – clases. Todas estas sub-clases tienen
en común la estructura básica (chasis , dirección , etc.) u varían
sólo en algunos de sus componentes.
Asociemos a este tipo básico una clase cuyos
atributos representen las piezas que componen el coche. Las
sub-clases aportarán sus propios atributos (en el caso de
vehículos con aire
acondicionado, todos aquellas piezas que lo componen),
permitiendo la definición de todos los posibles modelos.
Además, es posible que una sub-clase herede
atributos y propiedades de más de una clase. Este proceso se
denomina herencia múltiple y lo veremos con más
detalle en capítulos posteriores.
La herencia es, sin duda alguna, una de las propiedades
más importantes de la OOP, ya que permite, a través
de la definición de una clase básica, ir
añadiendo propiedades a medida que sean necesarias y,
además, en el sub-conjunto de objetos que sea
preciso.
La herencia permite que los objetos pueden compartir
datos y comportamientos a través de las diferentes
sub-clases, sin incurrir en redundancia. Más importante
que el ahorro de
código, es la claridad que aporta al identificar que las
distintas operaciones sobre los objetos son en realidad una misma
cosa.
Conclusión.
Identidad, clasificación, polimorfismo y herencia
caracterizan a los lenguajes orientados a objetos. Cada uno de
estos conceptos puede utilizarse aisladamente, incluso aparecen
en otras metodologías de programación, pero juntos
se complementan en una relación sinérgica. Los
beneficios de la programación orientada a objetos son
más que los que pueden verse a simple vista. El
énfasis en las propiedades esenciales de un objeto,
fuerza al
desarrollador a pensar cuidadosamente que es un objeto y que es
lo que hace con el resultado de que el sistema es normalmente
más preciso, general y robusto que si pusiéramos el
énfasis en los procedimientos y los datos por
separado
Construcción de clases
Tal como hemos definido con anterioridad, una clase de
objeto describe a un grupo de
objetos con similares:
- Propiedades (atributos)
- Comportamientos (operaciones)
- Relaciones con otros objetos
La abreviatura clase es utilizada en lugar de clase de
objetos. Los objetos difieren en los valores
asociados a sus atributos definidos dentro de la clase. Cada
objeto <<conoce>> cuál es su clase. La
mayoría de los lenguajes orientados a objetos pueden
determinar a que clase pertenece un objeto durante la
ejecución del programa.
A continuación expondremos una serie de pasos
para definir una clase.
Identificar los objetos.
Para ello examine la aplicación e identifique las
distintas estructuras de datos, algunos tips a tener en cuenta
son los siguientes:
- El nombre de la aplicación a veces nos da la
del nombre del objeto principal - Los objetos software pueden imitar el mundo real,
modelizando las propiedades de los objetos a través de
variables Cualquier propiedad de
un objeto puede ser identificada dentro del objeto
correspondiente a través de variables. - Los objetos no se han de corresponder siempre con
objetos físicos, sino que también pueden ser
entidades que se utilizan dentro de la construcción del programa. - Piense en el objeto en <<primera persona>>. Este truco nos puede
identificar claramente los atributos y sus operaciones
asociadas: <<Soy un cuadrado y me muevo, giro, agrando y
reduzco. Las partes que me componen son los puntos de mis
vértices>>. - Una clase es un tipo de dato que puede ser usado para
declarar objetos, de la misma forma que una estructura es un
tipo definido por el usuario que puede utilizarse para declarar
variables.
Definir las operaciones
Defina las operaciones a partir de los objetos,
examinando las distintas operaciones asociadas a un conjunto de
datos. Los atributos del objeto se deben definir de tal manera
que éstos satisfagan todos los requerimientos de cada una
de las operaciones.
A estas operaciones añada dos más: Crear y
Destruir. Estas operaciones nos servirán para inicializar
y borrar el objeto dentro de la aplicación.
A partir de la definición de las propiedades, un
objeto siempre debe ser capaz de responder a estas tres
preguntas: ¿Qué soy ?, ¿Qué hago?
¿Qué dejo ver al resto del mundo?
Algunas de las operaciones sólo se
aplicarán a determinados objetos pertenecientes a las
clases. Hemos visto que a través de la herencia podemos
<<especializar>> un sub conjunto de objetos creando
una sub-clase.
Únicamente aquellas operaciones que sean comunes
a todos los objetos de la clase deben incluirse dentro de las
operaciones de la clase. El resto, que corresponden a las
operaciones de sub-Grupos de
objetos, se deben definir dentro de la especializaciones de la
clase.
Definir los atributos de los
objetos
Una vez identificados los objetos, defina los atributos
de la clase. Un atributo es un valor
almacenado en los objetos de la clase.
Aplicaciones
orientadas a objetos
A lo largo de la historia de la
programación, los lenguajes y las metodologías han
pasado de una relativa simplicidad a una complejidad creciente.
Los lenguajes de programación orientados a objetos
pretenden aportar simplicidad a la tarea de programación
de grandes aplicaciones.
Cuando se crearon las primeras computadoras
todavía no existían los lenguajes de
programación, tal como ahora los entendemos. El lenguaje
ensamblador puede considerarse como el primer lenguaje de
programación propiamente dicho. Permitía al usuario
un diálogo
más fluido con la máquina a través de
instrucciones que tenían relación directa con el
conjunto de operaciones que la máquina podía
realizar.
A partir de este momento empezó la evolución de los lenguajes de
programación. _cada uno tenía su entorno definido y
aunque en realidad todos los lenguajes son polivalentes (en
teoría,
con cualquiera de ellos se puede desarrollar cualquier programa
de gestión
o científico). Pronto apareció la
especialización funcional. Así, COBOL (Common
Business Orientated Language) se introdujo como lenguaje
mainframe para el diseño de aplicaciones de gestión.; FORTRAN (Formula Translator) para
el diseño de aplicaciones científicas; APL (A
Programming Language) para el cálculo
matemático, etc.
A medida que el software tomaba importancia, aparecieron
los primeros problemas
relacionados con la programación. Al tiempo que aumenta el
volumen de un
programa, disminuye el control del mismo
por parte del programador y la capacidad de este de dar mantenimiento.
En un intento de solucionar estos problemas
aparecen las metodologías de programación. Una
metodología es un conjunto de reglas destinadas a
simplificar las tareas de diseño, estimación de
costes, desarrollo y mantenimiento
de un sistema informático. A menudo se ven
acompañadas con unas herramientas
(CASE: Computer Aided Software Engeneering) que permiten la
elaboración estructurada y documentada de los sistemas
informáticos.
DISEÑO DE APLICACIONES Y
ELECCIÓN DE ENTORNO.
En entorno de programación implica tanto el lenguaje de
programación como al empleo de una
determinada metodología.
Los lenguajes de programación no se producen por
generación espontánea y se ven influidos en gran
manera por la forma en la que los profesionales piensan que se
debe programar. De esta manera se crea un conjunto de reglas para
simplificar la tarea de programación. Generalizadas y
codificadas, se convierten en <<principios>> de los que surgen los lenguajes
de programación en un afán por darles
soporte.
Estos <<principios>> son modelos que
proporcionan técnicas
que , a su vez, deben aplicarse en el diseño e
implementación de los programas. Estas técnicas
nos indican la forma de resolver los distintos problemas que
surgen a la hora de programar.
Decimos que un lenguaje de programación
<<soporta>> un conjunto de <<principios>>
si el lenguaje
simplifica la aplicación de estas técnicas. A estos
<<principios>> se les denomina metodologías de
programación.
Las metodologías de programación son
modelos sobre como diseñar e implementar los programas.
Diferentes modelos tienen como resultado diferentes
técnicas. Que cada técnica sea distinta no implica
que una sea la verdadera y que las demás falsas. Por el
contrario, las metodologías se complementan entre
sí. Lo que todas las metodologías tienen en
común es la premisa de que hay que partir de abstracciones
que corresponden a elementos del problema a resolver, y que la
implementación de la solución se debe realizar
mediante un conjunto de módulos preferiblemente
reutilizables.
Las metodologías orientadas a objetos se centran
en las estructuras de datos que sin embargo se relegan a un
segundo plano en los modelos procedurales. La base de esta
metodología es que una estructura de datos debe contener
las operaciones que los modifican. La técnica que se
utiliza para obtener esta <<abstracción de
datos>> es la encapsulación de los mismos en una
estructura conocida como clase.
El accesos a los datos contenidos en la clase se realiza
mediante las operaciones que la propia clase define. Por tanto,
la metodología orientada a objetos complementa el punto de
vista procedural de operaciones realizadas sobre un flujo de
datos, al asociar a cada dato el conjunto de operaciones que lo
modifican. Como podrá ver, ambos enfoques son
complementarios.
Para ilustrar las diferencias entre las aproximaciones
orientadas a procedimientos y las orientadas a objetos, considere
el diseño de un <<compilador>>
El compilador es un programa que a partir de un conjunto
de fichero fuente (programa) construye el código objeto
que posteriormente se convierte en programa. Para realizar su
trabajo, el compilador lee el fichero fuente y separa de
él las variables y las instrucciones. Las variables
constituyen la tabla de símbolos del programa, mientras
que las instrucciones se organizan en un árbol
sintáctico donde se plasman todas la referencias que
realizan los mandatos y funciones entre sí.
El modelo mejor establecido es el basado en funciones
(procedural) que trata de la construcción de un
programa como una colección de funciones. Las
metodologías proporcionan una gruía sobre
cómo diseñar, organizar e implementar las funciones
que componen un programa. El método de
diseño es la descomposición funcional que
identifica las funciones como los pasos a seguir en la
resolución de un problema. La
organización en archivos permite
que las funciones se agrupen módulos separados, mientras
que las técnicas de programación estructurada
permiten que las implementaciones de las funciones sean
fáciles de consultar y mantener.
La programación orientada a objetos está
basada en un modelo de construcciones de programas como un
conjunto de clases. El diseño orientado a objetos
identifica los tipos que representan los distintos objetos en el
programa. Las operaciones a realizar con cada uno delos objetos
son, al igual que en el modelo procedural, los pasos destinados a
solucionar el problema. El objeto sirve además de
módulo que puede reutilizarse para la solución de
un problema de similares características en otro
programa.
Ninguna metodología resuelve con acierto todos
los tipos de problemas. La programación requiere una
especialización como la que se produce en la ingeniería pero todavía no es
posible identificarla como una ciencia. Las
técnicas a emplear se han de utilizar con exquisito
cuidado, sin perder de vista el objetivo de
resolver un determinado problema.
Actualmente existe la tendencia de identificar la
programación con una disciplina
como la ingeniería. Sin embargo, debe considerarse
más como un arte como la
arquitectura,
donde se unen la inspiración y el dominio de la
técnica.
Para la elección de un determinado entorno
debemos fijar los criterios necesarios, como los que describimos
a continuación.:
Tamaño de la
aplicación
Cuanto mayor sea el volumen de
información a procesar, mas necesidad habrá de
estructurar dicha información de forma que se fácil
su manipulación.
Complejidad
Podemos dividir el problema de la complejidad en dos
grandes apartados.
Datos: La complejidad viene reflejada por el tipo de
datos a tratar, por las relaciones que puedan tener los datos
entre si, etc.
Funciones: El método
para la obtención de nuevos datos es complicado o requiere
un esfuerzo de programación importante.
Aunque tratados como
grupos
independientes, ambos están generalmente
interrelacionados. De esta forma una estructura de datos compleja
suele ir acompañada de un conjunto de funciones de
diseño complejo.
Asimismo, una mayor abstracción se traduce en
unas instrucciones mas potentes y un soporte de estructuras de
datos más complejas. Esto a menudo se traduce en que el
compilador (programa que traduce el programa introducido por el
usuario en código ejecutable por la máquina) ha de
introducir una cantidad grande de código auxiliar para
poder ejecutar el código fuente.
Si ha programado en C o en Turbo Pascal,
habrá observado que los ejecutables son en general de
pequeño tamaño. Un simple programa <<Hola
mundo>>, clásico de programación. Nunca es
mayor de seis líneas de código y su ejecutable es
siempre inferior a 10 Kbytes. Si tomamos Clipper el programa no
ocupa más de una línea pero más de 200
Kbytes.
Rapidez
En algunos problemas la rapidez de respuesta es
crítica. Este factor depende mucho de soporte hardware y lentamente va
asumiendo menos importancia.
Portabilidad
La portabilidad es la capacidad que ha de tener el
programa para funcionar en distintos entornos operativos. La
realización de un programa portable , en general, depende
de la elección de un lenguaje de programación ,
así como del alejamiento de las ventajas e inconvenientes
que proporciona el soporte hardware y el sistema
operativo. La creación de un programa portable a
menudo incide negativamente en los apartados de tamaño y
rapidez, ya que un alejamiento de la plataforma hardware y del
sistema
operativo, a menudo se consigue emulando sus
características. Esto conlleva un aumento del
tamaño y la complejidad del programa, así como un
incremento en el tiempo de ejecución.
Gestión de recursos
Este factor indica las exigencias que hace nuestro
lenguaje de los recursos
disponibles por el ordenado. El más limitado, aun
más que el espacio en disco, es la memoria. Un
programa grande que gestione de manera incorrecta la memoria
pronto agotará todos los recursos del
sistema.
Interface de usuario.
Aunque no se puede contar como un factor a considerar,
la importancia que el interface de usuario está tomando en
los últimos años hace que lo consideremos por
separado. El diseño del interface de usuario aporta una
complejidad propia al desarrollo de aplicaciones. De hecho, se
considera que en un principio este apartado ocupaba apenas entre
el 10 y el 30 por ciento del esfuerzo de programación,
para llegar a absorber entre el 50 y 70 por ciento de dicho
esfuerzo en la actualidad.
La aparición de interfaces gráficos de usuario estándar
(Windows, os2, X-Windows, etc.) ha hecho que factores como la
rapidez o el tamaño vuelvan a tomarse en cuenta,
después de que el consumo de
recursos de la parte del interface de usuario creciera de forma
espectacular.
APLICACIONES ORIENTADAS A OBJETOS
Cómo afectan los requerimientos anteriores para
la elección de un lenguaje orientado a objetos como
herramienta para el desarrollo de nuestros programas?
Claridad
Al ligar de forma evidente la estructura de la
información con los procedimientos que la manipulan, los
programas ganan en claridad a la hora de desarrollarlos y
mantenerlos. Esto supone una ventaja frente a los lenguajes
procedurales , aunque éstos podrían suplir esta
deficiencia mediante una correcta elección de los nombres
de las variables y funciones, lo que se denomina una
<<oportuna codificación>>.
Complejidad
Cuando la complejidad de un problema es abarcable por
una sola persona,
resolverlo con una herramienta u otra no aporta grandes ventajas.
Pero cuando este desarrollo la tiene que realizar un equipo
grande, debe existir una forma para aislar partes de
problema.
Uno de los problemas más comunes , y a su vez
más simples de solucionar en el diseño de grandes
sistemas, es el nombre que se da a las funciones y que tipo de
datos manipulan éstas.
En la realización de un sistema
informático se utiliza un equipo de varias personas.
El trabajo se
divide en tres áreas funcionales: una parte del equipo se
encarga del interface de usuario, otra de la manipulación
de datos y, la última del diseño de salidas
impresas.
Cada quipo utiliza funciones y datos suministrados por
los otros miembros del equipo y a su vez diseña funciones
para su uso interno y para el uso del resto de los grupos. Si no
se realiza la división del trabajo de forma adecuada puede
producirse el caos. He aquí una pequeña
enumeración de los problemas que se pueden
encontrar.
- Las funciones desarrolladas por cada uno de los
grupos no encajan con las necesidades de los
demás. - Otros grupos han elegido nombres de variables y
funciones similares a los elegidos por nuestro grupo. Estas
funciones y variables son prácticamente iguales a las
desarrolladas por nosotros, pero varían ligeramente en
el tratamiento de la información, por lo que no podemos
sustituir nuestras funciones. Ambas deben coexistir aumentando
la complejidad del programa de manera innecesaria. - El resto de los grupos sólo cubren
determinados aspectos de la información a tratar, pero
no proporcionan toda la información necesaria para que
el programa funcione. El resto de información debe
suministrarse suplantando parte de la funcionalidad destinada a
otros grupos. - Algunas de las modificaciones que realizamos sobre
variables locales o globales producen resultados imprevistos en
el resto de los módulos.
Tamaño
Las aplicaciones orientadas a objetos son ideales para
la realización de programas de gran tamaño. Las
facilidades de encapsulación y asociación de las
funciones a los datos que manipulan, simplifican el proceso de
desarrollo. De hecho las bases de datos orientadas a objetos
suponen un gran adelanto, ya que aúnan la flexibilidad en
la manipulación de los OOP con la capacidad de consulta de
un DBMS (Data Base Management System)
Relación entre Datos
Por el mismo motivo se verán beneficiados
aquellos programas que impliquen una relación compleja
entre los datos. Este tipo de complejidad permite la
utilización de todas las ventajas de los lenguajes de
programación orientados a objetos. Propiedades como la
herencia ( donde los objetos pueden heredar estructura y
operaciones de objetos predecesores), la encapsulación,
etc. Muestran en este tipo de programas todas sus
ventajas.
Rapidez
En este aspecto, los lenguajes orientados a objetos
muestran una clara desventaja frente a otros lenguajes que se
acercan más a las especificaciones de la máquina.
Si la rapidez es crítica, puede elegir un lenguaje de
programación como C++, que aporta toda la funcionalidad de
los lenguajes orientados a objetos con la rapidez y la
compatibilidad de C.
Gestión de recursos
Las aplicaciones orientadas a objetos demandan
normalmente más recursos del sistema que las aplicaciones
procedurales. La creación dinámica de objetos, que ocupa un lugar en
la memoria del
ordenador, puede acarrear graves problemas. Una de las soluciones,
que incluye alguno delos lenguajes OOP, es liberar a menudo el
espacio que los objetos dejan de utilizar. Este procedimiento de
optimización como garbage collection (recolección
de basura,
implementado en java), minimiza
los efecto de la creación dinámica de objetos.
Interface de usuario.
El interface de usuario es uno de los aspectos
más importantes en la programación actual. La
aparición de sistemas de explotación que soportan
un interface gráfico de usuario como Windows, X-Windows o
Presentation Manager hace que la mayoría de los usuarios
prefieran que sus programas corran bajo este tipo de interface.
Este es uno de los puntos fuertes para la elección de un
lenguaje OOP. La mayoría de los interfaces gráficos actuales han sido diseñados
o rediseñados en base a la OOP. Existen en el mercado
librerías de clases que soportan todos los dispositivos de
control de
ventanas como menús, combo box, listas, barras de
herramientas, etc.
Lenguajes orientados a objetos
Los lenguajes OOP implementan de manera distinta los
conceptos de programación orientada a objetos. No existe
el lenguaje perfecto capaz de satisfacer todas las necesidades y
que se adapte a todos los estilos
A Continuación unos consejos que nos
facilitarán la elección del lenguaje de
programación adecuado:
- Si los programas se van a sentar en una cualidad
concreta de los OOP como herencia, elija el que mejor soporte
le dé. - Los lenguajes interpretados sirven para realizar un
desarrollo rápido o para aquellos programas que
necesiten una actualización constante. Si el programa
necesita rapidez o es crítico respecto al tamaño,
considere el uso de lenguajes que incorporen
compilador. - No <<reinvente la rueda>>. Si el lenguaje
le proporciona una librería de clases no intente
reescribrlas de nuevo, use las que le ofrece el sistema. Es
más tome como factor de elección las
librerías de clases que el compilador incorpora o que
estén disponibles en el mercado. - Si necesita mejorar la calidad del
programa previniendo errores, utilice un lenguaje que le
permita definir las variables con sus tipos
asociados. - Si la memoria del sistema es limitada, utilice
lenguajes que permitan la creación y destrucción
automática de clases dependiendo de su
utilización.
CARACTERÍSTICAS DE LOS LENGUAJES
OOP
Herencia múltiple
Esta característica suele ser común a la
mayoría de los lenguajes OOP, aunque introduce un problema
al existir la posibilidad de que el objeto sucesor herede el
mismo atributo, aunque con distinto tipo y valor, de mas
de un predecesor. Alguno de los lenguajes de programación
solucionan este problema de forma automática, aunque los
más populares generan un error en el tiempo de
compilación. Recomendamos que se examinen con cuidado las
clases para evitar en lo posible estos errores.
Eficiencia.
Los lenguajes OOP arrastraron en un principio la
reputación de ser ineficaces. Esto se debía en gran
medida a que los primeros lenguajes (como Smalltalk) eran
interpretados y no compilados. La existencia de compiladores
permite a los desarrolladores ganar rapidez. Actualmente, usando
un buen lenguaje orientado a objetos como C++, Java, etc. Junto
con las librerías apropiadas para la realización de
un programa, puede que se ejecute más rápidamente
que el mismo programa compilado con un lenguaje
procedural.
Asignación de tipos.
Los lenguajes orientados a objetos varían de
forma sustancial la forma por la que se aproximan a la
asignación de tipos.
Por asignación de tipos entendemos que cada
variable sea identificada como perteneciente a una clase
(asignación fuerte) o sea simplemente un objeto
indeterminado (asignación débil). Eiffel y C son
dos lenguajes basados en la asignación fuerte, frente a
Smalltalk, en el que todas las variables definidas pertenecen a
una clase indeterminada.
La asignación fuerte sirve a dos
propósitos. Por una parte para que el desarrollador pueda
identificar a que clase pertenece cada operación. De forma
concreta, en aquellos lenguajes donde está implementado el
operator overloading (refefinición de operador), el
compilador puede reconocer a través de las clases que
entran como parámetros en la operación que
operación tiene que utilizar.
Por otra, este tipo de declaración permite al
compilador un mayor grado de optimización, ya que conoce
en todo momento el espacio que ha de asignar.
Manejo de memoria.
Los OOP son lenguajes que utilizan de manera intensiva
la memoria de la
computadora.
Hay dos tipos de aproximación a la gestión
de memoria.
El sistema en tiempo de ejecución libera la
memoria automáticamente a medida que los objetos dejan de
utilizarse.
El sistema tiene instrucciones concretas para liberar l
memoria explícitamente. Este el enfoque adoptado por
lenguajes como C++, que aportan dos operadores: crear y destruir.
El primero reserva automáticamente memoria, mientras que
el segundo la libera.
Encapsulación
Consiste en separar aquellos atributos del objeto que
deben ser conocidos por el resto, de aquellos necesario para su
funcionamiento propio. No es propio de los lenguajes orientados a
objetos, pero la capacidad de éstos para unir las
estructuras de datos a los procedimientos que los modifican lo
hacen más potente que los lenguajes llamados
<<Modulares>>
PANORAMICA DE LOS
LENGUAJES OOP
A continuación, una pequeña
panorámica de los lenguajes orientados a
objetos
SMALLTALK
Fue el primer lenguaje de programación orientado
a objetos. Desarrollado en el Xerox PARC, en sus primeras
implementaciones no ofrece solamente un interprete, sino que es
mucho más ambicioso, integrando intérprete on-line
y otros aspectos que le convierten en un <<pseudo>>
sistema operativo. Es el primero en aportar la arquitectura de
Modelo/Visor/Controlador. El interface de usuario se divide en
una definición sobre la que se aplican determinado
número de vistas gestionadas por un controlador. El MVC
permite al desarrollador concentrarse en la parte esencial de la
aplicación (el modelo) y añadir interfaces de
usuarios ( las vistas y controles) de forma
independiente.
Ventajas
- Smalltalk es un lenguaje puro orientado a
objetos - La implementación a través de un
intérprete facilita la labor de desarrollo de programas.
Las clases son añadidas, corregidas y depuradas de forma
interactiva. - Tiene una sintaxis simple, donde las variables y los
atributos no necesitan tener un tipo asociado. Todo está
definido en principio como objeto, incluyendo las propias
clases.
Inconvenientes
- Es un lenguaje interpretado, lo que reduce su
rendimiento y dificulta su comercialización. - Al proporcionar su propio entorno operativo,
interactúa mal con otro tipo de software o
hardware
Eiffel
Es un lenguaje de programación escrito por
Bertrand Meyer. Al contrario que Smalltalk, incluye un
preprocesador que permite la traducción de código
Eiffel a Lenguaje C. Es
ideal para la ingeniería de
software, que permite la encapsulación , control de
acceso y ámbito de las modificaciones. Como lenguaje
orientado a objetos <<puro>>, es presumiblemente el
mejor por sus capacidades técnicas.
Los programas consisten en la declaración de
colecciones de clases que incluyen métodos.
El punto primordial de un programa Eiffel es la
declaración de clases, que asocia atributos. Ambos, clases
y atributos, son accesibles a partir de la implementación
de un concepto llamado característica. Una
característica es, por tanto, una agrupación de
datos y unas formas típicas de tratarlos.
En Eiffel una declaración de clases puede
incluir:
- Una lista de características
exportables. - Una lista de las clases antecesora: clases de la que
ésta es una derivación - Una lista de declaraciones de
características.
Ventajas
- Es un lenguaje orientado a objetos
<<puro>> - Eiffel es un lenguaje de programación
orientado hacia el diseño de grandes aplicaciones. Las
propiedades anteriores le hacen ideal para el diseño de
aplicaciones en grupos de trabajo. - El paso intermedio a código C se puede
considerar como una ventaja y no como un inconveniente, ya que
aquellas secciones que sean difíciles de tratar con
Eiffel pueden elaborarse a partir de código C. Su
compatibilidad con C asegura también su portabilidad
hacia otros sistemas operativos
Desventajas
- El manejo de la memoria , un punto delicado en todos
los lenguajes orientados a objetos no es transparente como en
el caso de Smalltalk. - Las librerías de clases son
reducidas - El rendimiento es mayor que el de Smalltalk, pero al
tener que incluir un módulo Run-time dentro del
ejecutable, su tamaño crece y su rendimiento
baja.
C++
Es un lenguaje de uso general que deriva del
C.
Añade a su predecesor una serie de
características que le convierten en un lenguaje orientado
a objetos. Dentro de estas características debemos
resaltar:
- La abstracción de datos
- La programación orientada a objetos, ya que
permite asociar a los datos las funciones que los
manipulan
C++ conserva todas las capacidades de su predecesor C.
De hecho, el código C puede tratarse con compiladores C++
y ejecutarse sin ningún problema. En un principio C++ era
traducido a código C a través de una utilidad llamada
precompilador.
También es cierto que se pueden utilizar algunas
de las ventajas de C++ (como C mejorado) para escribir
código no orientado a objetos.
Enumeramos los aspectos más importantes que hacen
del C++ un lenguaje orientado a objetos:
- La mayor contribución que realiza C++ al C es
la introducción del tipo clase. Las clases permiten
definir conjunto de datos y las funciones que los
manipulan. - La ocultación de datos es el mecanismo para
implementar la abstracción de datos. La
abstracción de datos permite al programador
<<olvidar>> el funcionamiento interno de una clase,
ya que sabe que su funcionamiento no va a alterar
anómalamente el funcionamiento de otras clases. Una vez
definida la clase es transparente para el desarrollador y
permite operar con ella como si fuera un tipo
básico. - La herencia extiende el concepto de
abstracción de datos al permitir la construcción
de clases a partir de otras (sus antecesores) - Los operadores definidos por el usuario permiten un
tratamiento homogéneo entre los tipos predefinidos por
el lenguaje y los desarrollados por el programado.
Otras características no relativas a la
programación orientada a objetos, simplifican el
diseño y desarrollo.
- Optimización de explotación de memorias,
que permite la creación de estructuras de datos
dinámicas. - Implementación del solapamiento de funciones.
Esta técnica permite definir varias funciones con el
mismo nombre pero distintos parámetros de entrada.
Dependiendo de los parámetros que acompañen la
llamada de la función,
será ejecutada una u otra.
BASES DE DATOS
ORIENTADAS A OBJETOS
La programación orientada a objetos es muy
versátil. No se restringe únicamente al
diseño de programas, sino que es posible aplicar los mismo
conceptos al diseño de bases de datos. El uso de una
técnica orientada a objetos trasciende a la
elección de la base de
datos.
El uso de esta técnica en el diseño de
bases de datos aporta las cualidades de esta metodología a
nuestro diseño. Eficiencia,
coherencia y un menor coste a la hora de actualizar la estructura
de las bases de datos son los principales beneficios que
aporta.
Como valor añadido, el uso de una misma
técnica en el diseño, tanto de los programas como
de las bases de datos proporciona coherencia a nuestro
sistema.
Las bases de datos orientadas a objetos unen dos
tecnologías:
La de las bases de datos y la de los lenguajes
orientados a objetos. Los Lenguajes OOP aportan gran capacidad en
la manipulación de datos, pero no implementan el almacenamiento y
consulta de grandes volúmenes de datos.
Por el contrario, las bases de datos convencionales
aportan un dominio de las
técnicas de almacenamiento y
consulta de grandes volúmenes de datos, aunque su
capacidad de manipulación es limitada.
Las bases de datos orientadas a objetos pretenden unir
la capacidad de manipulación de datos de los OPP con la
capacidad de almacenamiento y consulta de los DBMS.
Las aplicaciones convencionales que agrupan programas y
bases de datos, separan ambos entornos de manera
clara.
El desarrollador usa técnicas procedurales para
la descomposición de problemas y su codificación en
funciones. Posteriormente se emplean técnicas como las de
Entidad – Relación para el diseño de la base
de datos.
Su codificación suele realizarse en un lenguaje
de alto nivel como C, que lleva embebido código SQL. El
término embebido describe la inclusión de un
módulo escrito bajo otro lenguaje de programación
dentro del código fuente. El compilador incorpora durante
la fase de enlace el Run-Time correspondiente para que pueda
funcionar el código embebido.
Como podrá observar, esta técnica presenta
defectos evidentes:
Por una parte, se utilizan diferentes técnicas
para el desarrollo de ambos apartados, por lo que la tarea de
diseño no se puede considerara como un todo
único
Por otra y en gran medida debida a la primera, los
lenguajes que se utilizan para la implementación difieren,
dificultando las labores de mantenimiento.
Ejemplos
Como habrá podido observar a lo largo de esta
monografía, nuestro propósito no ha
siso el de enseñar una metodología ni la enseñanza de un determinado lenguaje de
programación.
El objetivo es
por el contrario dar una panorámica de los conceptos de la
programación orientada a objetos, de las
metodologías y de las técnicas de desarrollo de
aplicaciones.
En este apartado nos centraremos en lo aspectos
más importantes en el desarrollo de aplicaciones bajo OOP:
identificación de objetos y análisis de
asociaciones.
La parte más importante de todo diseño es
el punto de entrada de la definición de requerimientos. En
la observación atenta de los requerimientos se
pueden hallar la mayoría de los objetos pertenecientes a
nuestra aplicación.
En este ejemplo nos centraremos en la
identificación de objetos a partir de los requerimientos
básicos de la aplicación.
Este análisis es el primero que debe hacerse
dentro de OOP y es también útil para cualquier otra
técnica de programación.
Analicemos la siguiente definición de
requerimientos:
El <<sistema de tratamiento de información
documental>> es un gestor de <<documentos>>, de tal manera que puedan
clasificar en uno o varios <<índices>>,
recuperar para su modificación, visualizar, para su
consulta, reclasificar, archivar y destruir. El
<<sistema>> procesa la petición del
<<usuario>>, devolviendo un mensaje e indicando el
éxito o
el fracaso de la petición.
De una manera general hemos indicado entre comillas los
sustantivos y en cursiva los verbos. De esta forma hemos
identificado los objetos principales de la aplicación y
las operaciones asociadas a cada uno de los objetos.
Observe el siguiente diagrama.
Hemos traducido los requerimientos a un conjunto de
objetos.
Estos están inconexos entre sí, pero
aplicando la <<lógica>> podemos ver las relaciones
que existen entre ellos. Sin salirnos de las especificaciones de
la aplicación, vemos que existen las asociaciones que
aparecen en la siguiente figura:
Como podemos observar, algunas asociaciones
cíclicas como Indice <-> Documento. Estas
asociaciones pueden simplificarse. También existen otras
implícitas que examinaremos más adelante, como
Usuario->Documento->Indice.
Observemos gráficamente las asociaciones que
mantienen los objetos entre sí en la siguiente
figura
Como puede verse hay dos asociaciones sospechosas, ya
que no son verbos sino los sustantivos
<<petición>> y <<mensaje>>. Estas
dos asociaciones se pueden <<objetivar>> de tal
manera que reúnan las condiciones de un objeto. Para ello
debemos volver a las especificaciones iniciales.
Cuando se archiva un documento se debe indicar el nombre
del documento así como los índices a los que se va
a asociar. Las peticiones de recuperación deben incluir un
índice y el nombre del archivo. Las
consultas a los índices deben incluir el nombre del indice
y una condición.
A partir de este análisis se puede depurar con
HERENCIA y posteriormente realizar un <<ajuste
fino>>
A continuación vamos a centrarnos en la
relación de herencia.
Como ya sabemos ésta puede agrupar objeto son
similares característica o bien especializar objetos a
partir de una genérico. Observemos nuevamente los
requerimientos de nuestro sistema:
Principles of Component Design 1518A Microsoft
Autorized academic trining program
Fundamentos del diseño y la programación
orientada a objetos Sergio M Fernández Sastre, editorial
McGraw Hill
Ingeniería de software, Sommerville I, editorial
Addison-Wesley
Object-Oriented Programming, Coad P . Editorial Yourdon
Press.
Apuntes de cátedra Programación 3 lenguae
C++ Universidad
Nacional de la Matanza.
Autor:
Tejerina Martín