Capítulo 1

Principios de la orientación a objetos. Comparación con la programación estructurada

Contenido

1. Introducción

2. Programación estructurada y orientación a objetos

3. Ocultación de información (information hiding)

4. El Tipo Abstracto de Datos (ADT). Encapsulado de datos

5. Paso de mensajes

6. Resumen

1. Introducción

El desarrollo de una aplicación es un proceso con el que se pretende dar solución a una necesidad a través de una herramienta de software, obteniendo como resultado una serie de programas informáticos.

Al igual que ocurre en otras disciplinas, para construir un producto de calidad es necesario seguir un proceso de desarrollo adecuado, que habitualmente se inicia con un análisis de las necesidades a cubrir y un diseño del producto que se pretende conseguir.

La forma en que se lleva a cabo el proceso de desarrollo de software ha ido cambiando con el tiempo, pasando de la programación estructurada a una organización por módulos y, finalmente, a la programación orientada a objetos.

2. Programación estructurada y orientación a objetos

A la hora de iniciar un desarrollo de software, es necesario determinar el tipo de enfoque que quiere aplicarse, ya que no es lo mismo aplicar una programación estructurada que una orientación a objetos.

Esta decisión no solo afecta a la programación, sino que determina en gran medida las técnicas que han de aplicarse en el análisis previo.

2.1. Programación estructurada

La programación estructurada se organiza de forma lineal, utilizando únicamente instrucciones secuenciales, alternativas y repetitivas; todo el código es gestionado en un único bloque, por lo que es poco flexible y difícil de mantener en programas más complejos.

Para solventar estas carencias, surge la programación modular, que añade nuevas características a las técnicas utilizadas hasta el momento. El objetivo es separar en módulos las partes más complejas del programa, para que sean diseñados y desarrollados de forma independiente.

image

Nota

Cuando en los desarrollos actuales se aplica una programación estructurada, de manera implícita se asume que se está llevando a cabo de forma modular.

Con este enfoque, se toma el problema de partida y se realiza un proceso de descomposición en problemas más pequeños, proceso que se repite hasta llegar a problemas elementales que pueden ser solventados mediante funciones más simples. Finalmente, se realizan diferentes llamadas entre estas funciones, de forma que den solución al problema de partida.

image

Definición

Función

Conjunto de sentencias escritas en un lenguaje de programación, que utilizan unos parámetros para producir un resultado.

2.2. Orientación a objetos

La Programación Orientada a Objetos (POO) no consiste simplemente en nuevas características añadidas a las técnicas de programación estructurada y modular, es una nueva forma de pensar sobre el desarrollo de software y el proceso de descomposición de problemas.

Con la orientación a objetos el proceso se centra en simular los elementos de la realidad que están asociados al problema, ajustándose más al pensamiento humano que al comportamiento de la máquina, por lo que está más cercana a cómo se expresarían las cosas en la vida real.

Grady Booch, autor de Análisis y diseño orientado a objetos, define la Programación Orientada a Objetos como:

Un método de implementación en el que los programas son organizados como colecciones cooperativas de objetos, cada uno de los cuales representa una instancia de alguna clase, y cuyas clases son miembros de jerarquías de clases unidas a través de una relación de herencia.

Las aplicaciones orientadas a objetos están formadas por un conjunto de objetos que interaccionan entre sí enviándose mensajes. Los objetos similares se abstraen en clases, que son las que definen su comportamiento. Se dice que un objeto es una instancia de una clase.

image

Importante

Los valores que se asignan a los atributos de un determinado objeto hacen que ese objeto sea único.

La clase define su comportamiento y sus características generales.

La POO es un método de implementación en el que los programas están organizados como colecciones de objetos, pertenecientes a alguna clase. Una clase es la representación de un concepto y contiene toda la información necesaria para abstraer dicho concepto:

  1. Los datos, llamados “atributos”, que almacenan la información y describen su estado.
  2. Las operaciones, llamadas “métodos”, que definen el comportamiento del objeto y actúan sobre sus datos. Al indicar a un objeto que ejecute una operación, se dice que se le pasa un mensaje.

image

Recuerde

En la programación estructurada, los datos y los procesos están separados, ya que el objetivo es el procesamiento de unos datos de entrada para obtener como resultado una información de salida.

En la POO, los objetos agrupan los datos y los procesos (que actúan sobre esos datos).

2.3. Ventajas e inconvenientes

La POO presenta estas ventajas respecto a la programación estructurada:

  1. Ocultación de la información, que hace que las aplicaciones sean más fáciles de mantener, ya que se ocultan los detalles de la implementación.
  2. Encapsulado de datos y procedimientos, que permite mayor nivel de abstracción y facilita la descomposición del sistema en elementos más pequeños.
  3. Herencia de clases, que permite reutilizar su comportamiento sin necesidad de reescribir el código.
  4. Reusabilidad de clases ya definidas y probadas, pues con un diseño adecuado es posible que sean reutilizadas en otras aplicaciones.
  5. Fiabilidad, ya que al dividir el problema en partes más pequeñas es posible realizar la prueba de manera independiente y aislar con mayor facilidad los posibles errores que pudieran surgir.

Por el contrario, tiene los siguientes inconvenientes:

  1. Cambio en la forma de abordar el diseño de la aplicación, lo que requiere un análisis más exhaustivo.
  2. Complejidad en la implementación, que no facilita el desarrollo en aplicaciones pequeñas.
  3. Mayor curva de aprendizaje, ya que el dominio de las técnicas fundamentales de la POO es más complejo.

image

Actividades

1. ¿Qué ventajas de la programación orientada a objetos considera más importantes?

2. Además de los inconvenientes indicados, ¿ha identificado algún otro?

3. Ocultación de información (information hiding)

Un concepto muy importante de la orientación a objetos es la ocultación de la información, que permite definir de qué forma son accesibles los atributos y métodos de una clase.

De una forma básica, la ocultación consistiría en aislar la información (atributos) de forma que solo pueda ser modificada mediante las operaciones definidas para la clase (métodos).

Con la ocultación, se consigue proteger la información, evitando que se haga un mal uso de ella. La información no podrá ser modificada directamente, ya que cualquier cambio se realizará a través de alguno de los métodos definidos para la clase. Estos métodos incluirán las comprobaciones necesarias para asegurar que la información se modifica de forma adecuada.

image

Definición

Array

Permite contener elementos del mismo tipo en una zona de almacenamiento continuo.

image

Ejemplo

Una aplicación pretende registrar la nota media de cada uno de los 25 alumnos de un curso, para lo que define un array de 25 posiciones que pueda almacenar valores numéricos con decimales.

Al utilizar un enfoque orientado a objetos, se define la clase “curso”, con el atributo “nota_media” que se corresponde con el array de notas. Habría dos opciones:

  1. Si no se aplica el principio de ocultación, los objetos de la clase “curso” tendrán el atributo “nota_media” visible para el resto de los objetos de la aplicación, por lo que cualquiera podrá modificarlo sin ningún tipo de control, indicando valores negativos o demasiado altos.
  2. Al aplicar el principio de ocultación, se definirá el atributo “nota_media” como privado (de forma que no sea visible para el resto de los objetos), y se crearán los métodos públicos “leer_nota” (que devuelve la nota media de un alumno) y “grabar_nota” (que registra la nota media de un alumno).

Aplicando la ocultación, se consigue que la aplicación sea más robusta, ya que cualquier información que se quiera leer o escribir debe utilizar alguno de los métodos definidos, que contendrán las validaciones necesarias para evitar que se introduzcan valores erróneos (negativos o demasiado grandes) o que se muestren valores que aún no han sido informados (no inicializados o nulos).

La ocultación da lugar a que en las clases puedan identificarse dos partes bien diferenciadas:

  1. Interfaz: se corresponde con la visión externa de una clase. Es el conjunto de miembros que son accesibles por los demás elementos del sistema.
  2. Implementación: se refiere a la parte oculta, que incluye los mecanismos que conducen al comportamiento deseado.

Existen distintos niveles de ocultación, que definen el tipo de acceso que se permite a atributos y métodos:

  1. Público: permite que sea accesible desde cualquier clase y desde cualquier parte del programa.
  2. Privado: se permite acceder desde operaciones de la propia clase.
  3. Protegido: permite el acceso desde operaciones de la propia clase o de clases derivadas.

image

Definición

Clase derivada

Concepto que está relacionado con el de herencia, donde parte de la funcionalidad ha sido definida en otra clase (clase base o padre) y es reutilizada en la clase derivada (clase hija).

Al definir la visibilidad de una clase, habrá que tener en cuenta:

  1. Los atributos de una clase deberían ser privados, para que solo sean modificados mediante métodos de la propia clase.
  2. Los métodos de la clase deberían ser públicos.
  3. Los métodos que definen las operaciones que ayudan a implementar parte de la funcionalidad deberían ser privados (si no se utilizan desde clases derivadas) o protegidos (si se utilizan desde clases derivadas).

image

Recuerde

Los objetos de una clase son cajas negras, ya que no es posible saber cómo llevan a cabo internamente las operaciones, basta con saber cómo utilizarlos.

Al crear objetos de una clase, solo se conoce su interfaz, pero no su implementación; por tanto, un cambio en la implementación de una clase (si no se modifica su interfaz) es transparente para los programas que la utilizan.

image

Ejemplo

La clase “curso” utilizada en el ejemplo anterior podría tener el método “listar” para mostrar todas las notas ordenadas de mayor a menor.

Este método funciona correctamente, pero se ha detectado que su ejecución es un poco lenta.

Sería posible modificar la implementación de este método para aplicar algún otro algoritmo de ordenación más eficiente y, como no es necesario modificar su interfaz (nombre del método, parámetros y valor de retorno), este cambio no afectará a los objetos de la aplicación que lo utilicen.

image

Actividades

3. Amplíe información sobre los distintos niveles de ocultación, identificando si existe algún otro tipo menos utilizado.

4. El Tipo Abstracto de Datos (ADT). Encapsulado de datos

Con los lenguajes de programación estructurados surgió el concepto de tipos de datos (también llamados tipos de datos primitivos), que definen el conjunto de valores que pueden ser almacenados. Los más comunes son: enteros, decimales, cadenas alfanuméricas, fechas, etc. Pero estos tipos de datos primitivos empezaron a ser insuficientes, ya que los desarrolladores tenían la necesidad de definir los suyos propios.

Los Tipos Abstractos de Datos, cuyo acrónimo es TAD (o ADT si se utiliza la nomenclatura inglesa), son tipos de datos que pueden ser definidos por el programador para agrupar características y comportamientos similares, por lo que aplican el principio de abstracción.

image

Definición

Abstracción

En informática, la abstracción consiste en aislar un elemento de su contexto o del resto de los elementos que lo acompañan.

De la misma forma que se crean variables a partir de los tipos de datos primitivos, también pueden crearse variables a partir de los TAD definidos en el propio programa. Un TAD no define solo el conjunto de valores que puede almacenar, sino también las operaciones que pueden realizarse sobre ellos.

image

Importante

La abstracción es la base de la orientación a objetos, ya que permite la creación de un conjunto de clases para modelar el problema que se desea solventar.

El encapsulado de datos permite agrupar a un mismo nivel de abstracción todos los elementos que están relacionados con una misma entidad. De esta forma, se consigue aumentar la cohesión y robustez de los elementos que forman el sistema.

image

Ejemplo

La aplicación que se ha utilizado anteriormente como ejemplo para el registro de la nota media del alumnado podría haberse desarrollado siguiendo una estructura tradicional:

  1. Definiendo un array para almacenar cada nota y variables independientes para registrar la máxima y la mínima.
  2. Creando funciones para realizar operaciones con el array, ordenación, cálculo de la nota máxima, mínima, etc.

Pero con un enfoque orientado a objetos se realizaría un encapsulado de todos los elementos que estén relacionados, definiendo la clase “curso”, que agrupa tanto los datos como las operaciones que se realizan sobre esos datos.

El encapsulado de datos y la ocultación de información permiten reducir el número de errores que pueden producirse en una aplicación, ya que en un sistema orientado a objetos estos dependen unos de otros y, si uno de ellos falla, bastará con modificar su implementación y no será necesario modificar los demás objetos.

image

Sabía que

Es habitual confundir el concepto de encapsulamiento con el de ocultación, ya que ambos son utilizados de manera conjunta.

Al encapsular los datos y las operaciones, también se debería realizar una ocultación de aquellos que deban ser protegidos del mundo exterior.

image

Actividades

4. Explique la diferencia que existe entre los tipos abstractos de datos y las variables y detalle qué tipo de relación tienen.

5. ¿Qué elementos de la programación orientada a objetos serían los equivalentes a los tipos abstractos de datos y las variables?

image

Aplicación práctica

Se está iniciando el diseño de una aplicación para gestionar las facturas que se emiten a los clientes de una ferretería. En una primera reunión con los responsables de la empresa, se ha decido utilizar un enfoque orientado a objetos y que la próxima semana se plantee un borrador inicial de cómo podría ser la estructura de la aplicación.

SOLUCIÓN

Como se está en una etapa muy temprana del diseño, solo es posible identificar las clases más importantes y algunos de sus métodos y atributos más importantes. Cuando se tenga mayor detalle de la funcionalidad a implementar, se podrá completar el diseño de las clases.

En primer lugar, se deben abstraer los elementos que van a componer la aplicación, encapsulando sus datos y operaciones. De esta forma, se identificarán las clases que van a componer el sistema:

  1. Cliente: contiene los datos de un cliente (NIF, nombre, dirección, teléfonos, datos fiscales, etc.) y las operaciones que se pueden realizar sobre esos datos (cambiar dirección, modificar teléfono, mostrar ficha, etc.).
  2. Producto: agrupa la información de un producto (código, descripción, precio, tipo de IVA, stock en almacén, etc.) y sus operaciones (cambiar precio, cambiar stock, etc.).
  3. Factura: como datos de la factura se tendrán el código, la fecha de emisión, el cliente y una lista de los productos que la componen. Las operaciones habituales serán la modificación del cliente, el cambio de la fecha y la asignación y eliminación de productos.

5. Paso de mensajes

Con la orientación a objetos, las aplicaciones están formadas por un conjunto de objetos que interaccionan entre sí. Al indicar a un objeto que ejecute una operación sobre otro objeto, se dice que se le pasa un mensaje.

Un objeto se comunica con otros mediante mensajes. Cada mensaje implica la ejecución de un método sobre el objeto de destino, que ejecutará la operación correspondiente.

image

Importante

Los mensajes son la vía de conexión de un objeto con el mundo exterior, lo que le permite comunicarse con otros objetos del sistema.

Los objetos realizan acciones cuando reciben mensajes y solo es posible acceder a estos objetos a través de su interfaz pública.

Los métodos son procedimientos que son invocados cuando un objeto recibe un mensaje. En la programación tradicional, un mensaje se correspondería con la llamada a una función.

image

Nota

Mientras que un método es el procedimiento o función que es invocado para actuar sobre un objeto, el mensaje se refiere a la petición realizada.

Un mensaje es la petición de un objeto a otro, al que se le solicita ejecutar uno de sus métodos, por lo que se establece el convenio de denominar “emisor” al objeto que envía la petición y “receptor” al que la recibe.

En la estructura de un mensaje, se identifican los siguientes elementos:

  1. El objeto receptor que recibe la petición.
  2. El método que se desea ejecutar en el objeto receptor.
  3. Los parámetros que necesita el método para ejecutar la acción.
  4. La información que devuelve el método tras su ejecución.

Una vez que el receptor acepta el mensaje, ejecuta la acción que corresponda y, en algunos casos, retornará un valor.

El emisor solo necesita saber la estructura de los mensajes que aceptará el receptor, es decir, el nombre de sus métodos, los valores que recibe y los que devuelve; no es necesario conocer cómo se ejecutarán las acciones que dan respuesta a la petición. Una vez que el receptor acepta un mensaje, es el responsable de llevarlo a cabo.

La principal diferencia de un mensaje con respecto a la llamada a una función de la programación tradicional está en la obligación que tienen los mensajes de identificar al objeto receptor; de hecho, la interpretación del mensaje será diferente dependiendo del receptor.

Aunque haya objetos de diferentes clases que tengan métodos con el mismo nombre y parámetros, las acciones a ejecutar podrán ser diferentes. El mismo mensaje originará acciones distintas en función de a quién vaya dirigido.

image

Ejemplo

De la clase “curso” podrán instanciarse tantos objetos como cursos se deseen gestionar. Para el curso de “Contabilidad Financiera” se creará el objeto “contabilidad”, para el de “Gestión de Redes” el objeto “redes”, etc.

Todos estos objetos son instancias de la misma clase, por lo que tienen los mismos métodos y atributos (con valores diferentes); pero reciben mensajes diferentes, ya que cambia el objeto receptor del mensaje.

Un mismo objeto también recibe mensajes diferentes al ejecutar cada uno de sus métodos.

También es posible ejecutar un método con distintos parámetros, por lo que cambiará el correspondiente mensaje.

6. Resumen

La orientación a objetos aporta un nuevo enfoque al desarrollo de software, ya que obliga a cambiar la forma de pensar para realizar la descomposición del problema y el diseño de la aplicación.

Los programas se estructuran como colecciones de objetos que interactúan entre sí. Cada objeto es una instancia de una clase, que encapsula los datos y las operaciones para abstraer un determinado concepto.

La ocultación de la información va a permitir que pueda definirse el tipo de acceso a los elementos de una clase, haciendo posible diferenciar la interfaz pública de su implementación interna.

Los objetos se comunican entre sí a través de mensajes. Cada mensaje se corresponde con la ejecución de un método sobre el objeto de destino, que será el responsable de ejecutar la operación correspondiente y generar una respuesta.

Image

Ejercicios de repaso y autoevaluación

1. En relación a la orientación a objetos, ¿qué afirmación es la más adecuada?

  1. La ocultación de información dificulta la comprensión del código, ya que el programador no puede ver su implementación.
  2. Hace más compleja la reutilización, ya que obliga a tener que reescribir el código para cada clase.
  3. El encapsulado de datos y procedimientos facilita la descomposición del sistema en elementos más pequeños.
  4. Las aplicaciones creadas son difíciles de mantener, ya que los objetos están muy interconectados y cualquier cambio implica la modificación los demás.

2. De las siguientes afirmaciones, indique cuál es verdadera o falsa.

  1. La programación estructurada y modular son complementarias.
  2. La programación orientada a objetos es un complemento a la programación estructurada y modular.
  3. Una clase permite abstraer las características y el comportamiento de una entidad del mundo real.
  4. La ocultación impide que pueda diferenciarse el interfaz de la implementación.

3. Complete la siguiente frase.

Las aplicaciones orientadas a objetos están formadas por un conjunto de _____________ que interaccionan entre sí enviándose _____________. Los objetos similares se abstraen en _____________, que son las que definen su comportamiento. Se dice que un _____________ es una instancia de una _____________.

4. ¿Qué término define el concepto de aislar un elemento de su contexto o del resto de los elementos que lo acompañan?

  1. Visibilidad.
  2. Abstracción.
  3. Ocultación.
  4. Herencia.

5. A la hora de definir la visibilidad de los elementos de una clase, indique la recomendación que es incorrecta.

  1. Los atributos deberían ser privados, para que solo sean modificados mediante métodos de la propia clase.
  2. Los métodos que definan operaciones externas deben ser públicos.
  3. Los métodos que definan operaciones internas que van a ser utilizadas por las clases derivadas deberían ser privados.
  4. Es posible crear atributos públicos.

6. De las siguientes afirmaciones, marque la incorrecta.

  1. La abstracción y el encapsulamiento son conceptos similares.
  2. El encapsulado de datos y la ocultación son conceptos incompatibles.
  3. El encapsulado de datos y la ocultación se utilizan de manejan conjunta.
  4. El encapsulado de datos es un concepto fundamental de la orientación a objetos.

7. Una ventaja de la programación orientada a objetos, con respecto a la programación estructurada presenta es que

  1. … las aplicaciones son más fáciles de mantener.
  2. … las aplicaciones son más difíciles de mantener.
  3. … no se pueden reutilizar las clases definidas y probadas.
  4. … tiene la misma curva de aprendizaje que la programación estructurada.

8. En relación con las ventajas de la orientación a objetos, asocie cada término con su correspondiente definición.

  1. Ocultación.
  2. Encapsulado.
  3. Herencia.
  4. Fiabilidad.

9. Defina los conceptos de interfaz e implementación.

10. Complete la siguiente frase.

El tipo de acceso que se permite a _____________ y _____________ hace que se definan distintos niveles de ocultación. El _____________ hace que solo sean accesibles desde operaciones de la propia clase, el _____________ permite el acceso desde la propia clase o desde clases derivadas y el _____________ permite el acceso desde cualquier clase y desde cualquier parte del programa.

11. Si un atributo ha sido definido como “protected”, ¿desde dónde se puede acceder a la información que contiene?

  1. Desde cualquier parte de la aplicación.
  2. Desde la propia clase y sus clases derivadas.
  3. Solo desde los métodos de la propia clase.
  4. Desde sus clases derivadas.

12. De los siguientes elementos, marque el que no pertenezca a la estructura de un mensaje.

  1. El método que es ejecutado en el objeto receptor.
  2. Los parámetros necesarios para ejecutar la acción.
  3. El objeto receptor que recibe la petición.
  4. El método que realiza la petición en el objeto emisor.

13. Complete la siguiente frase.

La principal diferencia de un mensaje con respecto a la llamada a una _____________ de la programación tradicional está en la _____________ que tienen los mensajes de identificar al objeto _____________; de hecho, la interpretación del mensaje será diferente dependiendo del _____________.

14. En relación a los Tipos Abstractos de Datos, indique la afirmación incorrecta.

  1. Aplican el principio de abstracción.
  2. También se denominan tipos de datos primitivos.
  3. Encapsulan datos y operaciones.
  4. Pueden ser definidos por el usuario.

15. Las instrucciones secuenciales, alternativas y repetitivas

  1. … solo se pueden utilizar en la programación estructurada.
  2. … se usan únicamente en la programación estructurada y modular.
  3. … no es recomendable que sean utilizadas en la orientación a objetos.
  4. … son utilizadas tanto en la programación estructurada y modular como en la orientada a objetos.