Democratizar la Arquitectura: Cómo Abordar Los Patrones de Diseño

 Arantxa,  una vieja amiga mía española, tenía una responsabilidad muy fuerte en el mantenimiento de un core bancario. Entre sus actividades estaba velar por el rendimiento global de este núcleo de ejecución (que estaba desplegado en los principales países de América Latina). Para ello debía construir componentes que sirvieran para tomar evidencias de ese rendimiento (y eventualmente activar alarmas). Arantxa cumplía sobradamente con su compromiso, lo que me daba a pensar que ella tenía sólidos conocimientos de Diseño de Aplicaciones y sus Arquitecturas

Grande fue mi sorpresa en un almuerzo, cuando comentando un problema a resolver le dije algo como

-Nos conviene enmascararlo en un wrapper
-Que conviene enmascararlo en un qué!?- preguntó ella
-En un wrapper, un adaptador- respondí pensando que quizás en España no acostumbrasen usar (y abusar) del inglés como lo hacemos en América Latina
-Jo’err, hombre! Háblame claro. Qué es lo que es eso?
-No sabés lo que es un adaptador? Un patrón de diseño!- le dije pensando que en el fondo Arantxa conocería tanto de la materia que quizás los patrones básicos del GoF ya quedaban fuera de su día a día
-Ah, perdón!- dijo sonriendo vergonzoza- Es que Patrones de Diseño es una vieja deuda que aún debo comenzar a pagar

Esa anécdota me enseñó tres cosas

  • Se puede vivir sin conocer de patrones y aún se puede ser bueno como Ingeniero de Software. Evidentemente el sentido común seguirá dominando cualquier otra variante del racionio
  • Patrones de Diseño es algo que no se necesita aprender porque sí, especialmente -como en el caso de Arantxa- si uno igual es hábil para solucionar problemas
  • Y como consecuencia, si yo necesité estudiar y aprender patrones, es porque yo no podía ser exitoso si no los aprendía, ni era capaz de resolver problemas. Mi querida Arantxa, en ese sentido, los hubiera estudiado como una extravagancia

Ahora, vos sos como yo o como Arantxa? Si sos como ella, no necesitás seguir leyendo. Si sos como yo, dejame que te cuente todo lo que sé de los patrones

Qué es un Patrón de Diseño (o de Arquitectura)
No sé si esta definición la robé o si es mía, pero es la respuesta que daría en un examen.

"Un Patrón de Diseño (eventualmente, de Arquitectura) es una Solución Reusable a un Problema de Diseño (respectivamente, de Arquitectura) de Ocurrencia Frecuente en un Contexto Definido"

Esto es, cada vez que nos encontremos en ese contexto, si el problema aparece, la solución puede aplicarse. El Patrón es todo el conjunto: el Contexto, el Problema y su Solución

Ejemplo: el Wrapper (ostia, Arantxa, que dije el Adaptador!)
Contexto: para comunicarnos con un sistema externo se requiere poder optar de distintos protocolos de transporte (TCP, HTTP, UDP, etc) de modo de poder optar por uno u otro, a la hora del deployment, según las particularidades que cada protocolo aporte según las necesidades del entorno de ejecución
Problema: la lógica gruesa de aplicación no debería verse impactada si se usa uno u otro
Solución: se define una interfaz que contenga los métodos más básicos de comunicación, menos comprometidos con la implementación. La interfaz se implementa cada vez con cada posible tecnología. A la clase que va a necesitar usar el esquema de comunicación debe recibir una referencia a la clase que implemente la interfaz. La comunicación se limitará a los métodos básicos definidos en la interfaz. Los detalles de bajo nivel como conexiones, timeouts, buffering, etc, quedarán encapsulados en cada implementación

A grandes rasgos y sin demasiada rigurosidad, la definición de Patrón es aquella. Como ves, yo no distingo en la definición Diseño de Arquitectura. Si el problema es de Arquitectura uso esa definición para explicar qué es un Patrón de Arquitectura. Si el problema es de Diseño, mi definición cuenta qué es un Patrón de Diseño. Qué fácil la tengo yo, no? Tratemos de aclarar, sí, un poco más

Existen ciertas decisiones que se deben tomar al realizar una aplicación. Algunas decisiones son independientes de la capa de aplicación a la que nos estemos refiriendo. Vale decir, si bien el problema nos surge en una capa específica, ese mismo tipo de problema lo podemos tener en cualquiera de las otras capas. Digamos que en ese caso el problema es más de Diseño

Por caso, el problema con que ejemplifiqué la definición de patrón tenía que ver con desacoplar. Desacoplar una tecnología de transporte del resto de la aplicación. Pero también en la capa de presentación querré desacoplar la lógica de aplicación del canal de entrada. Y en la capa de persistencia probablemente querré desacoplarme de usar una base de datos o archivos XML. Y al iniciar la aplicación, querré desacoplarme de levantar los parámetros de configuración de un archivo separado por comas, de un XML o directamente hardcodeados en una clase construida a partir de un archivo de configuración (pero que al instanciarse ya está configurada y me evita el parsing: el inicio de la aplicación es más rápido, capisce?)

En todos estos casos, el patrón Adaptador (Adapter o Wrapper) sirve para desacoplar la capa que ejecuta una tarea, con la capa que da un apoyo secundario a esa ejecución. Decimos entonces que este tipo de patrones, de aplicación generalizada, son Patrones de Diseño

En cambio, ahora sí, planeando la arquitectura de una aplicación (empresarial o no, pero al menos una aplicación compleja, no trivial, no previsible), se nos pueden presentar problemas que deberemos para concretar el montaje de la misma

Por ejemplo, decidimos separar la captura de los datos en una capa diferente de la capa que va a ejecutar actividades relacionadas con el negocio (eso hoy lo hace cualquiera, incluso un principiante; creéme que aún quedan en producción arquitecturas cliente/servidor de épocas pasadas que no contemplaban esta separación hoy tan en boga). Bien, en este caso, una vez que los datos hayan sido ingresados, un mensaje es armado para enviar a la capa de negocio de la aplicación, a fin de que esta realice la tarea solicitada. Existen diversos patrones que proponen una solución elegante: Controlador Frontal (Front Controller) es uno, Servicio a Trabajador (Service-to-Worker) otro. No los voy a desarrollar acá: por ahora son ejemplos solamente, al final incluyo referencias concretas. El problema planteado, como se puede ver, es bastante más focalizado. Es menos probable -si bien no imposible- que este escenario se nos presente en otra capa

NOTA: es cierto, en el ejemplo, que si queremos integrar nuestra aplicación con una tercera, de modo que aquella sea un back-end detrás de nuestra capa de negocio, esta problemática se le presentará a aquella. Nuestra aplicación pasa a ser un nuevo canal de entrada de la misma. Este ejemplo es típico en aquellas aplicaciones de mainframe que durante años usaron terminales 3270 como interfaz de usuario, y hoy están capturando los datos desde canales Web o Smart Client

Problemas como éste aparecen recurrentemente montando la Arquitectura de la aplicación. La solución reusable que se propone, por ende, es una solución de arquitectura. El contexto es de Arquitectura! (se desea descomponer en capas la arquitectura de una aplicación). Por todo esto digo, pues, el Patrón es de Arquitectura

Los Patrones de Arquitectura, con frecuencia, son versiones más elaboradas de Patrones de Diseño. Por ejemplo, el patrón Front Controller puede verse como una versión más elaborada de un clásico patrón de diseño llamado Fachada (Facade)

Llegados a este punto, quiero hacer la reflexión de cuál es la misión de la Arquitectura de una Sistema. Se trata de administrar la complejidad, de organizarla. De canalizarla en componentes, en capas: de encasillarla. De esconderla del resto. Fuera del compartimento donde una complejidad específica se encapsuló, esa complejidad no existe. Y dentro del compartimento: esa complejidad está resuelta. Por consiguiente, para el resto de la aplicación y de sus desarrolladores, esa complejidad no debe preocupar. Habrá otras preocupaciones, claro. La Arquitectura debe encargarse de encasillar, encapsular, canalizar cada preocupación en componentes distinguibles. El diagrama de Arquitectura de la Aplicación debe reflejar claramente en qué capa o componente cada complejidad está encasillada, y cómo esas capas o componentes se relacionan entre sí (ABC: dirección de cada una -Addressing-, mecanismo de enlace -Binding-, y contrato de comunicación -Contract-)

A modo de conclusión y antes de proseguir, estemos de acuerdo que lo "reusable" de la solución que cada Patrón acerca es una forma de documentar "mejores prácticas" (best practices). Esto en procura de acelerar el dominio del diseño o la arquitectura, acortar los tiempos de decisión y quizás los de desarrollo con ideas más claras de los puntos de llegada

Categorías de Patrones
La distinción entre Patrones de Diseño y Arquitectura ya es historia vieja: hoy el espacio de patrones está mucho más maduro y organizado según contextos. Estamos en un contexto de acceso a datos? Hay patrones que ya documentan problemas típicos y sus soluciones. Tenemos que integrarnos a otras aplicaciones? Existen patrones de integración. Hay que encarar problemáticas de seguridad a nivel de aplicación, más allá de los productos? Para ello están las mejores prácticas que recomiendan los patrones de seguridad. Hay colecciones, series de libros que recopilan patrones según contexto

Por supuesto, si para poder dominar los patrones hay que "comerse" todos esos libros, lo que llegaba como una solución en seguida va a ser un nuevo problema. Yo llamo a esto "Patronitis", una suerte de infección que afecta a ciertos diseñadores o arquitectos, y los hace crear soluciones -en verdad no reusables- para problemas inexistentes en contextos a veces intangibles. Me acuerdo una vuelta que Hans me mostraba un patrón llamado "Stairways to Heaven" (Escaleras al Cielo). El autor del mismo tenía su propio sitio y creaba patrones diariamente. No sabía bien si sorprenderme de su predisposición a aportar tantas soluciones por unidad de tiempo, o si sorprenderme de la cantidad de problemas que se le presentaban por unidad de tiempo

Cómo comenzar a conocer de patrones
Lo que sigue le va a ser útil no sólo a aquel que quiere comenzar a explorar patrones, sino también a aquel que aún habiendo comenzado ya, siente que no encuentra el rumbo correcto, o al menos que no está claro el beneficio de conocerlos

Catálogos o repositorios de patrones, como decía antes, existen por doquier en múltiples formatos: hay muchos sitios web, hay muchos libros, hay webcasts, podcasts, artículos publicados en revistas, etc. Pero cómo dar los primeros pasos?

Para aquellos que dedican la mayor parte del tiempo a codificar, quiero recomendar ante todo el libro inicial de Patrones de Diseño (Dessign Patterns). El autor principal se llama Erich Gamma, aunque participaron tres autores más. El libro es adecuadísimo para quienes quieran iniciarse en esta área. Está organizado en tres grupos: patrones creacionales (creational, para instanciar objetos, dicho a la ligera), patrones estructurales (structural, para relacionar objetos en forma organizada), y patrones de comportamiento (behavioral, para asignar efectivamente las responsabilidades). Es una lectura amena, divertida, uno se llena de ganas de codificar, y dejar atrás todo lo que estuvo haciendo hasta conocer ese libro. Ahora vamos a hablar más sobre ese estado de ánimo post-conocer patrones, y de los riesgos
A cambio, debo decir que es información necesaria pero no suficiente para un arquitecto de software. No obstante, los patrones de este libro han extendido el vocabulario de los desarrolladores con palabras como Singleton, Composite, Visitor o, entre otros, Wrapper, con el que abrí este artículo
Algunas herramientas de modelado incluyen una paleta con estos patrones. De modo de rapidamente generar la estructura de clases y asignar inmediatamente las responsabilidades. También, se han escrito numerosas versiones de este libro pero adaptadas a lenguajes concretos como Java, C#, VB.NET y muchos otros

Para aquellos que dedican su tiempo a planificar arquitecturas, existe algunas biblias aunque ya van quedando algo obsoletas. La primera es para tener en la biblioteca de clásicos: Pattern-Oriented Software Architecture (POSA), de Frank Buschmann. El volumen 1 apareció en 1996. El año 2000 salió el volumen 2 y el 2004 apareció el volumen 3. Todos muy comprometidos con el desarrollo de aplicaciones a escala empresarial
Como contra, puedo decir que poner en práctica las ideas de este libro en una plataforma puede requerir toda una capacitación posterior. En realidad este libro es sólo una buena base, pero hoy existen versiones específicas para las plataformas modernas como J2EE o .NET. Realmente, si tenemos que enfrentar el desarrollo de una aplicación en una plataforma concreta, un libro de Patrones de Arquitectura más enfocado en dicha plataforma sería lo deseable
Los volúmenes del POSA le dan formación teórica a un arquitecto, sin un proyecto en concreto. Los libros de patrones de arquitectura para plataformas específicas, son más adecuados para dar formación práctica al arquitecto que está trabajando en un proyecto definido

Cuando se decide empezar, el secreto para no abandonar la lectura (desanimarse, aburrirse), consiste más que nada en entender el contexto y el problema que los patrones plantean. Conocer, en ese momento de estudio, la solución es lo menos relevante. Alcanza con entender el problema que se puede plantear, y tener la tranquilidad de que ahí se propone una solución. Vale decir, el que quiera leer la solución y aprenderla, eso es fantástico. Para aquel que sólo esté leyendo por leer e informarse, puede resultar abrumador. Arriesgo a creer que se va a abandonar el libro antes de llegar al quinto patrón. Conocer de antemano los contextos y problemas sí es, a mi juicio, importante. Estar preparado y conciente de los peligros que acechan es una cosa. Estar listo para responder es algo diferente. Yo personalmente suelo posponerlo hasta el momento verdadero. Además, permiso: los contextos y sus problemas son siempre los mismos. Las respuestas suelen cambiar con el tiempo, en la medida en que las plataformas evolucionan

Errores de principiantes
Lo que voy a contar es la forma que yo tengo de darme cuenta que alguien está comenzando a estudiar patrones

  • El martillo: enseñale a alguien a usar un martillo y le va a encontrar forma de clavo a todo. Es muy típico que el que conoce el contexto y el problema que motiva a solucionarlo limitando instancias con el Singleton, a partir de allí va a querer "singletonizar" todo. Va a sentir que controlar instancias es siempre lo adecuado, fundamentado en el problema que se describe en el libro de Erich Gamma. Esto va a decantar en un código desconcertante, difícil de entender y posteriormente de mantener (si es que se logra terminar). Este error lo suelen cometer aquellos que alcanzaron a leer unos pocos, pero no todos los patrones
  • Empatronizacionamiento exagerado: este error lo cometen más aquellos que han estado leyendo uno o varios libros (u otros compendios) completos de patrones. Algo los lleva a creer que el sólo hecho de aplicar patrones, hace a una aplicación correcta en sí misma. Algo así como que es políticamente correcta
    Anecdóticamente, alguien se ufanó cierta vez de que tenía una aplicación que usaba veinte de los veintitantos patrones de Gamma. Y que ya se proyectaba una versión posterior que los iba a aplicar a todos
    Hablemos claro: la calificación de correcta a una aplicación o sistema es subjetiva. Para el usuario va a ser más o menos correcta en la medida en que cumpla con la funcionalidad para la cual se la creó. Para la gente de TI, será correcta en la medida en que sea fácil de entender, mantener y evolucionar. En ningún caso, el hecho de que aplique patrones, por sí solo, otorga correctitud a una aplicación sino que en el mejor de los casos ayuda a que sea fácil de entender, mantener y evolucionar. Y esto último hace correcta a la aplicación del punto de vista de TI

Todo esto me motiva a extraer una cuarta enseñanza (para agregar a las tres enseñanzas que me dejó la ignorancia de Arantxa)

  • Conocer patrones concientiza, y eso ayuda a crear buenos diseños, buenas arquitecturas, buenas aplicaciones. Pero la ayuda no garantiza que eso vaya a ocurrir. El éxito siempre va a depender de cada uno. Conocer de memoria la Constitución le va a dejar claro a un funcionario la calidad de sus actos. Pero no lo va a hacer menos corrupto

Antipatrones (Antipatterns)
El éxito y difusión que tuvieron los patrones evidenciaron que aplicaciones ya construídas, en producción, y con problemas para mantenerlas, difíciles de entender y de evolucionar, no sólo no aplicaban patrones sino que era muy difícil saber por dónde empezar para encarrilarlas. Era difícil conocer cuáles habían sido las malas decisiones de diseño y los efectos que las mismas habían provocado

De este debate surgió un nuevo concepto, antítesis del concepto de Patrón. Un Antipatrón es una mala práctica, en la misma medida que un Patrón es una buena práctica. Los libros de Antipatrones están pensados para corregir deficiencias en aplicaciones ya creadas. Los libros de antipatrones son en realidad libros de patrones. Lo que pasa es que en lugar de promover el estudio de los patrones en forma aislada, parten por plantear un escenario concreto de implementación (de mala implementación), y allí explican como refactorizar esa parte de la aplicación para, mediante la aplicación de un patrón, corregir la pieza mal implementada

Muy útiles para rescatar aplicaciones, extender su vida útil, recuperar la confianza en la misma y en el equipo que la mantiene

Conclusión
Los patrones son soluciones listas para usar, aplicables a problemas que se repiten con frecuencia en contextos acotados. Hoy los catálogos de patrones están lo suficientemente maduros y categorizados. El estudio de los patrones se debe hacer convenientemente bajo demanda, ya que cada día surgen nuevos. Espero aquí haber aportado varios por qués de los patrones. Cierro con una lista de libros y catálogos de patrones, invito a quien quiera a que aporte su cosecha (las referencias que valgan la pena van a quedar plasmadas en futuras actualizaciones de este artículo)

Referencias

About these ads
Esta entrada fue publicada en Software Architecture. Guarda el enlace permanente.

2 respuestas a Democratizar la Arquitectura: Cómo Abordar Los Patrones de Diseño

  1. fabian dijo:

    Diego,
     
    Soy un profesional de la informática que además de trabajar en empresas de telecomunicaciones me gasto el tiempo haciendo catedras en algunas universidades, bueno el motivo de mi post es felicitarte por el grado de conocimiento que despliegas en el área de la ingeniería de software y fue realmente un agrado leer tu blog. En este momento estoy impartiendo un ramo llamado "Integración de sistemas" en donde debo hablar de algunos temas que aquí presentas, por lo cual además de ser interesante como cultura general, tus paper serán de gran ayuda en la catedra, se agradecen y ojala puedas postear más material de integración ya que este humilde docente y sus alumnos te lo agradeceran.
     
    Saludos
    Fabián Rodríguez
    fabian@caos.cl

  2. Diego dijo:

    Muchas gracias, Fabián!! Esos comentarios estimulan!
     
    Aún tengo pendiente terminar una serie llamada "Integración a la carte" en la cual describo los diferentes niveles de integración de aplicaciones pero al momento sólo llegué a cubrir en profundidad el nivel de capa de presentación
     
    No obstante, me estoy basando en el libro "Guías de Integración de Aplicaciones" del comité de Patterns & Practices
     
    Muchas gracias nuevamente!

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s