sábado, 13 de noviembre de 2021

Introducción a los patrones de diseño

Con este artículo comienza una nueva serie, que será el inicio de varias otras nuevas series, las cuales hablarán de diversas formas de mejorar la calidad de nuestro código, con el objetivo de hacerlo más mantenible, flexible, entendible, y mejor estructurado.

Con estas series busco brindarte una base formal que te ayude a afrontar problemas complejos y te prepare mejor para desarrollar tu carrera profesional.

En esa serie te explicaré qué son los patrones de diseño y hablaré de los patrones de diseño más comunes, y te mostraré diversas formas o estratégias para implementar cada uno de ellos.

En este primer artículo explicaré rápidamente qué son los patrones de diseño, cómo se clasifican, junto con una lista que se irá actualizando conforme vaya agregando más artículos.

Sin más, vamos al tema.


¿Qué son los patrones de diseño y por qué son importantes?

Cuando nos enfrentamos a un problema, pensamos en distintas soluciones para resolverlo, incluyendo soluciones exitosas que hemos aplicado en el pasado para el mismo o un problema similar.

Lo primero que debes saber cuando tratas de resolver un problema es que es muy probable que alguien más ya haya resuelto ese problema. No solo eso, sino que es probable que muchas personas ya hayan resuelto ese problema, hayan hablado de eso con sus colegas, en reuniones, en la cafetería, en foros, eventos especializados, etc. Que al final, se hayan dado cuenta de que es un problema común, hayan intercambiado distintas experiencias sobre cómo fue resuelto, esas experiencias se hayan documentado, recopilado, que varios otros miembros de la comunidad haya descartado algunas de esas soluciones, hayan probado varias de las soluciones no descartadas, y que al final la comunidad haya decidido cual o cuales son las mejores formas de resolver ese problema; se le haya dado un nombre, se haya clasificado junto con otros problemas similares, se hayan escrito libros, dado conferencias y cursos sobre estas mejores formas de resolver los problemas, se hayan hecho una o dos películas y documentales, etc., etc.

Los patrones de diseño entran dentro de la larga explicación del párrafo anterior (excepto, obviamente, por las películas y documentales; y sí, a mí también me frustra que haya una película sobre emojis, pero no sobre patrones de diseño). La gran ventaja que esto nos da es que no tenemos que empezar a experimentar desde cero una nueva solución, podemos buscar nuestro problema dentro de un catálogo y usar la solución que mejor se adapte a nuestro contexto particular. De esta forma reutilizamos la sabiduría de los que se enfrentaron al problema antes de nosotros.

Para explicarlo de una forma más sencilla: Los patrones de diseño son la abstracción de soluciones a alto nivel, probadas y reutilizables para problemas comunes en programación. El aplicarlos nos evitan el tener todos los problemas que conlleva reinventar la rueda.

Los patrones de diseño no han dejado de ser vigentes desde que fueron definidos hace ya muchos años.


Un poco de historia

La historia de los patrones de diseño comienza en 1977, pero no en el ámbito de software, sino en el de la ingeniería civil. En este año Christopher Alexander publica el libro "A Pattern Language Towns, Buildings, Construction". En este libro en lugar de hablar sobre los detalles de la construcción, Alexander se centra en los problemas comunes que enfrenta un trabajo de arquitectura. Estos problemas los explica de la forma más general posible, capturando solo su esencia. Con esto, logró que el libro hable de problemas generales y atemporales. En este libro también habla de las relaciones entre estos problemas.

¿Qué tiene que ver esto con el software? Pues bien, en 1994 un grupo de 4 sujetos: Erich Gamma, Richard Helm, Ralph Johnson, y John Vlissides tomaron esta idea de patrones para poder aplicarla al mundo del desarrollo de software y publicaron uno de los libros más influyentes en la historia de la programación: "Design Patterns: Elements of Reusable Object-Oriented Software". Cariñosamente nos referimos a este grupo de autores con el nombre de “La banda de los 4” (Gang of Four, en inglés) o simplemente GoF.

Este libro presenta un catálogo de 23 problemas que aparecen de forma recurrente cuando construimos aplicaciones usando un lenguaje orientado a objetos; además ofrece una solución general para cada uno de estos problemas. A cada una de estas soluciones, o patrones, les da un nombre y las clasifica dentro de uno de tres tipos. Facilitando con eso la creación de un lenguaje común para todos los programadores.

De acuerdo con los autores, todos los patrones de diseño se basan en los siguientes principios del diseño orientado a objetos:
  • Programar hacia una interface, no a una implementación.
  • Favorecer la composición de objetos frente a la herencia de clases.
  • Determinar qué parte del problema es común y qué parte es variable.
  • Permitir el reemplazo de la parte variable mediante la interfaz común.
Hay que recordar que estos autores no tomaron solo su experiencia para escribir estos patrones. Sino que recopilaron la experiencia de los problemas comunes que observaron en la comunidad y los concentraron en una sola fuente de información.

Los patrones de diseño se clasifican en 3 grupos:
  • Creacionales. Diferentes maneras de crear objetos o grupos de objetos. Sí, todos los objetos en Java se crean usando la palabra reservada new, pero podemos envolver este llamado en otras estructuras que faciliten que otros objetos obtengan una instancia apropiada e inicializada de forma correcta. Esto ayuda a ocultar los detalles de cómo los objetos son creados o inicializados.
  • Estructurales. Diferentes formas de crear la estructura de las clases; por ejemplo, usando herencia y composición para crear objetos grandes y complejos a través de otros más simples.
  • De comportamiento. Formas en las que podemos lograr una mejor interacción entre objetos para lograr un bajo acoplamiento y flexibilidad.
Cado uno de los grupos anteriores se divide en dos diferentes ámbitos: Clases y objetos.

Con esto, logramos tener 6 subclasificaciones:
  • Creacionales
    • Clases
    • Objetos
  • Estructurales
    • Clases
    • Objetos
  • De Comportamiento
    • Clases
    • Objetos

 

 A continuación, te dejo una lista de los patrones contenidos en este libro. A lo largo de esta serie iremos desarrollando la explicación de cada uno de estos patrones.

ClasificaciónClaseObjeto
Creacionales
  • Factory Method
  • Abstract Factory
  • Builder
  • Prototype
  • Singleton
Estructurales
  • Adapter
  • Adapter (sí, otra vez, pero con un ámbito diferente)
  • Bridge
  • Composite
  • Decorator
  • Facade
  • Flyweight
  • Proxy
De comportamiento
  • Interpreter
  • Template Method
  • Chain of Resposibility
  • Commander
  • Iterator
  • Mediator
  • Memento
  • Observer
  • State
  • Strategy
  • Visitor


¿Son estos los únicos patrones que existen? No, cada tecnología, lenguaje de programación, o incluso framework, puede definir sus propios patrones de diseño. En esta serie veremos los patrones más comunes y, dependiendo de la respuesta y necesidades, veré si es necesario que entremos en patrones más específicos. También es importante entender que esos patrones de diseño se usan en aplicaciones que usan el paradigma orientado a objetos. Diferentes paradigmas tienen una serie diferente de patrones.

Si quieres ver una lista más o menos completa de patrones de diseño aplicables a Java, puedes consultarlo en esta liga: https://java-design-patterns.com/patterns/

¿Son estas las únicas formas de clasificar los patrones de diseño? Igual que la respuesta anterior: No. Existen varias formas de clasificarlos; la anterior es la forma más común o popular, pero no es la única. Para da un breve ejemplo, en JavaEE (ahora JakartaEE) los patrones se dividen dependiendo de la capa de la aplicación en donde pueden usarse.

Para dar un ejemplo rápido de lo anterior, en JavaEE las aplicaciones se dividen en 5 capas, y se tiene un catálogo de 21 patrones de diseño que aplican para las tres capas intermedias.

 


 

 ¿Existe una sola forma de implementar un patrón? A esta altura ya sabes la respuesta: No. Existen diversas formas correctas de implementar un patrón de diseño, a cada una de estas formas se les da el nombre de Estrategia.


Definiendo un patrón

Recordemos que el objetivo de los patrones de diseño es recopilar problemas y sus soluciones; pero es importante entender dos cosas:
  1. No todos los problemas se pueden resolver aplicando algún patrón de diseño. Existen problemas para los cuales no existe, aún, algún patrón de diseño. Esto es muy importante ya que una aplicación no puede ser desarrollada usando solo patrones de diseño. Debe ser una combinación entre soluciones generales y soluciones particulares.
  2. Los patrones de diseño tienen un contexto donde se pueden aplicar y una solución. Si tratamos de aplicar esta solución en un contexto diferente para el cual el patrón fue concebido, es posible que terminemos con más problemas de los que teníamos inicialmente. ¿Esto quiere decir que el patrón no sirve? No, quiere decir que estamos aplicando un patrón para un problema diferente al que resuelve; dicho de otra manera, lo estamos sacando de su contexto de aplicación.
De los dos párrafos anteriores podemos concluir que: Un patrón de diseño representa la relación entre tres elementos: un contexto, un problema y una solución.

Cuando se explica un patrón de diseño, esta explicación normalmente incluye:
  • Descripción
  • Escenario de Uso
  • Solución concreta
  • Las consecuencias de utilizar este patrón
  • Ejemplos de implementación
  • Lista de patrones relacionados


Palabras finales de advertencia sobre el uso (y abuso) de los patrones de diseño

Aunque esto pueda sonar un poco contradictorio después de toda la explicación anterior, hay que recordar que, aunque el uso de los patrones de diseño es una buena práctica que ayuda a solucionar problemas, el abusar de ellos y no aplicarlos de forma correcta puede traer muchos problemas en el futuro.

Incluso existe un término para esas personas que intentan aplicar patrones de diseño en todo momento, aún fuera del contexto en el que funcionan, logrando con esto que no se obtenga ningún valor y abusar del uso de patrones de diseño. Este término es: Pattern Happy.

Este término también se aplica a personas que apenas aprender un patrón tratan de aplicarlo a un proyecto sin haber terminado de entender de todo el patrón y en donde no agrega ningún valor.

Muchas veces se trata a los patrones de diseño como verdades universales. Esto es incorrecto.

Martin Fowler nos advierte desde 1997 en su libro "Analysis Patterns: Reusable Object Models" otros dos puntos importantes que debemos tener en mente en todo momento al utilizar patrones de diseño: 

  • Los patrones son un punto de partida, no un destino.
  • Los modelos no están bien o mal, sino que son más útiles o menos útiles.

 Creo que esto es suficiente para una rápida introducción. En el siguiente artículo comenzaremos la aventura de aprender a usar nuestro primer patrón.

No hay comentarios:

Publicar un comentario