POO: Una particular forma de pensar
“Todas las cosas grandes, hermosas y complejas están compuestas de cosas pequeñas y simples que se comunican con otras cosas simples y pequeñas”
Este artículo está dirigido a quienes quieren entender cómo se modela y diseña un sistema de software, aunque también puede aplicarse a la creación de cualquier objeto en la vida real o virtual, de manera colaborativa.
Programación Orientada a Objetos (POO)
POO, siglas de Programación Orientada a Objetos, es un paradigma de programación, es decir, un estilo de programar que nos lleva a una forma particular de pensar. Se basa en cuatro principios fundamentales que usaremos para modelar un sistema que llamaremos “universo”: abstracción, herencia, encapsulamiento y polimorfismo.
Si por un momento pensamos en el universo, es “todo lo que nos rodea, incluyendo tu casa, la casa de tu vecino, el planeta, los planetas, las estrellas, las galaxias e incluso el tiempo. Antes de todo, no había nada.” Entonces surge la pregunta: ¿Cómo demonios modelamos esto?
La respuesta es la abstracción, que nos dice que cualquier cosa puede representarse como un objeto con propiedades y comportamientos (técnicamente conocidos como atributos y métodos). Veamos un ejemplo:
El sol, como objeto, tendría propiedades como: nivel de iluminación, nivel de calor, peso, velocidad de rotación y años de existencia. Sus comportamientos podrían ser: ejercer gravedad, emitir luz, proporcionar calor y dar vida.
Recordemos que el sol es una estrella. Si ahora queremos representar todas las estrellas del firmamento, ¿cómo lo hacemos? Podríamos crear cada estrella de manera individual, o simplemente crear una plantilla que defina las propiedades y comportamientos comunes de todas las estrellas. El sol sería entonces una implementación particular de esa plantilla estrella (en términos técnicos, a esta plantilla se le llama clase y contiene atributos y métodos).
Abstracción
Entre estrellas y planetas, ya entendemos el primer principio: la abstracción. Ahora pasemos a un segundo nivel para modelar casos relacionados pero diferentes. Por ejemplo, las estrellas en su lecho de muerte pueden convertirse en una enana blanca o en un agujero negro. Así que, modelemos al “hermano gemelo malvado” del sol.
Un agujero negro y nuestro sol no son tan distintos: ambos proporcionan gravedad, tienen rotación, peso, calor y luz. La diferencia es que, en un agujero negro, la gravedad es tan extrema que la luz no puede escapar, por lo que no brilla.
Si volvemos a la plantilla de estrella, no podríamos crear un agujero negro porque la plantilla define el comportamiento de “emitir luz”. Aquí entra en juego la herencia: creamos una nueva plantilla que extiende la de estrella y llamamos a esta nueva plantilla “agujero negro”. Así resolvemos el problema, e incluso podemos agregar condiciones específicas para el agujero negro, como que su temperatura sea cercana al cero absoluto y su gravedad infinita.
Al cambiar estas propiedades, aseguramos que el objeto se comporte como un agujero negro. Además, podemos modificar el comportamiento de “emitir luz” para que sea cero, o agregar un nuevo comportamiento, como “destrucción alrededor”.
Herencia
De esta forma, podemos agregar o anular propiedades y comportamientos en una plantilla base mediante la herencia.
Pero, ¿qué pasa si compartimos nuestras plantillas con amigos para que ellos creen sus propios objetos? Es probable que modifiquen tanto sus objetos que ya no respeten la definición original de la plantilla. ¿Cómo evitamos este desastre inminente?
Encapsulamiento
Para prevenir el caos, existe el tercer principio: el encapsulamiento. Esto implica establecer permisos para controlar qué propiedades y comportamientos pueden ser modificados por otros. De esta manera, un agujero negro seguirá siendo un agujero negro y no otra cosa.
Polimorfismo
¿Qué sucede cuando tenemos muchas plantillas y representaciones de objetos? Sería una locura agruparlas, identificar comportamientos o obtener resultados diferentes según las propiedades y comportamientos.
Aquí es donde entra el cuarto principio: el polimorfismo. Definimos contratos que obligan a los propietarios de plantillas a implementar ciertos comportamientos comunes, lo que nos permite trabajar en grupos o familias de objetos de manera ordenada. En términos técnicos, un contrato puede definirse como una clase abstracta o una interfaz.
Conclusión
En resumen, todo es un objeto. Define tus clases, atributos y métodos, agrúpalos bajo contratos, obtén resultados y, si no son los que esperabas, redefine hasta crear tu universo perfecto, donde quieras vivir.