> Manuales > Teoría de la Programación Orientada a Objetos

Cuáles son los beneficios que nos aporta la Programación Orientada a Objetos: Abstracción, Encapsulación, Modularidad, Jerarquización.

Hace poco hicimos un vídeo de una clase de Programación Orientada a Objetos, que nos ofrece las bases y fundamentos de este paradigma de la programación. La clase la impartió Luis Fernández y nos aclaró muchos detalles de los cuales queremos ahora hablar. Se trata de ahondar en torno de varios conceptos que son básicos para entender los beneficios de la Programación Orientada a Objetos.

Son varios conceptos que encontramos presentes en los lenguajes de programación más modernos, por lo que ya no solo se trata de "objetos" sino de programación en general. Nuevos lenguajes con nuevos paradigmas no hacen más que proporcionarnos herramientas para que podamos los programadores potenciar al máximo la presencia de los beneficios que vamos a explicar en este artículo. Son además la base de la evolución de los lenguajes, que han marcado la historia de la programación.

Nota: Este es un artículo un tanto teórico sobre programación. Es un conocimiento básico para asentar los conocimientos de Programación Orientada a Objetos sobre unos cimientos más sólidos, pero si lo que estás buscando es una explicación directa sobre lo que son objetos, clases y esas cosas, puedes leer el artículo Qué es la Programación Orientada a Objetos.

Comenzamos enumerando los conceptos que vamos a tratar: Abstracción, Encapsulación, Modularización y Jerarquía.

Abstracción

Es un proceso mental por el que se ignoran las características de algo, quedándonos con lo que realmente nos importa. La clave para entenderlo es "proceso mental", así que nos tenemos que poner a pensar, extrayendo aquello que realmente nos importa e ignorando lo superfluo.

La abstracción es algo que hacemos constantemente los humanos en nuestro día a día. Si no lo realizáramos nuestro cerebro se colapsaría con toda la información que nos rodea. Por ejemplo, para ir a la universidad o al trabajo vas en autobús. ¿Cuál es la abstracción del autobús? Es aquello que nos interesa como pasajeros, el precio del billete, la línea que recorre, el horario de las salidas, etc. No nos importa si se mueve con gasolina, gas o electricidad. Tampoco nos importa su cilindrada, potencia, consumo, la empresa que lo fabricó o el año en que lo hizo, ni la edad del conductor, por poner varios ejemplos. Así pues nos estamos abstrayendo de muchos detalles y quedándonos con lo fundamental.

Sin embargo, la abstracción es un proceso subjetivo. El mecánico del autobús realizará otro tipo de abstracción quedándose con determinados detalles que por su profesión le interesan. Por ejemplo, a él sí le importará si es diesel o gasolina, el fabricante, año, tipo de motor, transmisión, suspensión, etc.

Una forma de manejar la complejidad del software es conseguir escribir código de tal manera que permita la abstracción. En ensamblador, la aplicación más grande que podían hacer era de 10.000 líneas de código. Luego, con los lenguajes de alto nivel llegaron a 100.000, 300.000, 600.000 y eso se consiguió gracias a la abstracción procedimental. Por tanto, en la programación tradicional, la incorporación de las funciones o procedimientos trajo consigo una abstracción que cambió el mundo. Algo tan simple como tener funciones que realizan procedimientos y a las que podemos invocar enviando parámetros, abstrayéndonos de su complejidad. El algoritmo de esa función puede estar hecho de mil maneras distintas, recursivo, iterativo, con un bucle for, while, etc. Pero todos esos detalles le importan absolutamente nada a quien va a llamar a esta función, sino que lo esencial para él es el nombre de la función, los parámetros y el tipo de retorno.

Encapsulación

Es el proceso por el cual se ocultan los detalles del soporte donde se almacenan las características de una abstracción. En este punto el detalle clave para entender está en la palabra "soporte". Cuando encapsulamos estamos guardando cómo se soporta algo, como se almacena, qué medio es, cuál es su nombre, etc. Lo vas a entender mejor con un ejemplo.

Es como cuando te dan un medicamente encapsulado, donde tú no ves lo que hay dentro. Solo puedes tocar la cápsula pero no ves si dentro hay polvo, un comprimido, el color que tiene, etc. Nadie quiere que manosees el medicamento y por ello te lo entregan encapsulado. Te dicen "tómate esto" pero no te permiten tocar ni ver lo que hay dentro. Probablemente porque la cápsula está preparada para disolverse en el lugar correcto y no interactuar con saliva de la boca, o quizás con los jugos intestinales. Te venden un ordenador y te lo dan encapsulado, para que no lo abras. De un ordenador no tocas lo que hay dentro, solo tocas aquello que quieren que toques, como el teclado, ratón, botón de encendido y apagado, etc.

En la informática la encapsulación es algo también habitual. Piensa en una fecha. Primero tenemos una abstracción que sería "día / mes / año" (de todo lo que nos puede decir una fecha quedarnos con tres datos funamentales). Ahora, una fecha la puedo guardar de muchas maneras, con tres variables que mantienen esos valores, llamadas dia, mes y año. Aunque las variables podían estar en inglés, day, month, year. También podríamos usar un array de tres elementos donde tengo esos tres valores, o con el número de segundos transcurridos desde una fecha dada (conocido como "tiemstamp" así guardan la fecha tradicionalmente sistemas operativos como Linux). O quizás quieras guardar un simple string. Si un programador al escribir un programa te oculta deliberadamente el cómo ha almacenado esa fecha, entonces está encapsulando.

Además hay que añadir que, si un programador da a conocer cómo guardaba esa fecha (por ejemplo usó tal y tal variable) y deja que los demás toquen esas variables libremente, estará provocando serios problemas. Uno programa un tratamiento para la fecha y potencialmente infinitas personas lo pueden usar. Pero si todos acceden a las características fundamentales de la abstracción de la fecha (esas variables) y las manipulan se produce el problema: El día que el programador de la fecha se arrepiente y quiere empezar a tratar la fecha de otro modo, por ejemplo con el "timestamp" (número de segundos desde 1970), porque observa que hay una sensible mejoría en los procesos internos del programa al usar ese soporte, obligaría a todos los que usan fechas a cambiar su código. Es decir, si infinitas personas mencionan las variables con las que aquel programador guardaba la fecha (las características esenciales de la abstracción), todos los programadores que usaban la fecha van a tener que actualizar su código para acceder ahora a otra variable y tratar la fecha de una manera diferente, produciéndose un acoplamiento feroz que deriva en oleadas de mantenimiento y pérdidas de dinero en horas de trabajo.

El primer momento donde apareció encapsulación en el mundo de la programación fue con las variables locales de las funciones. Las variables locales son propias de una función y no pueden mencionarse desde fuera, luego están encapsuladas. Y ojo que no siempre los lenguajes permitían encapsulación, los ingenieros tardaron en darse cuenta que era beneficioso no tocar las variables que habían dentro de una función.

Para acabar hay que insistir en que no se oculta la información, aquel programador que programó la fecha te tiene que informar en todo momento sobre el día el mes y el año, si se lo pides, lo que no te deja saber ni tocar son las variables o cualquier otro soporte mediante el cual está almacenando la fecha.

Modularización

Es la descomposición de un sistema, creando una serie de piezas que colaboran entre si, poco acoplados y cohesivos. Modularidad es tomar un sistema y tener la capacidad de segmentarlo en diversas partes independientes, que tengan sentido.

Como sistema entendemos el concepto amplio que todos debemos de tener en la cabeza. Por ejemplo, un ser vivo (una planta, el hombre…), o parte de un ser vivo (el sistema nervioso, circulatorio, etc.), o cualquier tipo de producto u organismo (desde un coche, una bicicleta, a una universidad o empresa, el sistema solar, etc). En cualquiera de estos sistemas debemos de reconocer diversas partes y podremos observar que todas colaboran entre si para llevar a cabo un objetivo o conjunto de tareas.

Como acoplamiento entendemos los cambios en piezas y el grado de repercusión en otros elementos del sistema. Es decir, tengo una pieza del sistema y la cambio. Inmediatamente eso repercute a otras piezas del sistema, de modo que a ese grado de repercusión le denominamos acoplamiento. Poco acoplado quiere decir que los cambios en elementos del sistema repercuten poco en otros.

Por ejemplo, en una universidad, si le ocurre algo al rector no es motivo para que la universidad deje de funcionar. Probablemente los profesores no se estén enterando que el rector ha fallecido y sigan dando la clase sin ningún tipo de interrupción. Eso es porque el rector está poco acoplado con otras piezas de una universidad.

Los mejores sistemas son poco acoplados, porque me permiten hacer cambios en las piezas sin que éstos repercutan en realizar cambios en otras partes del sistema. Pero podrá haber sistemas más acoplados y menos acoplados, porque acoplamiento siempre va a existir. Si tenemos una pieza que no tiene ningún acoplamiento con ninguna otra del sistema probablemente es que forma parte de otro sistema. Por ejemplo, la uña del dedo gordo del pie tiene cero acoplamiento con otras piezas del sistema respiratorio y eso es porque no forma parte de ese sistema. En resumen, si una pieza no colabora con nadie, simplemente se debe a que no forma parte de ese sistema y por tanto, hay que reducir los acoplamientos, no anularlos.

Cohesión en un sistema bien modularizado implica que sus módulos deben ser entendibles por si mismos. El término viene de coherencia y quiere decir que las partes de un sistema deben funcionar de una manera dada en todas las ocasiones y además ese funcionamiento debe entenderse bien, sin que para ello necesites explicar otra cantidad indeterminada de datos adicionales que quizás no forman parte de esa pieza.

En términos de programación, un módulo cohesivo se ve cuando consigues explicarlo atendiendo a su propio código. Si al explicarlo tienes que hablar de código que está disperso por otros lugares, otras estructuras guardadas en variables ajenas al módulo, entonces no es cohesivo. Si te dan un código de un módulo (una función, un procedimiento, clase…) y lo entendes sin recurrir a otras partes del proyecto, entonces es cohesivo.

La modularización va de la mano de la abstracción y la encapsulación, puesto que estos conceptos representan las herramientas necesarias para hacer módulos cohesivos y poco acoplados. Encapsular reduce los acoplamentos, porque los cambios en las cosas de dentro de un módulo no afectan al resto de los módulos del sistema.

La modularidad va de la mano de la abstracción. Si yo entiendo una pieza por si misma normalmente es que es una buena abstracción. Nos centramos en las características esenciales de algo, no es un conglomerado de cosas sin conexión o sin sentido. Por tanto, la abstracción correcta permite entender las piezas por si mismas y por tanto disponer de módulos cohesivos.

Jerarquización

Es la estructuración por niveles de los módulos o elementos que forman parte de un sistema. Es la forma de organizar los módulos, existiendo jerarquías de todo tipo y con diversos grados de dependencia, responsabilidad, incumbencia, composición, entre otros.

Jerarquías típicas podría ser algo como una factura, de la que dependen clientes, productos, total y otras informaciones. Podríamos tener jerarquías como los animales, en las que podemos clasificar vertebrados e invertebrados. Los vertebrados a su vez se dividen en mamíferos, aves, reptiles…

En programación jerarquías hay por todos lados. Algo tan simple como una expresión cualquiera "5 * 2 + 3 * 8" es una jerarquía, en la que tenemos el "+" arriba y luego abajo las expresiones "5 * 2" y "3 * 8", las cuales se pueden descomponer en otras jerarquías. Las funciones que llaman a otras y éstas que llaman a otras, forman en si una jerarquía. Los programadores usamos esa jerarquía de funciones para descomponer nuestro código y dominarlo, en lugar de nadar entre cientos de líneas de código que se hacen difíciles de manejar. En programación orientada a objetos, las jerarquías las forman las clases, las cuales unas se apoyan en otras para llevar a cabo las tareas, ya sea mediante herencia o composición, que veremos más adelante.

Conclusión

Los cuatro conceptos que hemos visto en este artículo son fundamentales y están relacionados. La abstracción y la encapsulación están relacionados porque la encapsulación oculta los detalles de una abstracción. Están relacionados con la modularidad, porque para ser poco acoplados tienen que encapsular y para ser cohesivos deben ser buenas abstracciones. La jerarquía está relacionada con los módulos ya que éstos deben estar organizarlos por niveles, con algún tipo de jerarquía, ya sea de composición, clasificación, o alguna otra.

Los cuatro conceptos son fundamentales y por ello volveremos muchas otras veces sobre ellos al explicar la programación orientada a objetos. Son esenciales para que tu código se entienda bien, se pueda cambiar, se pueda ampliar, se pueda adaptar a otra plataforma, para aumentar la reutilización.

Tenéis que agradecer el conocimiento a Luis Fernandez y la transcripción a Miguel Angel Alvarez. Recordar que tenéis el vídeo completo de la clase de los fundamentos de la programación orientada a objetos, con estas descripciones y muchas otras en nuestro canal de Youtube. Otros artículos sobre objetos los encuentras en el Manual de Programación Orientada a Objetos.

Luis Fernández Muñoz

Profesor de la Escuela Superior de Informática de la UPM

Manual