Sei sulla pagina 1di 20

Orientación a objetos: Conceptos y terminología

ORIENTACIÓN A OBJETOS: CONCEPTOS Y TERMINOLOGÍA (PARTE 1)

Miguel Ángel Abián

Copyright (c) 2003, Miguel Ángel Abián. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en http://www.javahispano.org/licencias/).

Abstract: This paper, divided in two parts, provides an introduction to Object-Oriented (OO) terminology and its concepts. It introduces terms and core concepts to Object- Orientation from a conceptual point of view, giving formal, intuitive and manageable definitions. There is also a comparison with the structured paradigm.

Keywords: Object Oriented Terminology, Object Oriented Programming, Object Orientation, Classes, Objects, Software Analysis, Software Design, Learning Object Orientation, Object Orientation Paradigm, Structured Paradigm

“Los objetos en el sentido de la OO han estado presentes entre nosotros desde que se desarrolló la conciencia en la especie humana, pero se han

tardado miles de años en aprovecharlos como técnica. ¿Cuánto tiempo más se necesitará para extraer el

Quizá necesitemos

un cambio conceptual antes que una sucesión frenética de cambios técnicos.”

Howard Humphrey, 2002

máximo rendimiento de la OO? [

]

“Cualquier programador lo suficientemente persistente y empecinado conseguirá escribir código al estilo Fortran ó Cobol en cualquier lenguaje de programación que utilice.” Anónimo. Oído en la Universidad de Valencia

1. Introducción. El porqué de este artículo.

El propósito de este artículo, que se presenta dividido en dos partes, es realizar una introducción a la orientación a objetos (OO), incluyendo sus conceptos y terminología. No se pretende dar únicamente definiciones formales de los conceptos, sino también presentarlos de una forma fácilmente inteligible e intuitiva, pero no exenta de precisión. El lector juzgará si se ha conseguido. En la primera parte se exponen, de manera introductoria, los fundamentos de la OO, su comparación con la metodología estructurada, los motivos de su éxito y en la segunda se expondrán en detalle los conceptos básicos de la misma (objetos, clases, etc.).

Deliberadamente, el artículo está centrado en conceptos y definiciones de la OO, y no en su aplicación a lenguajes de programación concretos, por los siguientes motivos:

1

http://www.javahispano.org

- El

necesariamente a sistemas de software o de información.

análisis

y

diseño

orientado

a

objetos

no

tiene

por

qué

estar

ligado

- En sistemas de software la orientación a objetos no está exclusivamente asociada a lenguajes de programación concretos (aunque se presenten como lenguajes OO):

es una metodología independiente del lenguaje utilizado, aunque hay lenguajes

que cuentan con mejores mecanismos que otros para poder aplicar eficientemente esta metodología. Utilizar la OO es más que programar en uno o varios lenguajes

de programación, es usar la OO como filosofía de desarrollo.

- En el desarrollo de software, los lenguajes OO por sí mismos, sin la compresión

de lo que hay tras ellos y sin haber conseguido la reorientación filosófica en la práctica del diseño y uso de software que requiere la OO, no son más que coches

sin motores.

- Por experiencia propia, sé que existe una gran diferencia entre comprender los

fundamentos de la orientación a objetos y aplicarlos con éxito: es el eterno salto en

el vacío entre la teoría y la práctica. Ahora bien, no comprender previamente los

fundamentos de la OO y sus sutilezas, y utilizar lenguajes OO es encaminarse

cierta

envergadura. A lo largo de diez años he visto, en programas de compañeros y clientes, clases con miles de líneas y decenas de métodos estáticos, clases compuestas sólo por métodos, clases con cohesión tan fuerte que volvían el código completamente irreutilizable, usos de la herencia que derivaban en código confuso e inestable Me consta que no son hechos aislados, cualquier programador o analista que tenga cierta experiencia puede referir hechos similares, si no calcados. El motivo de estos fallos conceptuales suele ser éste: el programador ha pasado de utilizar un lenguaje estructurado a uno presuntamente orientado a objetos sin tener claros o haber madurado los conceptos de la OO. Aparentemente

son conceptos muy sencillos

hacia un desastre casi seguro cuando el problema que se aborda es de

pero solo aparentemente. Intentar continuar,

consciente o inconscientemente, con un enfoque estructurado de programación en lenguajes OO puede hacerse, al igual que puede escribirse con una pluma de ave y tinta china, pero no es lo más adecuado. Suscribo por completo las palabras de Wolfgang Strigel cuando escribe “ Los conceptos básicos de la OO se conocen desde hace dos décadas, pero su

aceptación todavía no está tan extendida como los beneficios que esta tecnología

puede sugerir” y “

mayoría de los usuarios de la OO no utilizan los

conceptos de la OO de forma purista, como inicialmente se pretendía. Esta práctica ha sido promovida por muchas herramientas y lenguajes que intentan utilizar los conceptos en diversos grados” (la negrita es mía).

La

2. Definiciones previas.

A continuación se presentan las definiciones de términos de uso frecuente en lo

que sigue, y que vale la pena definir al menos una vez para evitar confusiones o ambigüedades. [Las definiciones de Clase y Objeto son temporales y se concretarán más detalladamente en la segunda parte del artículo]

2

Orientación a objetos: Conceptos y terminología

Análisis: Proceso que permite pasar del sistema real a un modelo conceptual. Clase: Conjunto de objetos que tienen en común la misma estructura y comportamiento. Diseño: Proceso que especifica la implementación de un sistema a partir de un modelo conceptual de éste. Ingeniería de software: Disciplina cuyo propósito es la producción de software libre de fallos, dentro del plazo previsto, cumpliendo el presupuesto inicial, y que satisfaga las necesidades del usuario o cliente. Ingeniero/a de software: Persona que aplica las técnicas de la ingeniería de software y que, a menudo, tiene que afrontar con tranquilidad de espíritu, mirada resignada y autocontrol Zen las reducciones de los plazos de entrega, los recortes en el presupuesto original y las modificaciones sustanciales y sin previo aviso de los requisitos iniciales. Mensaje: Estímulo enviado a un objeto con un nombre y los parámetros adecuados que provoca que el objeto comience cierto comportamiento al ejecutar una operación. Metodología: Sinónimo de paradigma. Modelo: Abstracción que describe el sistema bajo estudio. (Un modelo puede consistir en diagramas más los textos, notaciones o aclaraciones necesarias para entenderlos) Objeto: Entidad con identidad propia y capaz de exhibir un comportamiento. Estructura de datos encapsulada con un conjunto de operaciones que operan sobre los datos. Operación: Descripción de la habilidad de un objeto para responder a un mensaje y de los requisitos para ese mensaje. (Su imple mentación se denomina método) Paradigma: Estrategia o punto de vista para realizar tareas. Colección de técnicas para resolver problemas. Marco conceptual. Matriz disciplinaria. [Su significado profundo, según Kuhn, se verá en el Apdo. 6] Sistema: Parte del mundo real bajo estudio. Conjunto de cosas (reales o abstractas) que forman un todo de acuerdo con cierto plan o propósito.

3. Raíces de los conceptos de la OO. La orientación a objetos como filosofía de desarrollo de sistemas. Comparación con el paradigma estructurado.

Pese a que el término “orientación a objetos” ejerce una innegable fascinación para muchos ingenieros de software, gran parte de sus conceptos distan mucho de ser nuevos. Algunos, incluso, forman parte de la tradición cultural occidental casi desde sus inicios: Platón y Aristóteles usaron ya en sus escritos términos como “objetos”, “clases”, “subclases”, “clasificaciones”, etc. (Posiblemente Aristóteles llevara demasiado lejos el concepto de clase: clasificó dentro del mismo grupo a la cotorra y la lechuga, pues ambas son verdes) Ya a principios del siglo XX, matemáticos lógicos eminentes como Whitehead y Lord Russell, formalizaron y ampliaron los anteriores conceptos, tratando de dar (infructuosamente) una base lógica auto-consistente a la matemática. Las definiciones lógicas y filosóficas de estos conceptos han influido mucho en la terminología OO. Por ejemplo, en Principia Mathematica [Whitehead & R, 1910] se define “clase” como una colección de objetos a los que se aplica un concepto, y esta misma definición fue la que inspiró el término “clase” en la OO e influyó en el desarrollo de los lenguajes de programación SIMULA I (1962-65) y Simula 67 (1967), cuya influencia conceptual subyace en todos los modernos lenguajes OO. Lo anterior no tiene un interés únicamente anecdótico o histórico: los conceptos matemáticos, lógicos y filosóficos permiten expresar con exactitud y sin ambigüedades lo que hoy en día se considera “orientación a objetos”. Además, la OO (y, por tanto, el software OO) evo lucionará con el tiempo hacia caminos aún inciertos y son los

3

http://www.javahispano.org

conceptos lógico- matemáticos y filosóficos los que podrán seguir usándose para elaborar lo que llamaré “orientación a objetos no estándar” e incluso para elaborar nuevos métodos de análisis y diseño de parentesco remoto con la orientación de objetos. Si existe algo parecido a la inmortalidad, las ideas matemáticas lo tienen: las ideas de Pitágoras pervivirán más que las obras de Shakespeare y seguirán vigentes cuando los actuales lenguajes de programación no sean más que notas a pie de página.

Aunque, todavía hoy, suele asociarse la orientación a objetos a determinados lenguajes de programación (Java, C++, Eiffel, etc.) es mayoritaria la opinión de que la OO es una filosofía general o metodología de desarrollo de sistemas (informáticos o no). La orientación a objetos puede aplicarse a la ingeniería de procesos, de redes, de productos, a la gestión empresarial, etc. El enfoque o la perspectiva OO considera los sistemas como colecciones de objetos capaces de interactuar entre sí, que trabajan conjuntamente para realizar tareas. El análisis OO define todos los tipos de objetos que modelan el sistema (es decir, que realizan las funciones de interés del sistema) y muestra cómo interaccionan. El diseño OO define todos los tipos de objetos adicionales que se necesitan para comunicarse con el exterior del sistema y se encarga de perfilar o de refinar los tipos de objetos de cara a una posterior implementación.

ORIENTACIÓN A OBJETOS

ORIENTACIÓN A OBJETOS La orientación a objetos permite ver y modelar el mundo como un conjunto
ORIENTACIÓN A OBJETOS La orientación a objetos permite ver y modelar el mundo como un conjunto

La orientación a objetos permite ver y modelar el mundo como un conjunto de objetos que intercambian mensajes entre sí

Miguel Ángel Abián, Nov. 2002

Figura 1. La orientación a objetos como metodología de uso general en nuestro mundo

Cuando se consideran específicamente sistemas de software, el paradigma orientado a objetos consiste en el análisis OO, el diseño OO y la programación OO; es una metodología de la ingeniería del software que considera los sistemas de software desde la perspectiva OO descrita en el primer párrafo de este apartado. La programación OO es cualquier técnica de desarrollo de software que incluya el diseño OO –obtenido, por lo general, a partir de un análisis OO- y que permita producir programas OO (programas que consisten en un conjunto de objetos capaces de comunicarse entre sí).

4

Orientación a objetos: Conceptos y terminología

El paradigma OO fue el “paradigma emergente” en la década de los 90 (en el sentido que expone Kuhn en La estructura de las revoluciones científicas [Kuhn, 1971] y que se detallará en el apartado 6) y es ahora el paradigma aceptado por la industria y la investigación. Dado que estamos en un contexto más aplicado que el de la ciencia pura, su permanencia como paradigma dependerá de que resuelva con éxito problemas reales, sin plantear más problemas (y gastos) de los que efectivamente resuelva (y ahorre).

PROGRAMACIÓN ORIENTADA A OBJETOS

PROGRAMACIÓN ORIENTADA A OBJETOS La programación orientada a objetos permite construir modelos de objetos en el
PROGRAMACIÓN ORIENTADA A OBJETOS La programación orientada a objetos permite construir modelos de objetos en el

La programación orientada a objetos permite construir modelos de objetos en el mundo real usando objetos de software

Miguel Ángel Abián, Nov. 2002

Figura 2. La programación orientada a objetos como técnica de desarrollo de software

Antes de comenzar con los fundamentos de la orientación a objetos, conviene mencionar a su oponente (el paradigma anterior a la OO y que se encuentra en proceso de cambio): El análisis y diseño estructurado (o funcional) construye modelos basados en el procesamiento de datos. Una persona que utilice este enfoque intentará dividir el problema bajo estudio identificando una serie de procesos, manipulaciones o tratamientos de datos (llamados funciones o procedimientos en las fases de diseño e implementación) que, organizados de modo que puedan llamarse unos a otros, proporcionen la solución. Siempre existe una separación entre datos y procesos: los procesos manipulan y usan datos, pero no se integran con ellos. El paradigma estructurado (análisis estructurado + diseño estructurado + programación estructurada) en la ingeniería de software se basa en la abstracción por descomposición funcional o por procedimientos: el problema estudiado se descompone en una serie de capas sucesivas de procesos, hasta que finalmente se descompone en procesos relativamente fáciles de implementar y codificar (desarrollo top-down). Un programa estructurado se divide en unidades lógicas (módulos) mediante el uso de funciones y procedimientos; los detalles más internos del programa residen en los módulos de más bajo nivel y los módulos de más alto nivel se encargan del control lógico del programa. El paradigma estructurado mantendrá su vigencia, posiblemente, por cierto tiempo en la ingeniería del software pues muchas aplicaciones informáticas de gestión utilizan mayoritariamente pseudoobjetos u objetos que no pueden considerarse objetos de pleno

5

http://www.javahispano.org

derecho (por ejemplo, objetos sin atributos u objetos sin métodos), generalmente asociados a las estructuras tradicionales de datos. A la vista de la Tabla 1 se aprecia uno de los defectos má s comúnmente señalados por los críticos del paradigma estructurado: la separación clara e insalvable entre el análisis y el diseño, es decir, entre lo que se quiere que haga el sistema y cómo lo hace. En el paradigma OO la frontera entre el análisis y el diseño es difusa, y los objetos se introducen desde el principio. Es más natural pasar del análisis a la implementación en el paradigma OO que en el estructurado: el salto conceptual es menor en aquél.

Paradigma estructurado

Paradigma orientado a objetos

Etapa de análisis: se determina qué debe hacer el sistema a construir.

Etapa de análisis OO: se determina qué debe hacer el sistema a construir y se extraen los objetos. Se modela el espacio del problema mediante notación OO.

Etapa de diseño: se extraen funciones o procedimientos (muy vinculados con los datos con los que se va a trabajar y poco naturales para el modo de pensar huma- no: no pensamos mediante algoritmos). Esta fase no puede omitirse.

Etapa de diseño OO: se perfecciona el diseño, afinándose las características de los objetos. Muchas veces esta fase puede ser omiti- da conociendo las especificaciones del análisis OO.

Etapa de implementación: se imple- mentan las funciones en un lenguaje de programación adecuado.

Etapa de implementación OO: se implementan los objetos en un lenguaje de programación orientado a objetos.

Tabla 1. Comparación entre el análisis, el diseño y la implementación en los dos paradigmas.

La conversión de los términos del análisis OO hacia construcciones en lenguajes de programación OO es bastante directa, lo que constituye una importante ventaja sobre el paradigma estructurado.

6

Orientación a objetos: Conceptos y terminología

Sistema real

El poder saltarse en ocasiones la etapa de diseño, favorece la creación de prototipos rápidos
El poder saltarse en ocasiones la
etapa de diseño, favorece la
creación de prototipos rápidos OO
sobre los cuales hacer pruebas
Modelo
conceptual OO
Modelo de
diseño OO
Implementación OO

Miguel Ángel Abián, Nov. 2002

Figura 3. Muchas veces se pueden hacer prototipos rápidos en el paradigma OO, sin tener que pasar por la etapa de diseño. En el paradigma estruc turado no puede evitarse la etapa de diseño.

Algunos autores consideran que el enfoque OO ha evolucionado a partir del enfoque estructurado y otros que es un salto revolucionario, cualitativo más que cuantitativo. Desde luego, los partidarios del salto revolucionario suelen ser firmes partidarios de la OO, cuando no creadores de metodologías OO. Así, en la obra Object- Oriented Modeling and Design [Rumbaugh et al, 1991] se considera que el diseño orientado a objetos es una nueva forma de pensar en los problemas usando modelos sobre conceptos del mundo real y, en Ingeniería del Software. Un Enfoque práctico [Pressman, 1992], Pressman refiere que “a diferencia de otros métodos de diseño, el diseño orientado a objetos da como resultado un diseño que interconecta los objetos de datos y las operaciones, de forma que modulariza la información y el procesamiento en vez de sólo la información. La naturaleza del diseño orientado a objetos está ligada a tres conceptos básicos: abstracción, modularidad y ocultación de la información.” Mi opinión, dado que no hay un acuerdo unánime, es que realmente el enfoque OO utiliza abstracciones no presentes en el enfoque estructurado y que no admiten equivalencia. Nótese que estoy hablando en términos conceptuales, no de lenguajes de programación. Teóricamente todo lo que podría hacer un lenguaje OO podría hacerlo un lenguaje estructurado. De hecho, las primeras versiones de C++ utilizaban una traducción previa a C mediante un preprocesador antes de la compilación, de ahí su lentitud. Incluso un lenguaje “puro” OO como Eiffel permite la traducción del código Eiffel a código C.

4. Fundamentos de la orientación a objetos

El paradigma orientado a objetos se fundamenta en los siguientes principios:

7

http://www.javahispano.org

- Abstracción

- Modularidad

- Encapsulación o encapsulamiento

- Jerarquía

4.1. Abstracción.

La abstracción es una aproximación o abordaje del diseño que hace hincapié en los aspectos más importantes de algo, sin preocuparse por los detalles menos importantes. De acuerdo con el Dictionary of Object Technology: The Definitive Desk Reference [Firesmith & E, 1995], la abstracción es “Cualquier modelo que incluye los aspectos más importantes, esenciales o distinguibles de algo mientras suprime o ignora los detalles menos importantes, inmateriales o que pueden distraer ”. La abstracción es específica del dominio (área seleccionada de interés). La abstracción Persona es distinta en el dominio “Censo electoral” que en el dominio “Hospital”. Quizá el ejemplo más gráfico de lo que es una abstracción lo dé el cuadro “La trahison des images” del pintor surrealista belga René Magritte (1898-1967). En él aparece dibujada una pipa y bajo ella aparece la frase “Ceci n’est pas une pipe” (Esto no es una pipa) escrita con caligrafía escolar. Efectivamente, el dibujo es una abstracción o representación conceptual de una pipa, no una pipa (cuán sutiles solían ser los surrealistas). En el cuadro se ha perdido la tridimensionalidad de la pipa real, sus pequeñas imperfecciones, pero se han mantenido la mayor parte de sus características fundamentales (forma, etc.). En ese sentido, el dibujo de la pipa es una buena abstracción o un buen modelo de una pipa real. En la ingeniería del software y en la OO es fundamental comenzar desde el principio con buenas abstracciones o modelos del problema que vaya a ser abordado.

o modelos del problema que vaya a ser abordado. Figura 4. “La traición de las imágenes”

Figura 4. “La traición de las imágenes” de René Magritte (1926) Cuando la abstracción se confunde con la realidad: ¿Es esto una pipa? Si fuera de verdad una pipa, ¿no debería poder encenderse y echar humo?

8

Orientación a objetos: Conceptos y terminología

4.2. Modularidad

Informalmente, es la descomposición de un proceso complejo en subprocesos más sencillos y manejables. Según el Dictionary of OT la modularidad es “La descomposición lógica de las cosas (por ejemplo, responsabilidades y software) en agrupaciones simples, pequeñas (por ejemplo, requisitos y clases, respectivamente), que aumentan las posibilidades de lograr las metas de la ingeniería de software”. Cuando nos restringimos a software, un módulo es un conjunto de sentencias bajo el paraguas de un nombre por el cual puede ser llamado o invocado. Los módulos serían la unidad de programación. En Java, una clase sería un módulo. Las características deseables de un módulo, aunque no detalladas en la definición del Dictionary of OT, serían las siguientes:

- Alta cohesión; entendiendo la cohesión como una medida del grado de relación funcional interna de los componentes de un módulo. - Bajo acoplamiento; entendiendo el acoplamiento como una medida de la interconexión entre módulos.

Ambos conceptos (cohesión y acoplamiento) no son absolutamente rígidos y no admiten una cuantificación milimétrica. Además, no son totalmente independientes:

generalmente –aunque no siempre- una alta cohesión de un módulo implica bajo acoplamiento del mismo con respecto a otros.

9

http://www.javahispano.org

4.3. Encapsulación o encapsulamiento

Llanamente, la encapsulación es el ocultamiento de la información. Según el Dictionary of OT es “La localización física de las propiedades dentro de una sola abstracción de caja negra que oculta su implementación (y las decisiones asociadas de diseño) tras un interfaz público ”. La abstracción de “caja negra” es utilizada ampliamente en física, electrónica e informática y consiste en esconder todos los detalles internos del sistema que se estudia bajo una caja negra imaginaria, cuando sea más importante comprender qué hace el sistema que cómo lo hace. El encapsulamiento es como introducir el sistema dentro de una caja negra con dos ranuras llamadas “Entrada” y “Salida”. Por ejemplo, en metrología, cuando quiere calibrarse un dinamómetro, no se estudia la incertidumbre que proporciona cada circuito, cada muelle, cada parte móvil, etc. (entre otras cosas porque el problema se tornaría casi inabordable) y luego se combinan para obtener la incertidumbre del aparato. En la práctica, lo que se hace es considerar el dinamómetro como una caja negra y se calibra viendo las lecturas (“Salida”) que da frente a fuerzas patrón (“Entrada”), olvidándose de sus componentes internos. Así, por poner otro ejemplo lejano al campo de la informática, un complejo circuito electrónico que forme parte de un sistema mayor puede ser substituido imaginariamente, para facilitar el estudio del sistema completo, por una caja negra que recibe una señal eléctrica y devuelve otra. Es más, el circuito podría caracterizarse por su función de transferencia (“lo que hace”) sin que fuera necesario conocer la forma en que modifica la señal de entrada (“cómo lo hace”) ni sus componentes. Del mismo modo, cuando en Java se utiliza la clase Vector, no es necesario saber qué operaciones internas realiza para añadir o eliminar elementos; es más, si se necesitara conocerlas se estaría violando el principio de encapsulamiento.

Señal entrada Señal salida Miguel Ángel Abián, Nov. 2002 La caja negra oculta los componentes

Señal entrada

Señal entrada Señal salida Miguel Ángel Abián, Nov. 2002 La caja negra oculta los componentes internos

Señal salida

Miguel Ángel Abián, Nov. 2002

Señal entrada Señal salida Miguel Ángel Abián, Nov. 2002 La caja negra oculta los componentes internos

La caja negra oculta los componentes internos (la implementación)

entrada Señal salida Miguel Ángel Abián, Nov. 2002 La caja negra oculta los componentes internos (la
entrada Señal salida Miguel Ángel Abián, Nov. 2002 La caja negra oculta los componentes internos (la

Figura 5. La encapsulación es una herramienta poderosa en muchos campos

10

Orientación a objetos: Conceptos y terminología

Los conceptos de abstracción y encapsulación no son conceptos independientes,

sino complementarios: la abstracción hace referencia al comportamiento observable de un objeto, mientras la encapsulación hace referencia a la implementación que le permite alcanzar este comportamiento.

la

encapsulación se traduce en que los objetos de software son inaccesibles directamente

para otros objetos. Esta inaccesibilidad directa hace que un objeto deba comunicarse con otros (o, lo que es lo mismo, intercambiar información) a través de mensajes con los nombres y parámetros adecuados. La encapsulación será correcta cuando la interfaz que se muestra al público cumpla las tareas que desea el cliente y no muestre más de lo que éste precisa. Un encapsulamiento correcto siempre separa las vistas que del sistema tienen el constructor y el usuario. Resulta llamativo que el término encapsulación provenga, precisamente, de la ingeniería electrónica. Pero esta coincidencia de terminología, al igual que el ejemplo del circuito electrónico de la página anterior, no es ni mucho menos casual. La ingeniería electrónica aplicada a la construcción de ordenadores siempre ha trabajado, una vez pasada la época de tubos de vacío, con componentes (“cápsulas”) en los que se integran otros muchos componentes. Sus principales avances han sido tecnológicos:

cada vez caben más componentes por unidad de superficie, pero siempre ha estado presente implícitamente un concepto primordial: la reutilización. Resultaría inaceptable que se estropeara un componente electrónico y que hubiera que construir otro idéntico desde la nada o que nuevos componentes tuvieran que desarrollarse necesariamente combinando resistencias, condensadores y bobinas, sin poder aprovechar nada de todos los componentes ya fabricados, o que fuera imprescindible conocer todos los elementos de un componente antes de poder saber para qué podría ser útil. El considerar los objetos como “cápsulas” facilita enormemente que un objeto ya implementado pueda ser transportado a otras partes del sistema del que forma parte o a otros sistemas. En principio, un objeto correctamente diseñado y construido debería seguir realizando sus tareas (mediante los métodos) en cualquier otro sistema.

la

importancia capital que tienen hoy en la ingeniería de software (hasta mediados de la década de los 70, aproximadamente, no se empezó a hacer un uso intensivo de la encapsulación) sucedía algo similar en la programación: empezar un nuevo programa era, a menudo, comenzar desde cero y la reutilización de “componentes” de programación era mínima. En los pocos casos en que se podían reutilizar estos “componentes” de programación era necesario conocer cómo funcionaban “por dentro”, lo que tornaba imposible la encapsulación.

Desde

el

punto

de

vista

de

la

ingeniería

de

software,

la

propiedad

de

Antes

de

que

los

conceptos

de

modularidad

y

encapsulación

tuvieran

4.4. Jerarquía

Según el Dictionary of OT es “Cualquier clasificación u ordenación de abstracciones en una estructura de árbol. Tipos: Jerarquía de agregación, jerarquía de clases, jerarquía de herencia, jerarquía de partición, jerarquía de especialización, jerarquía de tipo ”. La jerarquía se ha utilizado ampliamente desde hace muchísimo tiempo en las ciencias naturales para clasificar a los seres vivos. Con ello no quiero decir que los

11

http://www.javahispano.org

primeros botánicos o zoólogos pudieran ser, de haber vivido en esta época, unos extraordinarios programadores, sino que entendieron desde el principio la importancia de dividir los problemas en una jerarquía de ideas. Quizá Aristóteles fuera un poco desencaminado en cuanto a los detalles (véase apdo. 3), pero andaba bastante acertado en cuanto a las ideas generales.

Programador Trabajador Persona Mamífero Animal Ser vivo Miguel Ángel Abián, Nov. 2002
Programador
Trabajador
Persona
Mamífero
Animal
Ser vivo
Miguel Ángel Abián, Nov. 2002

Figura 6. Un ejemplo de jerarquía

De modo general, la herencia es el principio de que las propiedades de una categoría general se transmiten para todas las categorías que especializan la categoría general. En sistemas de software el término herencia designa la facultad de los objetos de compartir propiedades y operaciones entre ellos. Un subobjeto u objeto derivado es una extensión de un objeto base que hereda parte o todas las características del objeto

base o “padre”. El objeto derivado u objeto “hijo” aporta especialización al objeto base, pudiendo redefinir determinados métodos y/o añadir nuevos métodos y atributos que sólo estarán disponibles para sus objetos derivados.

la

información y jerarquía de herencia, que requiere como solución una apertura en el acceso a la información pues necesariamente un objeto derivado debe conocer al menos parte de la información contenida en el objeto base. Muy relacionado con la herencia, se encuentra el polimorfismo. Aunque se tratará con detalle en la 2ª parte del artículo, puede adelantarse que el polimorfismo permite redefinir métodos en objetos derivados que sobrescriban a los del objeto base. Como se vio en el apartado 3, el paradigma estructurado se basa en la abstracción por descomposición. El paradigma orientado a objetos incluye también la descomposición como un mecanismo de abstracción, pero la complementa con la herencia, que se basa en la abstracción por clasificación. En mi opinión la abstracción por clasificación no tiene equivalente en el paradigma estructurado y constituye, por tanto, una característica novedosa de la OO. A fecha de hoy el debate de la evolución- revolución de la OO frente al paradigma estructurado continúa abierto. La herencia es responsable, combinada con el encapsulamiento, en gran medida del éxito de la programación OO al permitir la reutilización del código OO. La correcta utilización de la herencia y el encapsulamiento permite concebir los programas OO

Existe

una

tensión

esencial

entre

los

conceptos

de

encapsulamiento

de

12

Orientación a objetos: Conceptos y terminología

como una unión de “cápsulas” (objetos) intercambiables con otros programas y que pueden transmitir sus propiedades (atributos y métodos) a nuevas “cápsulas” sin tener que desarrollarlas desde cero. Por otro lado, el cambio de implementación de una “cápsula” no implicará cambios en la implementación de otras con las que se relacione, siempre que se mantengan intactos los métodos por los que se comunican. En los sistemas de software el mantenimiento ha supuesto siempre el coste más importante de los sistemas. La herencia y el encapsulamiento permiten reducir el coste de las modificaciones, casi siempre inevitables, que deben ir sufriendo los programas al contacto con la realidad.

5. Lenguajes de programación orientados a objetos. ¿Puede utilizarse la OO en lenguajes no orientados a objetos?

Al considerar sistemas de software, la programación OO implica habitualmente (pero no necesariamente) el uso de lenguajes de programación orientados a objetos. Como metodología, la OO es independiente de cualquier lenguaje, sea orientado a objetos o no. El análisis y diseño OO puede aplicarse –en teoría- a cualquier lenguaje de programación. No existe un acuerdo común e inapelable en la bibliografía sobre los requisitos que debe cumplir un lenguaje para considerarse OO, pero generalmente se admite que un lenguaje OO debe tener como mínimo:

a) Encapsulación

b) Herencia

c) Polimorfismo [Este término se estudiará en la segunda parte del artículo]

Adicionalmente, en un lenguaje OO puede suceder que:

d)

Todos los tipos de datos predefinidos en el lenguaje sean objetos

e)

Todos los tipos de datos que puedan ser definidos por los programadores sean

objetos

f)

Todas las posibles operaciones se realicen enviando mensajes entre objetos

Se consideran lenguajes OO “puros” aquellos que tienen las 6 características a)- f) y se consideran “híbridos” aquellos que carecen de alguna de las 3 últimas: d), e) ó f).

Característica

Fortran 77

C++

C#

Java

Smalltalk

Eiffel

a) NO

 

SI

SI

SI

SI

SI

b) NO

 

SI

SI

SI

SI

SI

c) NO

 

SI

SI

SI

SI

SI

d) NO

 

NO

NO

NO

SI

SI

e) NO

 

NO

NO

SI

SI

SI

f) NO

 

NO

NO

NO

SI

SI

Tabla 2. Ejemplos de lenguajes no OO, OO “híbridos” y OO “puros”.

Es importante resaltar que cualquier programa que se realice con un lenguaje orientado a objetos (híbrido o puro) podría realizarse con un lenguaje estructurado o no orientado a objetos. Es más, se podrían escribir programas verdaderamente orientados a objetos (es decir, en los que se usara abstracción, encapsulación, etc.) usando un

13

http://www.javahispano.org

lenguaje de desarrollo no OO. El programador debería implementar las principales características de la OO en el lenguaje seleccionado (convertir en objetos las estructuras de datos propia del lenguaje no OO, almacenarlos en memoria, elegir cuidadosamente los nombres de los métodos para asociarlos inmediatamente a los objetos

correspondientes, implementar la herencia y el polimorfismo,

en un lenguaje OO pues ya posee de partida esas implementaciones. En la práctica siempre será más rápido y eficiente trabajar directamente con lenguajes OO que implementar las características OO en lenguajes no orientados a objetos. Como ejemplo de lo dicho se va a implementar en Fortran 77 y C una clase Rectángulo y se implementará también la herencia para dos clases Circulo y Elipse que derivan de una clase Punto.

),

proceso innecesario

Implementación de la clase Rectángulo en Fortran 77

implicit none

common /rectangulo/ x1, x2, y1, y2, num_rectangulo real x1(100), x2(100), y1(100), y2(100) integer num_rectangulo

Este

código

definiría

una

clase

Rectángulo,

quedando

cada

rectángulo

caracterizado

por

las

coordenadas

de

sus

vértices.

Se

guardarían

en

memoria

simultáneamente 100 objetos de tipo rectángulo (en Fortran 77 no existe la asignación dinámica de memoria) y el índice entero num_rectangulo permitiría identificar en todo momento cualquier objeto rectángulo. El bloque common permite que ciertas variables se comportan entre varias subrutinas. En Fortran 77 un objeto solo puede representarse por una colección de cadenas de variables, representando cada variable un atributo del objeto. No existen tipos de datos definidos por el usuario.

Implementación de la clase Rectángulo en C

struct rectangulo{

float x1;

float x2;

float y1;

float y2;

}

Para iniciar un objeto rectángulo

struct rectangulo miRectangulo={0, 2, 3, 5}

14

Orientación a objetos: Conceptos y terminología

Implementación de la herencia en Fortran 77 con dos clases: Elipse y Círculo que derivan de una clase Punto

Implementación de las clases Elipse y Círculo.

implicit none

common /figura/ x, y, semiejea, semiejeb, radio, num_figura, clase_figura real x(100), y(100), semiejea(100), semiejeb(100), radio(100) integer num_figura integer clase_figura(100)

common /clases/ ELIPSE, CIRCULO integer ELIPSE /1/, CIRCULO /2/

Este modo sería muy ineficiente, pues reservaría espacio en memoria tanto para los atributos de la clase base Punto (coordenadas x e y) como para los atributos adicionales de las clases derivadas Círculo (radio) y Elipse (semiejes), pero sirve como ejemplo del modo de trabajar en Fortran 77.

Para crear objetos derivados o “hijos”, el código sería similar a este:

function crear_elipse(x0, y0, semiejea0, semiejeb0)

integer crear_elipse

common /figura/ x, y, semiejea, semiejeb, radio, num_figura, clase_figura real x(100), y(100), semiejea(100), semiejeb(100), radio(100) integer num_figura integer clase_figura(100)

common /clases/ ELIPSE, CIRCULO integer ELIPSE /1/, CIRCULO /2/

num_figura=num_figura + 1

x(num_figura)=x0

y(num_figura)=y0

semiejea(num_figura)=semiejea0

semiejeb(num_figura)=semiejeb0

radio(num_figura)=0

clase_figura(num_figura)=ELIPSE

crear_elipse=num_figura

end

15

http://www.javahispano.org

function crear_circulo(x0, y0, radio0)

integer crear_circulo

common /figura/ x, y, semiejea, semiejeb, radio, num_figura, clase_figura real x(100), y(100), semiejea(100), semiejeb(100), radio(100) integer num_figura integer clase_figura(100)

common /clases/ ELIPSE, CIRCULO integer ELIPSE /1/, CIRCULO /2/

num_figura=num_figura + 1

x(num_figura)=x0

y(num_figura)=y0

semiejea(num_figura)=radio0

semiejeb(num_figura)=radio0

radio(num_figura)=radio0

clase_figura(num_figura)=CIRCULO

crear_circulo=num_figura

end

Para

implementar

el

polimorfismo

bastaría

comprobar,

dado

un

objeto

(caracterizado por su num_figura), cuál es el valor de clase_figura(num_figura) y, dependiendo de si es CIRCULO ó ELIPSE, asignarle un método u otro.

Implementación de la herencia en C con dos clases: Elipse y Círculo que derivan de una clase Punto

struct punto{

float x;

float y;

};

struct circulo{ struct punto origen_figura; float radio;

};

struct elipse{ struct punto origen_figura; float semiejea; float semiejeb;

};

16

Orientación a objetos: Conceptos y terminología

Se ha escogido deliberadamente Fortran 77 para los ejemplos por ser un lenguaje primitivo -aunque extremadamente potente para aplicaciones que requieran cálculos numéricos intensivos- en comparación con los lenguajes de programación actuales. Sería el equivalente informático a un mamut lanudo que hubiera escapado de una glaciación y perviviera en nuestros días. Para ser justos, hay que añadir que la versión anterior (Fortran 66) se utilizaba con tarjetas perforadas y que las versiones actuales (Fortran 90 y 95) sí incorporan asignación dinámica de la memoria y punteros, tipos de datos definidos por el usuario, módulos –en el sentido de la OO- y otras características. Al ser un lenguaje que tiene un único tipo de estructuras de datos (matrices) resulta posible, pero muy complicado e ineficaz, implementar los principios de la OO. En C resulta mucho más fácil, porque permite al programador definir sus propias estructuras de datos y el uso de la asignación dinámica de la memoria hace que se aproveche mucho más eficientemente la memoria que en Fortran 77. En resumen, aunque la manera más cómoda, rápida y eficiente de realizar programas orientados a objetos es utilizar lenguajes OO, ya sean puros o híbridos, resulta posible aprovechar el análisis y diseño OO en implementaciones con lenguajes no orientados a objetos.

6. Él éxito del paradigma orientado a objetos: ¿basado únicamente en criterios objetivos? Factores extracurriculares. Lo que la OO no puede hacer

Una vez expuestos los fundamentos de la OO y antes de definir detenidamente los conceptos de la misma es interesante reflexionar sobre el éxito de la OO desde una perspectiva poco ortodoxa y un tanto herética. En su célebre libro La estructura de la revoluciones científicas Thomas S. Kuhn definió paradigma en el sentido de matriz disciplinaria: elementos ordenados de

diversas maneras, cuyo orden hay que especificar, que son posesión común de los profesionales de una disciplina. Kuhn proponía que cuando los científicos observan determinados fenómenos no los miran objetivamente en realidad, sino a través del filtro de un conjunto de ideas y conceptos (procedentes de la tradición cultural, social y científica en la que han sido educados) que han formado/deformado su percepción. Los ven a través de un paradigma firmemente establecido. Solo así podía entenderse, según Kuhn, que ideas como que la velocidad de caída de los cuerpos era proporcional a su masa hubieran pervivido desde la Grecia antigua hasta Galileo, cuando unos sencillos experimentos hubieran demostrado su falsedad. Según sus ideas, los científicos de todos esos siglos intermedios aceptaron la idea de que los cuerpos caían con una velocidad proporcional a su masa como parte de su paradigma, y por ello no se plantearon hacer experimentos ni “vieron” los hechos que iban en su contra. Por eso mismo, la idea de que la tierra era plana pervivió durante mucho tiempo, aunque numerosos hechos de la experiencia común la invalidaban; la gente era educada en un sistema de creencias compartidas (paradigma) donde esa idea era aceptada.

de

científicos, se coloca las “gafas” de un nuevo paradigma, el resto de la comunidad científica reniega y manifiesta su desacuerdo inicialmente hasta que el paradigma emergente demuestra su validez (mediante hechos empíricos, permitiendo explorar nuevos programas de investigación, solucionando con más sencillez problemas ya conocidos o abordando nuevos problemas) y/o los viejos científicos, educados en el

Generalmente –siempre según Kuhn-

cuando

un

científico,

o

un

grupo

17

http://www.javahispano.org

paradigma anterior, fallecen de viejos. En ocasiones un paradigma puede no ser intrínsecamente mejor que otro, pero la comunidad científica lo puede adoptar por encajar con una ideología, una cultura o una preconcepción del mundo. Al cabo de pocas generaciones todos los científicos se educan ya en el nuevo paradigma y los conflictos conceptuales entre el paradigma antiguo y el nuevo son solamente recordados

por filósofos o historiadores de la ciencia que mantienen hasta su defunción apasionadas

y encarnizadas batallas dialécticas–batallas que probablemente proseguirán, si es

posible, en el lugar adonde vayan los filósofos al morir- sobre la respectiva superioridad

o inferioridad de cada paradigma. Y así una y otra vez. Kuhn venía a decir que hay un componente sociológico y cultural, ajeno a la

pretendida ciega y aséptica objetividad científica, en el modo en que los científicos de una época observan el mundo y en las razones por las que un paradigma se convierte en dominante sobre sus contrincantes, y que los paradigmas son consensos tácitos dentro

de una comunidad (científica, técnica, etc.).

Sin lugar a dudas, la OO es un paradigma dentro de la comunidad de la ingeniería de software en el sentido de Kuhn expuesto arriba. La orientación a objetos es el paradigma aceptado actualmente (aunque existen otros) en los sistemas de software y ha

relevado al antiguo paradigma estructurado. Los estudiantes de ingeniería de software se forman ya en la OO, está incluida en los planes académicos, y sus términos son de uso común. Incluso el uso de lenguajes OO está desplazando a los lenguajes estructurados tradicionales que se utilizaban en las asignaturas de introducción a la programación. ¿Por qué se ha impuesto como paradigma la orientación a objetos? En gran parte por su efectividad, el desarrollo de proyectos software de gran envergadura volvió ineficiente al paradigma estructurado y la OO permite abordar viejos problemas de nuevas maneras

y con costes menores (gracias a su hincapié en la reutilización mediante la herencia y el

encapsulamiento, como se describe en el apartado 4). Sin la OO, muchos proyectos modernos no hubieran podido ejecutarse. También por su sencillez conceptual (¿quién no sabe lo que es un objeto?), está mucho más cerca del pensamiento humano que el paradigma estructurado (¿cuántas personas piensan en los problemas de su vida cotidiana en términos de algorítmica?). Pero tampoco cabe cegarse ante la evidencia: hay un cierto elemento de profecía autocumplida en el éxito de la OO y de consenso socio-cultural mayoritario (paradigma) acerca de sus ventajas poco crítico y objetivo en la comunidad de investigadores y desarrolladores de software. Supóngase que los investigadores de prestigiosas universidades comenzasen a desarrollar lenguajes MM, crearan revistas y publicaciones con las siglas MM – engordando de paso sus currículos y aumentando sus posibilidades de acceder a mejores remuneraciones y a puestos más elevados- y abrieran nuevas parcelas de investigación con nuevas promesas de sencillez, productividad, ahorro de costes, etc. Las empresas se harían eco de estas promesas (aunque solo sea por miedo a que otras empresas usen las nuevas técnicas antes que ellas) y la industria apoyaría el nuevo paradigma; aparecerían libros como “Aprenda MM en 21 días” y “Thinking in MM”, comités de normalización, becas para investigar la MM, se venderían camisetas con el lema “I love MM”, y las empresas anunciarían orgullosas sus inversiones en MM, presentándose probablemente como empresas que caminan por el “filo de la tecnología”. ¿Acaso no sería difícil que el nuevo paradigma, avalado y apoyado por la industria y la comunidad investigadora, fracasara? Es probable que a partir de esfuerzos e inversiones se consiguieran éxitos – totales o parciales- que reafirmarían las promesas iniciales de sencillez, productividad,

18

Orientación a objetos: Conceptos y terminología

etc. ¿Se reconocerían abiertamente sus fracasos o se justificarían como éxitos parciales? ¿Cuesta mucho sustituir MM por OO? El éxito de la OO, como el éxito de muchas teorías científicas, tiene –aunque en un grado muy pequeño, pero no despreciable- un ingrediente sociológico en el sentido de Kuhn y otro ingrediente autojustificativo: se prometen nuevos avances, se realizan inversiones muy importantes, se dedican muchos recursos y, efectivamente, se obtienen avances, ¿pero no habrían podido conseguirse esos mismos avances u otros mayores con cualquier otro paradigma razonable si se hubieran dedicado los mismos recursos e inversiones? Hoy difícilmente un especialista se embarcaría en un importante proyecto de software sin seguir la metodología OO, porque es el paradigma dominante y la mayoría de recursos e investigación van a parar a él y resulta muy difícil conseguir financiación para ideas o proyectos fuera del paradigma dominante.

La orientación a objetos, aun siendo el paradigma dominante, no aporta capacidades o métodos de resolución de problemas irresolubles –en sentido teórico- por otros medios o técnicas. Una máquina de Turing podría ser simulada por cualquier lenguaje de programación que permitiera sentencias condicionales y saltos. De acuerdo con la conjetura de Church, cualquier computación para la que exista un algoritmo funcional (ya fuera el tiempo necesario de computo finito o no) puede ser realizada por una máquina de Turing. Por lo tanto, cualquier computación con un algoritmo funcional podría ser realizada –en sentido teórico, en la práctica habría limitaciones de tiempo, memoria, capacidad, etc.- en cualquier lenguaje de programación que permitiera sentencias condicionales y saltos, sea o no un lenguaje OO. La OO suministra unos nuevos “anteojos” conceptuales con los que ver el mundo y con los que comprender y solucionar los problemas de un modo más rápido, eficiente, económico y natural que con el paradigma estructurado (y más cercano al pensamiento humano: es mucho más natural para nosotros pensar en términos de objetos que de algoritmos), pero no proporciona soluciones a problemas no solubles con otros medios o técnicas.

Nota del autor: La reproducción del cuadro “La traición de las imágenes” de René Magritte se realiza con carácter ilustrativo y pedagógico. Los derechos de reproducción pertenecen a los herederos de René Magritte y/o a cualquier empresa, entidad o fundación que los representara o los hubiera adquirido. El autor no persigue en modo alguno lucrarse u obtener beneficio económico alguno de la reproducción del cuadro.

Nota biográfica del Autor: Miguel Ángel Abián nació en Soria (1972). Se licenció en Ciencias Físicas en 1995 por la U. de Valencia y consiguió la suficiencia investigadora en 1997 dentro del Dpto. Física Aplicada de la U.V. Además ha realizado diversos cursos de Postgrado sobre bases de datos, lenguajes de programación Web, sistemas Unix y Java. Ha participado en diversos programas de investigación TIC relacionados con el estudio de fibras ópticas y cristales fotónicos, y ha publicado

diversos artículos en el

relacionados con el análisis de guías de onda inhomogeneas y guías de onda elípticas. En el ámbito laboral ha trabajado como gestor de carteras y asesor fiscal para una agencia de bolsa y actualmente trabaja en el Laboratorio del Mueble Acabado de AIDIMA (Instituto Tecnológico del Mueble y Afines), ubicado en Paterna (Valencia), en tareas de normalización y certificación. En dicho centro se están desarrollando

IEEE Transactions on Microwave Theory and Techniques

19

http://www.javahispano.org

proyectos europeos de comercio electrónico B2B para la industria del mueble basados en Java y XML (más información en www.aidima.es). Sus intereses actuales son: el diseño asistido por ordenador de guías de ondas y cristales fotónicos, la evolución de la programación orientada a objetos, Java, el surrealismo y París, siempre París.

Copyright (c) 2003, Miguel Ángel Abián. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en http://www.javahispano.org/licencias/).

20