Te presento los patrones de diseño

Te presento los patrones de diseño

        Click here to view this post in English

Los patrones de diseño son como herramientas especializadas que ya están comprobadas y listas para solucionar esos problemas que suelen surgir una y otra vez durante el desarrollo de software. Es como tener un conjunto de técnicas probadas que te permiten abordar de manera efectiva desafíos comunes en el ciclo de desarrollo.__

Contexto...

En mi experiencia personal, mientras aprendía a programar por mi cuenta, llegué a un punto en el que me sentí estancado.
A pesar de tener conocimientos básicos sobre lenguajes de programación y entender conceptos como sentencias y programación orientada a objetos, me encontré con un dilema: mis programas, aunque funcionaban, no estaban bien diseñados para escalar.
Lo que inicialmente parecía simple, pronto se convirtió en un desafío para mantener y desarrollar más a medida que crecía en complejidad.

Estaba en busca de una manera más profesional de desarrollar aplicaciones, pero me encontraba perdido sin saber por dónde empezar.
Afortunadamente, la vida me presentó a amigos con una vasta experiencia en el campo. Ellos me sugirieron investigar sobre Patrones de Diseño, especialmente el libro del famoso grupo conocido como "Gang Of Four", cuatro desarrolladores que en 1994 publicaron un libro titulado "Design Patterns: Elements of Reusable Object-Oriented Software".
Fue a través de esta lectura donde comencé a comprender los fundamentos de la arquitectura de aplicaciones, siendo solo la punta del iceberg de todo lo que aún tenía por descubrir en este fascinante mundo de la programación.

¿Que puedo lograr usando patrones de diseño?

Lo que lograrías sin patrones es básicamente lo mismo, pero la gran diferencia radica en que obtendrás una aplicación que no requerirá ser reconstruida desde cero cuando comience a expandirse. Además, contarás con una estandarización en el espacio de nombres de la solución, lo que te ayudará a recordar qué estabas pensando en el momento de escribir esa porción de código.

Tipos de patrones de diseño

Los patrones de diseño se clasifican en varios tipos, los cuales están vinculados con los tipos de problemas que resuelven.
Hay tres categorías principales: la creación de objetos, la composición de objetos y el comportamiento de los objetos. Un consejo importante sobre los patrones es "Si tienes un martillo no todo es un clavo", lo que significa que no todos los patrones de diseño se aplican en todos los programas, y definitivamente no hay un "Mejor Patrón". Cada patrón o combinación tiene sus pros y sus contras.
Ahora, hagamos una breve lista de los patrones de cada categoría.

Patrones Estructurales

Los Patrones Estructurales son aquellos que nos dicen cómo las clases se relacionan entre sí para formar estructuras más grandes. Esto nos ayuda a resolver problemas de una manera más organizada y eficiente.

![lego-car](http://alanriveros.com/wp-content/uploads/2024/01/2020-03-05-22-22-15-150x150.png)

       Adapter

El Patrón Adapter soluciona el tema de conectar dos interfaces distintas convirtiendo los datos para que puedan transmitirse entre ellas. Es como usar un adaptador eléctrico para pasar de un enchufe de dos patas a uno de tres patas. Es como cuando te comprás un aparato de afuera y necesitás usarlo acá en Argentina, pero los enchufes son diferentes. Con el adaptador, hacés que todo encaje y funcione sin problemas.
Adapter

        Bridge

El Patrón Bridge nos da la chance de separar una idea abstracta de cómo se lleva a cabo realmente.
¿Qué significa eso? Bueno, que el cliente no tiene ni idea de cómo se hacen las cosas por debajo, solo sabe que tiene que llamar a cierto método y listo. Esto es re útil porque nos permite cambiar cómo se implementan las cosas mientras el programa está en marcha, sin que el cliente ni se entere.
Así, logramos un desacoplamiento re copado y nos da libertad para cambiar las cosas sin afectar al resto del código.

        Composite

El Patrón Composite es como armar algo grande con piezas más chicas, tipo esos rompecabezas que te dan ganas de mandar todo al carajo.
Imaginate un árbol genealógico, ¿te acordás de esas cosas? Bueno, es algo así pero en código.
Por ejemplo, pensá en un juego como World of Warcraft, donde tenés todo un mundo 3D para explorar. Cada parte del juego, como personajes, enemigos o paisajes, se puede representar como un objeto en sí mismo, pero al mismo tiempo, todos juntos forman parte de algo mucho más grande. Es como armar un lego gigante con un montón de piezas más chiquitas, pero al final queda algo copado.
trees
En el mapa se nota que hay montones de árboles, ¿viste? Todos esos arbolitos son como modelos 3D que el juego va cargando. ¿Y sabés qué? Muchos de ellos son más parecidos que dos gotas de agua. Pero juntos, forman todo ese verde que ves en el juego, como si fuera un bosque de verdad, pero en el mundo virtual.

        Decorator

Mirá, para que te des una idea más clara, pensemos en un personaje de videojuego, digamos que es un arquero. Bueno, ya sabés, los arqueros usan sus arcos para atacar y cada arco tiene su poder. Ahora, ¿cómo hacemos para que nuestro personaje cambie de arco sin complicarnos la vida o sin hacer un código que parezca un laberinto?archer
Acá entra en juego el patrón Decorator. Este patrón nos permite agregar o quitar habilidades en el momento en que el juego está corriendo. Entonces, nuestro arquero puede usar arcos que parecen sacados de un cuento de hadas, sin que eso haga que el juego se vuelva más lento o que el código sea un desastre. Es como tener lo mejor de dos mundos: personalización sin romper todo.

        Facade

Ahora te voy a explicar algo que seguro te va a ayudar a entender mejor cómo funcionan algunas cosas en la programación. ¿Alguna vez te pusiste a pensar en cómo es el motor de un auto por dentro? Bueno, imaginate tener que entender y manejar cada pieza, cada cable, cada parte que hace funcionar el motor. Sería un lío, ¿no?
car panel
Bueno, en la programación pasa algo parecido a veces. Hay momentos en los que lidiamos con un montón de métodos y funciones, y saber el orden exacto en que tienen que ser llamados puede ser un dolor de cabeza. Acá es donde entra en juego el patrón Facade. Este patrón nos simplifica la vida, nos da una especie de "ventanita" fácil de usar para interactuar con todo ese "motor" de funciones complicadas. Es como tener un control remoto para el auto, todo en un solo botón. ¡Una maravilla!

        Flyweight

Cuando tienes muchos objetos con funciones similares, a veces es mejor agrupar esas funciones en una sola entidad externa. ¿Por qué? Porque eso te permite ahorrar memoria y hacer tu código más eficiente.
En lugar de tener mil objetos con métodos similares ocupando espacio, puedes tener uno solo que comparta esas funcionalidades. Así, liberas memoria y haces tu programa más liviano.
Como juntar todas tus herramientas en una caja, en lugar de tenerlas tiradas por toda la casa. ¡Más orden, menos lío!

        Private Class Data

El patrón Private Class Data nos brinda la posibilidad de resguardar ciertos atributos de un objeto, evitando que manos curiosas o distraídas los manipulen, especialmente cuando no podemos definirlos como constantes o final.
characcter creation
Imaginate que estás diseñando un panel para crear un personaje en un juego. Tienes que asignarle puntos de fuerza, agilidad, inteligencia y stamina, que serán vitales para su desarrollo a lo largo del juego. Una vez que el personaje está creado, estos atributos son cruciales, pues afectan directamente su desempeño en las batallas y misiones. Por eso, es fundamental protegerlos de modificaciones externas que podrían arruinar la experiencia de juego.

        Proxy

El patrón Proxy se emplea cuando utilizamos un objeto para representar a otro, y aunque pueda parecer inútil en principio, en ciertas circunstancias resulta de gran utilidad. Un ejemplo cotidiano del patrón Proxy es una tarjeta de débito.
credit cards
La tarjeta de débito gestiona los estados de cuenta que reflejan el saldo de efectivo disponible en el banco. Si necesitas utilizar esos fondos en forma real, puedes ir hasta el banco y retirarlos en persona, pero eso implica un costo de tiempo y esfuerzo mayor que simplemente usarlos a través de la tarjeta.

        Patrones Creacionales

Este tipo de patrón se encarga de controlar cómo se crean e instancian los objetos, liberando así a las demás clases del sistema de esa responsabilidad.
Es como cuando un mago invoca elementales: a nadie le importa cómo realmente los invoca, solo queremos usarlos para luchar.
invoker

        Abstract Factory

El patrón Abstract Factory nos ayuda a crear una instancia perteneciente a una familia. Por ejemplo vamos al caso del panel creador de personaje, tenemos las razas, Elfo, Gnomo, y Humano. Cada raza necesita un cuerpo, pero no sería posible asignarle a un Gnomo el cuerpo de un Humano. En estos casos el patrón Abstract Factory nos ayuda al momento de instanciar un Jugador pasarle a que familia de componentes pertenece y nuestro Gnomo puede empezar con el pie derecho y tener su cabeza, cuerpo y armas iniciales acorde con su raza.

        Builder

El patrón Builder nos permite delegar la creación de objetos complejos a otra clase.
dragon slayer sword cold sword
Por ejemplo, si necesitamos crear una Espada Matadragones de Fuego y otra Espada Matadragones de Hielo, ambas espadas necesitan diferentes componentes para ser creadas. Luego, necesitamos algo que los ensamble y nos entregue nuestra Espada. Estos actores son las partes de nuestro patrón Builder.

        Factory Method

Este patrón también nos sirve para delegar la creación de un objeto en otra clase, pero es más simple. El Factory Method le dice a un Factory Creator qué objeto quiere, sin saber cómo se crea, lo que beneficia al desacoplamiento.

        Object Pool

El patrón Object Pool ayuda cuando necesitamos optimizar recursos. Si tenemos un objeto costoso en recursos para ser instanciado y lo necesitamos temporalmente, como una animación de lanzamiento de hechizos, este patrón tiene un almacén de instancias que pueden ser llamadas y luego volver a estar disponibles para otra tarea.

        Prototype

naruto clones
El patrón Prototype establece un objeto modelo del cual se generan copias en tiempo de ejecución, como los clones en Naruto, que son exactamente iguales al original, inclusive en su estado.

        Singleton

El patrón Singleton asegura que solo haya una instancia de una clase en el sistema. Por ejemplo, podemos crear un NPC rey de la ciudad y estar seguros de que nunca habrá otro mientras ese rey siga vivo.

Patrones de Comportamiento

Estos patrones están orientados a la comunicación entre clases, asignación de responsabilidades y colaboración entre objetos.

        Chain of responsability

Este patrón ayuda cuando el procesamiento es secuencial, como en una línea de producción, donde el producto es procesado en una serie de etapas hasta alcanzar el estado deseado.

        Command

Este patrón nos ayuda a invocar rutinas o subprogramas sin saber realmente lo que hacen, como los elementales de agua en un juego, que pelean por nosotros sin necesidad de entender cómo lo hacen.
water elemental

        Interpreter

Este patrón trata con expresiones o sentencias que necesitan ser evaluadas, como entender palabras clave que un jugador tipea o reconocer un lenguaje extraño como el élfico.

        Iterator

Iterator ayuda a recorrer una lista o colección de objetos sin necesidad de conocer cómo se implementa la colección, solo llamando a ciertos métodos establecidos previamente.

        Mediator

Este patrón crea un mediador entre objetos, como en un sistema de chat, donde un mensaje se comunica a todos los participantes de la sala.

        Memento

Memento ermite guardar y restaurar el estado de un objeto en un momento dado, como guardar el estado de un juego RPG online para poder volver a un punto previo. Por ejemplo, cada media hora se puede hacer un guardado completo de los mapas con las ubicaciones de los jugadores, items y demas como back-up. En caso de que ocurra algo al estado actual del juego podremos volver al último estado guardado.

        Null Object

Evita errores cuando se referencia una dependencia nula, creando objetos sin comportamiento que evitan la explosión del programa.

        Observer

Permite que los "observadores" reciban actualizaciones de un "emisor" cuando cambia su estado.
Como cuando el "emisor" realice algún cambio, todos los suscritos reciban un mensaje con la actualización.

        State

El patron State se utiliza cuando un objeto tiene distintos comportamientos dependiendo de su estado, como un hechizo que puede estar activo o inactivo.

        Strategy

Strategy Delega la ejecución de un método a clases concretas, permitiendo cambiar el comportamiento del método en tiempo de ejecución.

        Template Method

Reduce el código duplicado al establecer una clase abstracta con comportamientos base compartidos por todas las clases hijas.

        Visitor

El patrón Visitor pAgrega funcionalidades a una clase sin modificarla, útil para agregar características como armas a un personaje sin modificar su clase base.

Conclusion

Los Patrones de Diseño son herramientas poderosas que pueden ayudar o entorpecer dependiendo de cómo se utilicen. Esta introducción es solo un vistazo, puedes explorar enlaces para conocer más detalles y ejemplos.

Nos saludamos en la próxima entrada.

< El último apaga la luz >