Arquitectura evolutiva y diseño emergente: Arquitectura evolutiva

Consideraciones y técnicas para una arquitectura ágil

La entrega sobre Arquitectura Evolutiva y el diseño emergente se ocupa de una variedad de temas relacionados con la arquitectura evolutiva, incluyendo la importante distinción entre diseño y arquitectura (y cómo diferenciarlos), algunos problemas que surgen cuando se crean arquitecturas a nivel empresarial, y la diferencia entre la escritura estática y dinámica en las arquitecturas orientadas a servicios.

Neal Ford, Application Architect, ThoughtWorks Inc.

Photo of Neal FordNeal Ford es software architect y Meme Wrangler en Thought Works, consultora de TI global. También diseña y desarrolla aplicaciones, materiales instructivos, artículos para revistas, material de aprendizaje y presentaciones en video/DVD, y es autor o editor de libros que abarcan una variedad de tecnologías, incluyendo el más reciente The Productive Programmer [El programador productivo]. Neal se concentra en diseñar y construir aplicaciones de negocios de gran escala, y es un orador internacionalmente aclamado en las conferencias para desarrolladores de todo el mundo. Consulte su Sitio Web.



05-08-2011

Ya hace mucho, en la primera entrega de esta serie, sugerí algunas definiciones para el término arquitectura en el mundo del software. Sin embargo, si usted ha leído la serie completa (y si no es mi madre, ¡se lo agradezco!), se habrá dado cuenta de que dediqué casi todo el tiempo al diseño. Lo hice por un par de motivos. En primer lugar, existen muchas definiciones de arquitectura en el mundo del software (para bien o para mal), mientras que el diseño emergente goza de menor fama. En segundo lugar, muchas de las preocupaciones que existen en torno al diseño poseen soluciones concretas y menos contextualizadas. La arquitectura siempre involucra mucho acoplamiento con infraestructura física y lógica dentro de las organizaciones, lo cual hace que sea más difícil hablar de ella de manera aislada.

Acerca de esta serie

Esta serie apunta a brindar una perspectiva nueva sobre los muy discutidos pero esquivos conceptos de arquitectura y diseño de software. A través de ejemplos concretos, Neal Ford le brinda sólidos fundamentos para las prácticas ágiles de arquitectura evolutiva y diseño emergente. Al diferir las decisiones importantes de arquitectura y diseño hasta el último momento en que resulte responsable hacerlo, usted puede evitar que una complejidad innecesaria obstaculice sus proyectos de software.

Esta entrega rectifica la falta de material sobre arquitectura ágil. En ella, hablo sobre cómo distinguir entre arquitectura y diseño, me ocupo de algunas consideraciones generales de la arquitectura, y más tarde toco el tema de la arquitectura orientada a servicios (SOA) ágil con una discusión sobre los puntos finales del control de versiones.

Cómo distinguir la arquitectura del diseño

La definición de arquitectura de Martin Fowler (extraída de conversaciones que he mantenido con él) es mi preferida:

Arquitectura es todo aquello que es difícil de cambiar más adelante. Y debe haber lo menos posible.

Usted puede considerar la interacción entre arquitectura y diseño como la relación que se muestra en la Figura 1:

Figura 1. Relación entre arquitectura y diseño
Relación entre arquitectura y diseño

La arquitectura de un sistema de software forma la base sobre la cual se apoya todo lo demás, lo cual está representado en la Figura 1 como cajas grises. Los elementos de diseño se apoyan sobre la arquitectura, como se muestra en las cajas rojas. Al ser más fundacionales, los elementos de la arquitectura son más difíciles de mover y reemplazar debido a que se tendrían que mover todos los elementos sobre ellos para adaptarse a los cambios. Esta distinción hace más sencilla la identificación de diseño versus arquitectura. Por ejemplo, el marco Web que usted usa es un elemento arquitectónico porque es difícil de reemplazar. Dentro de ese marco Web, sin embargo, usted puede usar diferentes patrones de diseño para expresar metas específicas, lo cual sugiere que la mayoría de los patrones de diseño formales son, de hecho, parte del diseño y no de la arquitectura.

El corolario para la definición de arquitectura de Fowler es que usted deberá construir los elementos arquitectónicos de manera que sean más sencillos de reemplazar en caso de ser necesario. Pero, ¿cómo asegurarnos de eso? A continuación veremos un ejemplo.

Existen muchísimos marcos que intentan seducirlo para que usted use algunas de sus clases en lugar de las más generales que ya sea con el JDK o de un contenido de estándar abierto (como por ejemplo OASIS). Este es el modelo de acoplamiento más adictivo: si usted se rinde a la tentación, quedará conectado al marco para siempre. El enfoque general que toman estos marcos es hacer que ciertas tareas sean muchísimo más sencillas si usted usa sus clases. Un ejemplo perfecto de lo dicho es el marco Web Apache Struts (ver Recursos).

Las clases dentro de su aplicación que incluyen reglas de negocios y otros códigos no pertenecientes a la infraestructura son clases de dominio: contienen información de interés sobre el dominio del problema. Una de las buenas clases auxiliares que incluye Struts es la clase ActionForm. Si usted hereda sus objetos de dominio de ActionForm, toda clase de magia sucederá en su aplicación. Los campos se poblarán automáticamente a partir de los parámetros, se validarán también automáticamente (tanto en el nivel de la Web como del servidor), y se producirán otras cosas útiles. Todo lo que usted deber hacer es subclasificar la clase ActionForm de Struts, como se muestra en la Figura 2:

Figura 2. Cómo usar la clase ActionForm de Struts
Cómo usar la clase ActionForm de Struts

En la Figura 2, el casillero etiquetado Model (Modelo) incluye el objeto de su dominio. Extiende el ActionForm de Struts, haciendo que esta estructura sea difícil de modificar con posterioridad. Si, en algún otro momento, usted decide que el ScheduleItem también debe funcionar dentro de una aplicación de Swing, estará en problemas. Quedará con dos soluciones igualmente desagradables: arrastrar todo lo de Struts a la aplicación de Swing (para no usarlo) o deshacer la dependencia de Struts.

La mejor alternativa usa la composición más que la herencia, como se muestra en la Figura 3:

Figura 3. Cómo desacoplar su clase de dominio a través de la composición
Cómo desacoplar su clase de dominio a través de la composición

En esta versión, la clase de dominio (en amarillo) incluye una interfaz que define la semántica de un artículo de cronograma. El ScheduleItem original implementa esta interfaz, que también es implementada por ScheduleItemForm, lo cual obliga a las semánticas de ambas clases a estar siempre de acuerdo. ScheduleItemForm a su vez, posee una instancia del objeto de dominio ScheduleItem, y todos los elementos de acceso y de mutación deScheduleItemForm pasan a través de los elementos de acceso y mutación subyacentes del ScheduleItem encapsulado. Esto le permite aprovechar las características de Struts mientras se mantiene desconectado del marco.

La regla general es la siguiente: está bien que el marco sepa sobre usted, pero no está bien que usted sepa sobre el marco. Mientras usted pueda mantener esta relación, evitará el acoplamiento de su código a la infraestructura, permitiéndole realizar cambios de arquitectura y diseño de manera más sencilla. En ocasiones exigirá un poco más de trabajo, pero usted tundra finalmente mayor flexibilidad. Struts no es el único marco en ofrecer estas ventajas. Prácticamente todos los marcos incluyen algunos elementos de ayuda que lo acoplarán al marco. Si alguna vez se descubre importando paquetes de un marco o proveedor a sus clases de dominio, significa que se estará generando n futuro dolor de cabeza.


Algunas consideraciones sobre la arquitectura

Más allá de la definición de arquitectura, surge una amplia variedad de cuestiones en las típicas configuraciones empresariales. En este artículo me ocuparé de los enfoques de la arquitectura ágil para algunos de ellos.

Política de arquitectura

La política empresarial es una de las primeras sorpresas desagradables que usted se encontrará cuando asuma un puesto relacionado con la arquitectura. Debido a que el puesto de arquitecto es por lo general el puesto técnico más alto en las empresas, usted se convertirá en el vocero (y defensor) de todas las decisiones que se toman en el departamento de TI, para bien o para mal. De hecho, por lo general lo culparán por lo malo y no tendrá reconocimiento alguno por lo bueno. Algunos nuevos arquitectos intentan ignorar este hecho (que solía funcionar bastante bien cuando usted se encontraba en las trincheras del área técnica), pero es un hecho inevitable en su nuevo puesto.

Recuerde que la comunicación es más importante que la tecnología en la mayoría de los proyectos de software. Si alguna vez ha participado de un proyecto de software que fracasó, considere los motives del fracaso. ¿Se debió a un motivo de tecnología o a un problema de comunicación? En la mayoría de los casos, el problema es comunicacional más que tecnológico. Los problemas tecnológicos tienen solución. (A veces se trata de soluciones complejas, pero siempre existe alguna.) Los problemas sociales son mucho más desagradables y difíciles de solucionar. Una de las citas famosas del libro Peopleware (ver Recursos) es:

Siempre es un problema de personas.

Incluso en las decisiones sobre tecnología que usted cree que son claras, la política tundra injerencia, en especial si usted se encuentra en una posición en la que debe aprobar las compras de herramientas empresariales. (La ventaja es que probablemente lo inviten a una exótica salida para jugar al golf, cortesía de los proveedores de las herramientas). Recuerde que, como arquitecto, no sólo debe tomar decisiones importantes; también debe defenderlas. En ocasiones, las personas con las que habla tienen sus propias agendas, que si bien no tienen sentido lógico, tienen sentido desde el punto de vista de la política empresarial. No se sienta frustrado, y recuerde por qué tomo la decisión en primer lugar.

Construir vs. comprar

Una de las preguntas comunes que surgen en las grandes empresas es si se debe construir o comprar: para los requerimientos actuales, ¿debemos comprar COTS (Commercial Off-the-Shelf Software o software comercialmente disponible) o debemos construirlo nosotros mismos? La motivación para esta decisión es comprensible — si la empresa encuentra software ya programado que hace exactamente lo que se necesita, se ahorrará tiempo y dinero. Desafortunadamente, muchos proveedores de software comprenden este deseo y elaboran paquetes de software que se pueden adaptar a la medida de las necesidades del cliente. Están motivados para construir el software más genérico posible debido a que potencialmente este software se adaptará a más ecosistemas. Pero cuanto más general es, más adaptaciones necesitará. Entonces surge un ejército de consultores, que a veces demoran años en realizar toda la adaptación del código.

La pregunta sobre si se debe o no comprar COTS en realidad se reduce a otra pregunta: el proceso que soporta este software, ¿es estratégico o de gastos generales? La compra de COTS tiene sentido si el proceso de negocios en cuestión es meramente de gastos generales. Entre los ejemplos de este tipo de software se incluyen s recursos humanos, finanzas, y otros procesos de negocios comunes. El software estratégico representa una ventaja competitiva en su campo de negocios, y esta ventaja competitiva no debe ser cedida fácilmente.

Evite la trampa

Recuerde: No todos los procesos de negocios se pueden transformar en commodities, y algunos varían de un negocio a otro. No caiga en la trampa de creerles a los proveedores que dicen que ya han programado su proceso de negocios. Si así fuera, puede estar seguro de que también se lo están vendiendo a la competencia.

El diagrama de flujo de la Figura 4 está diseñado para ayudarlo a decidir entre construir y comprar:

Figura 4. Diagrama de flujo de decisiones para construir vs. comprar
Diagrama de flujo de decisiones para construir vs. comprar

En este diagrama de flujo, la primera decisión que usted debe tomar gira en torno a la importante distinción entre estratégico y de gastos generales. Si la necesidad es estratégica, siempre deberá construir la solución usted mismo. De lo contrario, se estará colocando en un campo de juego igual al de su competencia, en lugar de construir algo que se adapte exactamente a sus necesidades presentes y futuras. Los paquetes de software pregonan su capacidad de adaptación, pero siempre existen límites a cuánto se puede personalizar. Si usted programa su propio software, llevará más tiempo pero usted contará con una plataforma sobre la cual podrá construir elementos que lo distingan de la competencia.

La segunda decisión del diagrama de flujo le pregunta si el paquete de software tiene una utilidad inmediata. Una de las trampas comunes que aparecen al comprar paquetes de software es no comprender exactamente cuánto tiempo llevará la adaptación de los mismos a sus procesos de negocios; la mayoría de las empresas juzgan esto mal debido a la magnitud del asunto. Cuanto más se deba adaptar, más tiempo llevará el proceso. Peor aún, algunas empresas permiten que sus procesos de negocios cambien para adaptarse al software. Esto es un error porque, para bien o mal, sus procesos de negocios deben distinguirse de los de la competencia.

El tercer paso en el árbol de toma de decisiones pregunta si el paquete es extensible versus adaptable. Los sistemas extensibles tienen modos bien definidos de ampliar la funcionalidad sin necesidad de sacar nada de lugar. Estos puntos de extensión incluyen APIs, llamadas SOAP, etc., bien definidas. La adaptación a medida implica que usted deberá “hacer trampa” para que el paquete haga algo que usted desea. Por ejemplo, si usted se encuentra abriendo un archive WAR para poder reemplazar el archivo denominado index.gif por una imagen diferente (que deberá ser denominada index.gif), usted está adaptando, no ampliando. La prueba determinante es si usted tiene posibilidades o no de sobrevivir a una actualización. Si es así, usted ha extendido su paquete; de lo contrario, lo ha adaptado a medida. La adaptación a medida lo disuade de mantener el paquete actualizado porque usted se da cuenta de todo el esfuerzo que implicará realizar los mismos cambios en la nueva versión. Por lo tanto, la tendencia es no actualizar, dejándolo eventualmente en una versión cinco veces más Antigua que la última, lo cual genera el riesgo de que pierda el soporte de la versión antigua que utiliza.

Lo que para algunos es de gastos generales, para otros es estratégico. Por ejemplo, he realizado ciertos trabajos de consultoría para una compañía de servicios financieros cuyo proceso de contratación es considerado como una de sus ventajas estratégicas. Contratan a los mejores y a los más brillantes, y dedican mucho tiempo y esfuerzo a encontrar a las personas correctas. Una vez me pidieron asesoramiento sobre la compra de un sistema de recursos humanos COTS, y les recomendé que no lo compraran: ¿por qué colocarse en un campo de juego igual al de la competencia? En cambio, siguieron mi consejo y programaron su propio sistema de RR HH. Llevó más tiempo, pero una vez que el sistema estuvo listo, la empresa contó con una plataforma que facilitó las tareas que demandaban más trabajo a la competencia. La contratación es simplemente un costo general para muchas organizaciones, pero para esta compañía era un tema estratégico.


Cómo programar una arquitectura

Un tema más técnico (menos orientado a los procesos) que surge a menudo en las iniciativas de SOA tiene relación con la programación y el control de versiones de los sistemas distribuidos. Esto constituye uno de los escollos más comunes de este tipo de proyectos. Resulta común tanto porque es fácil seguir el camino marcado por los proveedores de herramientas como porque transcurre algún tiempo antes de que el problema se manifieste — y los problemas más difíciles surgen de no saber lo que se desconoce en las etapas iniciales de un proyecto.

El debate sobre si es posible construir sistemas “empresariales” con lenguajes escritos de manera dinámica ha sido tomado una y otra vez, y los argumentos son ahora muy exaltados y ofrecen poca claridad. Sin embargo, este debate brinda una importante consideración para los sistemas distribuidos con respecto a la escritura de los puntos finales. Por puntos finales, me refiero al portal de comunicaciones entre dos sistemas dispares. Los dos estilos de escritura que compiten son SOAP, que normalmente incluye una escritura fuerte que usa estándares como por ejemplo Web Services Description Language (WSDL), y Representational State Transfer (REST), que favorece un enfoque centrado en los documentos de escritura más holgada (ver Rcursos). El detalle de las ventajas y desventajas de SOAP vs. REST se encuentran fuera del alcance del presente artículo; aquí solamente deseo hablar sobre los beneficios de la escritura holgada en el nivel del punto final, que se puede lograr con cualquiera de estos estilos.

La escritura más dinámica es importante en los puntos finales debido a que estos puntos finales forman una API de integración publicada entre sistemas que usualmente evolucionan a distintos ritmos. Es preferible evitar el acoplamiento estrecho de firmas específicas (nombres de parámetros y escrituras) entre dichos sistemas, lo cual haría que cualquiera de los extremos de la conversación se volviera frágil y fácil de romperse, poniendo en riesgo su capacidad de controlar las versiones de ambas aplicaciones de manera independiente.

A continuación puede verse un ejemplo. En la integración tradicional de estilo SOAP, usted usa un protocolo del tipo Remote Procedure Call (RPC), que usa WSDL para definir los detalles de la conversación entre ambas aplicaciones. Esto se ilustra en la Figura 5:

Figura 5. Cómo usar llamadas de estilo RPC entre aplicaciones
Cómo usar llamadas de estilo RPC entre aplicaciones

La integración estilo RPC usa WSDL para tomar una llamada del método "regular" y abstraerla en SOAP. De este modo, cada clase se mapea a una escritura en WSDL, que incluye los tipos de todos sus parámetros. Este enfoque acopla estrechamente ambos lados de la conversación, porque ambos se basan en WSDL para definir qué se envía y qué se espera. El problema está en la definición estricta. ¿Qué pasaría si usted desea modificar una de las aplicaciones para que tome distintos parámetros o modifique la escritura de uno existente, y no puede modificar ambas aplicaciones al mismo tiempo? ¿Cómo controla la versión del punto final? Hay varias maneras posibles, pero todas ellas tienen serias complicaciones. Por ejemplo, usted puede crear otro punto final con la nueva definición de WSDL. Si el punto final original se denominaba addOrder, usted puede crear otro punto final denominado addOrder2. Con seguridad verá el inconveniente que esto ocasiona. En poco tiempo, tundra docenas de puntos finales levemente diferentes, con códigos duplicados por todas partes, manejando situaciones extraordinarias porque resulta difícil anticipar de qué manera las personas usarán el punto de integración una vez que éste haya sido publicado. También puede hacer trucos con la resolución de puntos finales usando herramientas como Universal Description, Discovery e Integration (UDDI) (o simplemente una tabla hash), pero esto tampoco tiene buena escalabilidad. El problema fundamental es el acoplamiento estrecho entre los puntos finales, que evita que los mismos evolucionen a un ritmo natural e independiente.

Un enfoque alternativa es tratar a los puntos finales de la integración como si estuvieran escritos de manera holgada, como se muestra en la Figura 6:

Figura 6. Cómo usar la escritura holgada en los puntos finales de integración
Cómo usar la escritura holgada en los puntos finales de integración

Al pasar la información interesante al punto final dentro de un documento, es posible dejar sin cambios la definición del punto final en todas las actualizaciones importantes o no de cada lado de la conversación. En lugar de depender de WSDL para definir estrictamente qué es lo que se espera, usted cuenta con la opción de la flexibilidad. Ahora, el punto final siempre incluye un documento que encapsula los tipos de cosas que el punto final necesita.

Para manejar el control de versiones del punto final, el primer paso en la resolución del punto final es quitar el documento del paquete, determinar qué es lo que ha pasado y conciliarlo con lo que se espera. Por lo general uso una combinación de los patrones de diseño de Factory y Strategy (ver Recursos) para establecer si estoy obteniendo lo que espero, como se muestra en la Figura 7:

Figura 7. Cómo sacar los contenidos de dentro de punto final para determinar los tipos
Cómo sacar los contenidos de dentro de punto final para determinar los tipos

El primer trabajo del punto final es mirar el manifiesto del documento y determinar qué es lo que contiene. Luego, usa una fábrica para ejemplificar la estrategia adecuada para extraer la información del documento. Una vez verificadas todas las partes (de ser necesario, usando WSDL), los objetos deserializados pasan para el procesamiento de negocios.

Este enfoque presenta un par de beneficios. En primer lugar, no es buena idea contar con un mecanismo con dos trabajos ortogonales, si bien esto es lo que supone el RCP tradicional: el punto final es responsable de brindar la API publicada para la integración y de verificar la escritura. Debido a que tiene dos comportamientos, se tiende a entremezclar los códigos, lo cual los vuelve más difíciles de comprender y actualizar. En segundo lugar, usted cuenta ahora con cualquier cantidad de usuarios de este punto final, todos los cuales usan versiones levemente diferentes del mismo. Mientras usted tenga una estrategia, podrá brindar soporte a cualquier versión (incluyendo las versiones antiguas de aplicaciones cuya actualización es lenta) con el mismo punto final. Esto le permite realizar cambios a medida que lo necesite y despreocuparse de forzar el resto de las aplicaciones de la empresa para seguirle el ritmo a los cambios. Pueden cambiar y usar nuevas versiones de los documentos en sus propias escalas temporales.

Todavía no se dispone de ninguna herramienta que le permita implementar este enfoque de manera sencilla, pero se pueden lograr los beneficios antes mencionados con un poco de esfuerzo extra. Usted podrá implementar este estilo con SOAP o REST (si bien es más sencillo en REST porque REST está en sí mismo orientado a los documentos). Al crear un ecosistema con escritura holgada, usted puede permitir que diferentes grupos de desarrollos se muevan a su propio ritmo, lo cual permite el avance en el uso de aplicaciones en toda la empresa con la menor fricción posible. Esta es la esencia de la arquitectura evolutiva: colocar una base que permita cambios sin fricciones al ritmo más rápido posible sin comprometer las capacidades.


Conclusión

La arquitectura constituye un tema amplio y complejo dentro del software; en esta entrega he tratado de mencionar muchas facetas diferentes, que van desde la política hasta los detalles de implementación para los puntos finales de control de versiones en SOA. En futuras entregas, desarrollaré más en detalle estas ideas sobre la arquitectura en general y algunos nuevos enfoques arquitectónicos para la construcción de una SOA evolutiva sin necesidad de pagar millones a los proveedores.

Recursos

Aprender

Comentar

Comentarios

developerWorks: Ingrese

Los campos obligatorios están marcados con un asterisco (*).


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. La información en su propio perfil (nombre, país/región y nombre de la empresa) se muestra al público y acompañará a cualquier contenido que publique, a menos que opte por la opción de ocultar el nombre de su empresa. Puede actualizar su cuenta de IBM en cualquier momento.

Toda la información enviada es segura.

Elija su nombre para mostrar



La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Los campos obligatorios están marcados con un asterisco (*).

(Por favor elija un nombre de 3 - 31 caracteres.)

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Toda la información enviada es segura.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=tecnologia Java, SOA y servicios web
ArticleID=480670
ArticleTitle=Arquitectura evolutiva y diseño emergente: Arquitectura evolutiva
publish-date=08052011