lunes, 16 de junio de 2014

El Pensamiento Orientado a Objetos

Para desarrollar el concepto total de Pensamiento Orientado a Objetos, es importante tener en claro qué es la Programación Orientada a Objetos y en qué consiste así como sus características.
Es decir, como en una clase de biología, cuando se ven los tipos de métodos, aquí empezaremos de lo particular a lo general y a su vez, en algunos casos de lo general a lo particular.

Entender el Pensamiento Orientado a Objetos, quizás sea un poco difícil si eres un novato en la programación, si ya has programado en un lenguaje estructurado, verás que esto es mucho más fácil. Pero al mismo tiempo es significativo saber cómo funciona y por qué se dice que “programar en un lenguaje orientado a objetos es muchísimo más fácil que programar en un lenguaje estructurado”.

Bien, empecemos por definir ¿qué es la Programación Orientada a Objetos?
Sencillamente: es una manera de programar.
Sirve para crear aplicaciones o resolver algún problema.

Ahora, ¿cómo trabaja?

Bueno, la POO trabaja con objetos que vienen de clases y cada objeto tiene sus propios atributos.
Seguro, has de pensar ¿y eso qué quiere decir, qué es cada cosa?
Bueno, para empezar a entender la POO primero debes conocer los conceptos clave que se manejan, así que haré lo posible por explicar de la manera más sencilla qué es cada concepto y cómo se ve en POO.

-Objeto: entidad que tiene una o más funciones con características o atributos propios. En un diagrama UML se puede representar de la siguiente manera:
-Clase: es un modelo que define las características y funciones generales de todos los objetos que pertenecen a ella.

Cada clase viene de una súper clase, también denominada “clase abstracta”. Llamada así porque justamente generaliza los atributos de una clase. Y las clases a su vez pueden formar subclases. 

Veámoslo con un ejemplo representado en un diagrama UML:

Como ves “Triángulo” y “Círculo” pertenecen a la misma clase abstracta “Figura”, y así como conservaron los atributos generales, también poseen sus características especiales.

Al mismo tiempo que tenemos una clase, podemos tener Instancias, y una instancia, en términos sencillos es un objeto ya con sus atributos y funciones bien establecidos. En éste caso, podemos tener todas las instancias que queramos de una clase porque éstas son totalmente independientes una de otra. Entonces si hacemos un cambio a la clase, cada instancia se actualizará al momento y a su vez, si queremos cierto comportamiento en alguna instancia lo podemos hacer en ella y no afectará a las demás. Al mismo tiempo, si lo deseamos, podemos instanciar el mismo procedimiento a todas las instancias.

Como decíamos hace unos instantes, la POO posee ciertas características:

Abstracción: consiste en captar las características y comportamientos esenciales de un objeto.
Como vimos en el ejemplo anterior de la clase abstracta “Figura”, ésta abordaba las generalidades de las figuras geométricas como el cálculo de área y perímetro, así como la forma, entre otras cosas.
Jerarquía: consiste en la clasificación y organización de las abstracciones según su naturaleza.

Herencia: es la capacidad que tiene una clase de derivar las características y las funciones de otras. Esto nos permite no tener que volver a escribir el mismo código una y otra vez, puesto que al definir que cierta clase pertenece a una Súper clase, automáticamente estamos atribuyéndole las características generales de la clase abstracta. Y así ya no volvemos a escribir el código, ahorrando tiempo.

Encapsulamiento: se encarga de mantener ocultos los procedimientos internos que necesita hacer el objeto para llevar a cabo una función.

Por ejemplo, imagina que crearás un programa virtual, y harás una coreografía de baile. Tu pones los movimientos que deben seguir los objetos (sean humanos, perros, dinosaurios, círculos o gotas de agua) y en cada estribillo deben repetir los mismos movimientos. Esos movimientos que tú definiste para el coro lo llamas de una sola manera, creando así un paso, supongamos que tu paso se llama “viento”, de esa manera los bailarines sabrán que cada que tu les digas “viento”, los bailarines harán los movimientos que incluye “viento”, tal cual los movimientos que tú les dijiste y en el orden que tú lo dijiste. Entonces, para no repetir los mismos movimientos una y otra vez en el programa tú los encapsulas, es decir, declaras el procedimiento “viento”, le agregas los movimientos y los instancias en la clase que estás trabajando. De ésta manera, las demás personas que vean tu programa verán el paso “viento”, pero aunque los vean, no sabrán qué movimientos van en ése paso porque no verán la totalidad del código.

Así el código del programa queda más pequeño. Lo que hace más rápido también, el encontrar un error en el código que si fuese en un lenguaje estructurado. Pues al corregir el error, éste se aplicará a todas las partes del programa que contengan ése fragmento, (en éste caso sería “viento”) y su cambio no afectará al resto del programa.

Modularidad: consiste en dividir el programa en partes más pequeñas llamadas módulos y cada uno de ellos es independiente.

De ésta manera el código del programa es más pequeño y facilita el trabajo en equipo, agilizando la labor, puesto que cada persona puede encargarse de cualquier área del programa. Ya que lo que se realice en un módulo no afectará el desempeño del otro.

Polimorfismo: existen tres tipos de polimorfismo: sobrecarga, paramétrico y Subtipado.

El polimorfismo de sobrecarga ocurre cuando funciones del mismo nombre existen con funcionalidad similar en clases que son completamente independientes y diferentes. Esto nos permite definir operadores cuyos comportamientos varían de acuerdo a los parámetros que se aplican.
Por ejemplo, imagina que de nuevo te piden que crees una coreografía de baile, pero ésta vez debe ser en pareja y con clases diferentes. Tú decides tus pasos, sabes que existen bailes de pareja como el Tap en el que no necesariamente deben de estar abrazados o tomarse de la manos para hacerlo en pareja, así que si no mantienen contacto no hay problema realmente, sin embargo, forzosamente deben de estar coordinados, después de todo es un baile.

Entonces lo que tú tienes que hacer es tener clases que compartan funciones similares, y es allí donde entra el polimorfismo de sobrecarga, porque existen clases completamente independientes que tienen las mismas funciones. Por ejemplo un hada y un espía, ambos pueden saltar, estirar los brazos, las piernas, girar, caminar, etc. Fácilmente pueden crear una coreografía.

(Ahora piensa que lo único que los hace diferentes además del físico, es que el hada puede volar y el espía hace karate, incluso, si usas la imaginación, puedes crear pasos combinando éstas dos cosas, siempre y cuando coordines correctamente.) (Pero bueno, esto ya no tiene que ver con el polimorfismo).

El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando la misma clase, pero usando características diferentes.
Por ejemplo, cuando creas instancias, debido a que el objeto pertenece a la misma clase puedes definir las funciones que gustes, pero las características de cada objeto son diferentes.

El polimorfismo de Subtipado permite no tomar en cuenta detalles de una clase cualquiera para poder utilizarlas de igual manera en una clase abstracta.

Pues trabajan de manera similar. Como una gallina y un dinosaurio, aunque no sean similares, se puede trabajar con ambos, pues tienen funcionamientos comunes y pertenecen a la misma clase (podría ser “Animal” u “Ovíparo” pero esto ya depende en gran medida del lenguaje de POO)

Algo muy importante que todos debemos tener en cuenta cuando programamos en un lenguaje orientado a objetos (y por supuesto en cualquier situación que tengamos) son los pasos a seguir para la resolución de un problema. Puesto que hacerlo en orden y con prudencia nos dará mejores resultados.

Porque, como ya se explicó anteriormente, la POO se basa precisamente en situaciones reales.

Proceso de solución de problemas

1.-  Identificación del problema --> ¿Cuál es el problema?
2.- Encontrar el origen del problema --> ¿Por qué ocurrió?
3.- Producción de respuestas de solución --> ¿Qué puedes hacer para resolverlo?, da todas las opciones que se te vengan en mente.
4.- Examinar cada respuesta críticamente --> Piensa en las ventajas y desventajas de cada una.
5.- Seleccionar la solución más óptima --> La que presente más ventajas que todas, es la que debes de elegir, pues así evitarás más problemas.
6.- Comprobar en la acción la seleccionada --> Llévala a cabo, y si algo sale mal, modifícalo, o soluciónalo.

También es importante determinar de que se encargará cada objeto, y si tu trabajo se hace en equipo, también.

Para eso se utiliza la asignación de responsabilidades, en donde enlistas todo lo que necesitas hacer para llevar a cabo una tarea. Como ves, va de la mano de la resolución de un problema. Pues tú tienes qué elegir de qué se encargará cada uno para lograr el éxito.

Por ejemplo, en la misma coreografía de baile (sea la primera o la segunda), los objetos deben saber bailar, deben de estar vestidos de la manera que tú lo requieres y tú, por ser el programador, debes de crear la coreografía, armar el escenario, elegir la música, el vestuario, entre otras cosas. Así debe de ser, pues si cambiaras la asignación de responsabilidades jamás lograrías hacer el programa, y es sencillo: los objetos de tu programa no tienen vida.

Ventajas de la Programación Orientada a Objetos

-Fomenta la reutilización y extensión del código
-Permite crear sistemas más complejos
-Relaciona el programa con el mundo real
-Facilita la creación de programas visuales
-Agiliza el desarrollo del programa
-Facilita el trabajo en equipo
-Facilita el mantenimiento del programa

Síntesis

La POO es una manera de programar basada en el mundo real y como tal maneja objetos con atributos y funciones. Sirve para crear aplicaciones y resolver problemas. Sus características son la abstracción, la herencia, la jerarquía, el encapsulamiento, la modularidad y el polimorfismo. Para obtener mejores resultados al elaborar un programa con un lenguaje orientado a objetos es importante asignar bien las responsabilidades y resolver el problema con la mejor solución posible.