Patrones de diseño

Luego de un tiempo de no haber posteado, porque no había encontrado el momento ni el tema, he decidido volver a hacerlo, motivado por el post llamado A post a day keeps the doctor away de mi estimado compañero de trabajo Angel “Java” Lopez.

Me faltaba ver el tema en particular, ya que estaba decidido en emprender una vuelta fuerte, con algo en particular, un aporte para todos. Dicho tema lo encontré en mi estudio de patrones de diseño. Busqué… busqué… y busqué, pero la falta de contenido en la red era sorprendente (en particular en ciertos lugares donde reinaban las inconsistencias).

Luego de la lectura de algunos libros, webs y blogs, me di cuenta que lo que tenía uno, le faltaba al otro, por lo que me he decidido emprender una descripción concisa de algunos.

Aún así, quiero aclarar que trataré de lo que es un patrón en sí. Cuándo y cómo seleccionar uno en particular, cómo resuelven los patrones los problemas de diseño y cómo se utiliza un patrón (es decir, los pasos que debe seguir el lector para ponerlo en práctica, y no su implementación) están fuera del alcance de este post.

Dicho ésto, a su vez, quiero aclarar que todo tipo de comentario o feedback será bienvenido. Así se podrá corregir y actualizar para proveer una fuente base para todo lector interesado en el tema.

¿Qué es un patrón de diseño?

Ahora, bien, concentrémonos en el tema: patrones de diseño. Primero, quiero hacer una especie de “herencia” de definiciones, comenzando por lo genérico hasta llegar a lo específico.

Comencemos por la definición más abstracta:

  • Dechado (modelo o muestra que se copia para aprender a hacer lo que hay en ella) que sirve de muestra para sacar otra cosa igual.
  • Referencia aceptada usada para definir una unidad de medida.
  • Modelo que se toma como eje para medir o valorar otros de la misma especie.

Curiosamente, estas tres definiciones presentan un patrón, un modelo común; apuntan a lo mismo. Indican que un patrón es una referencia que sirve como modelo para medir, valorar y hacer otro del mismo tipo. Esa es mi interpretación. Simple y concreta, ¿no? Me parece correcta para asentar una base del concepto de la cual comenzaremos a “heredar”.

Continuemos con el concepto de patrón. En su libro A Timeless Way Of Building, Christopher Alexander indica que “cada patrón es una regla de tres partes que expresa una relación entre un cierto contexto, un problema y una solución.

Como un elemento en el mundo, cada patrón es una relación entre un cierto contexto, un cierto sistema de fuerzas que ocurre repetidamente en ese contexto, y una cierta configuración espacial que permite que esas fuerzas se resuelvan.

Como un elemento de lenguaje, un patrón es una instrucción que muestra cómo esa configuración espacial puede ser usada, una y otra vez, para resolver el sistema de fuerzas dado, en cualquier contexto que lo haga relevante.

Un patrón es, brevemente, al mismo tiempo una cosa que sucede en el mundo y la regla que nos dice cómo crear esa cosa, y cuándo tenemos que crearla. Es ambas, un proceso y una cosa; una descripción de una cosa que vive y una descrición de un proceso que generará esa cosa.”

Aquí me detendré para denotar lo interesante de estos párrafos que me llevó a citarlos. Alexander indica que un patrón es una regla de tres partes (contexto-problema-solución), una cosa que nos indica cómo y cuándo crearla para resolver un sistema dado en un contexto relevante. Ésto muestra que un patrón puede describir un problema determinado, una situación particular para dicho problema y una solución en el mismo contexto dado.

Ahora, pasemos a algo más específico, quizás, a nuestro tema. Alexander nos dice (en su libro A Pattern Language) que “cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, así como la solución a ese problema, de tal modo que se pueda aplicar esta solución un millón de veces, sin hacer lo mismo dos veces”. Es muy interesante esta definición. La primera vez que la vi fue en un post del blog de Mathew Nolton llamado The Bridge Pattern, en el cual Nolton rescata la parte que indica que un patrón describe “[…] la solución a ese problema […]”, para hacer hincapié en que entendiendo ese problema se puede llegar a comprender el por qué de cúando aplicar qué patrón. Es decir, entendiendo nuestro problema utilizaremos un patrón determinado y lo adaptaremos a dicho contexto.

Vayamos entrando en lo que es un patrón de diseño. Veamos la definición que nos provee Erich Gamma (en su libro Patrones de diseño):

“Un patrón de diseño nomina, abstrae e identifica los aspectos clave de una estructura de diseño común, lo que los hace útiles para crear un diseño orientado a objetos reutilizable. El patrón de diseño identifica las clases e instancias participantes, sus roles y sus colaboraciones, y la distribución de responsabilidades. Cada patrón de diseño se centra en un problema concreto, describiendo cuándo aplicarlo y si tiene sentido hacerlo teniendo en cuenta otras restricciones de diseño, así como las consecuencias y las ventajas e inconvenientes de su uso.”

Esta definición ya no da lugar a dudas. Explica concretamente lo que es un patrón de diseño y todo lo que conlleva, pero Gamma no se queda allí y explica que “un patrón es como una plantilla que puede aplicarse en muchas situaciones diferentes. […] una descripción abstracta de un problema de diseño y cómo lo resuelve una disposición general de elementos”. Creo que con ésto ya se cerraría el concepto. Estas frases agregan valor a la definición ya que indica que un patrón de diseño nos provee una plantilla, un formato predeterminado de solución, un set de herramientas que podemos utilizar de forma personalizada para adaptarlo a nuestra situación particular. Es decir, un patrón ataca un problema en particular, si, pero somos nosotros quienes debemos adaptarlo a nuestro caso personal, nuestro contexto concreto. Para darse cuenta de ésto, simplemente basta con recordar la definición de C. Alexander.

Teniendo ya el concepto en claro, ¿qué más debemos saber de un patrón de diseño? Gamma nos indica que un patrón generalmente cuenta con cuatro elementos esenciales:

  • Nombre del patrón: describe, en una o dos palabras, un problema de diseño junto con sus soluciones y consecuencias.
  • Problema: describe cuándo aplicar el patrón (explica el problema y su contexto).
  • Solución: describe los elementos que constituyen el diseño, sus relaciones, responsabilidades y colaboraciones.
  • Consecuencias: son los resultados (ventajas e inconvenientes) de aplicar el patrón. Dichos pueden referirse al equilibrio entre espacio y tiempo, junto con su impacto sobre la flexibilidad, extensibilidad y portabilidad de un sistema.

Y los clasifica según su propósito (refleja que hace el patrón) y su ámbito (si se aplican a clases u objetos).

patterns

Ámbito

Los patrones de clases se ocupan de las relaciones entre las clases y sus subclases establecidas a través de la herencia (relaciones estáticas, fijadas en tiempo de compilación). En cambio, los patrones de objetos tratan con las relaciones entre objetos (relaciones dinámicas que cambian en tiempo de ejecución).

Propósito

Los patrones de creación tienen que ver con el proceso de creación de objetos. Los de clases delegan alguna parte del proceso de creación de objetos en las subclases, mientras que los de objetos lo hacen en otro objeto.

Los patrones estructurales tratan con la composición de clases u objetos. En el primer caso, se usa la herencia, mientras que en el segundo, se describen formas de ensamblar objetos.

Los patrones comportamiento caracterizan el modo en que las clases y objetos interactúan y se reparten la responsabilidad. Los de clases usan la herencia para describir algoritmos y flujos de control, mientras que los de objetos describen cómo cooperan un grupo de objetos para realizar una tarea que ninguno podría llevar a cabo por sí solo.

Con esto último ya cerraría el tema. Dejo aquí el listado de patrones que, a medida que vaya tratando cada uno, contendrán los links a sus respectivos posts.

Patrones de creación:

  • Abstract Factory
  • Builder
  • Factory Method
  • Prototype
  • Singleton

Patrones estructurales:

  • Adapter
  • Bridge
  • Composite
  • Decorator
  • Façade
  • Flyweight
  • Proxy

Patrones de comportamiento:

  • Chain of Responsibility
  • Command
  • Interpreter
  • Iterator
  • Mediator
  • Memento
  • Observer

– Salu2, Nacho

PD: Les dejo unos links que contienen referencias interesantes:

See this topic in English.