Actualmente gran parte de mi tiempo paso asesorando a empresas en proyectos de desarrollo de software de misión crítica haciendo uso de nuevos paradigmas de diseño y de programación. Me solicitan debido a una buena reputación acumulada (vayan primero las gracias a mi buen Dios Jehová) liderando proyectos exitosos en los rubros bancario/financiero, seguros, telecomunicaciones y salud principalmente. Y por éxito no me refiero únicamente a los tiempos cumplidos. Me refiero también a la calidad técnica y funcional logradas con la colaboración de excelentes equipos humanos con los que me ha tocado trabajar. Personas que han captado con entusiasmo estos nuevos paradigmas que se les ha dado a conocer y que muy rápidamente los han puesto en práctica, muchas veces cambiando completamente los procedimientos de diseño y desarrollo en sus empresas.
Al mismo tiempo que asesoro a equipos de trabajo en estos proyectos de misión crítica, a menudo la empresa en cuestión desea que capacite también a los demás profesionales que no hicieron parte de estos grupos de trabajo. Me piden que los capacite en esta “Nueva Arquitectura”, como suelen llamarla. Siempre acepto gustosamente hacerlo, aunque es difícil para mí explicarles de primera que no hay ninguna “Nueva Arquitectura”.
Nombres nuevos, conceptos antiguos
No hay ninguna Nueva Arquitectura. Lo que hay es simplemente una mayor claridad respecto de cómo aplicar correctamente conceptos teóricos que ya llevan al menos 2 décadas tratando de imponerse en la mente de nosotros profesionales informáticos, desgraciadamente aún sin lograr la comprensión y aceptación esperados. Para apoyar esto que afirmo, citaré a un gran arquitecto/artesano de software reconocido internacionalmente y cariñosamente llamado Uncle ‘Bob’ Martin. Esto dijo en su post Arquitectura que Grita del 2011:
Una buena arquitectura de software permite que decisiones relacionadas con frameworks, bases de datos, servidores web u otros elementos y herramientas puedan ser diferidos en el tiempo. Una buena arquitectura hace innecesario decidir acerca de Rails, Spring, Hibernate, Tomcat o MySql hasta bien más adelante en el proyecto. Una buena arquitectura también hace fácil cambiar de idea respecto de dichas decisiones. Una buena arquitectura enfatiza los Casos de Uso y los desacopla de los temas periféricos.
Y por supuesto debo citar la conclusión de su post:
Tus arquitecturas debiesen hablarles a tus lectores acerca del Sistema, no acerca de los Frameworks utilizados en tu sistema. Si estás construyendo un sistema de asistencia médica, entonces cuando nuevos programadores vean tu repositorio de código fuente, su primera impresión debiese ser: “Oh, esto es un sistema de asistencia médica”. Estos nuevos programadores debiesen ser capaces de aprender todo acerca de los Casos de Uso del sistema, sin tener que saber nada todavía acerca de cómo éste es ‘entregado’. Ellos deberían acercarse a tí y decirte: “Vimos cosas que se parecen a modelos, pero ¿dónde están las vistas y los controladores?”, y tú deberías contestarles de vuelta: “Oh, esos son detalles que no merecen su preocupación por el momento. Nosotros se las explicaremos más tarde.”
En el mismo post, Uncle Bob hace mención de los planos de arquitectura de un edificio. Estos por lo general hablan claramente acerca de qué clase de edificio ellos tratan. Al mirarlos no es difícil determinar si se trata de una casa residencial, una biblioteca o un edificio de oficinas. Temas relacionados con los materiales utilizados o las técnicas de construcción a aplicarse pueden estar presentes en los planos pero no son lo que salta a la vista. Lo que salta a la vista, o “lo que grita”, es el tema principal del plano: una Casa, una Biblioteca o un Edificio de Oficinas. En el primero se ven la cocina, la sala de estar, los baños y dormitorios. En el segundo se notan claramente las salas de estudio, el hall de entrada, las vias de escape, etc. Y en el último se deben ver las oficinas, los ascensores, los pasillos, etc.
Similarmente, una arquitectura correcta de software debe “gritar” o hacer saltar a la vista su tema principal: un sistema contable, una integración entre sistemas, un sistema de asistencia a la venta o a la facturación, etc. El “plano” de cada uno de esos sistemas debe hacer que salte a la vista los elementos más importantes de sus Casos de Uso. En un sistema contable saltaría a la vista entidades como Cuenta Contable, Transacción, Centro de Costo, entre otros. Luego, al mirar más detenidamente, se debería poder observar las operaciones más importantes: Creación de Asiento Contable, Emisión de Voucher, Orden de Facturación, etc. Lo mismo ocurriría con los planos de cada uno de los demás sistemas mencionados.
Haciendo uso de un lenguaje semántico adecuado, como Domain-Driven Design o UML por ejemplo (o sea cual sea tu ontología preferida), las principales entidades, junto con sus más importantes operaciones, estarían ubicadas dentro de un modelo que mostrara claramente su relación con el contexto donde existieran. Un modelo de un sistema de ventas no puede ser lo suficientemente claro si no muestra su relación con los sistemas de catálogo de productos, de inventario, de maestro de clientes o de facturación de la compañía.
Qué NO debería afectar tu Arquitectura
De modo que lo primero a aclarar durante toda charla que me toca dar es esto: lo más importante en cualquier proyecto de desarrollo de software es poder definirlo a un nivel de abstracción independiente de motores de bases de datos, de sistemas operativos, lenguajes de programación o frameworks. Es más. Como el mismo Uncle Bob dijo en su post:
¿Es la Web una arquitectura? ¿El hecho de que tu sistema sea ‘entregado’ por la web acaso debe dictar su arquitectura? ¡Por supuesto que no! La Web es un mecanismo de entrega, y la arquitectura de tu aplicación debería tratarla como tal. El hecho de que tu aplicación sea entregada sobre la web es un detalle y, por lo tanto, no debería dominar la estructura de tu sistema. En realidad, el hecho de que tu aplicación sea entregada sobre la web es algo que deberías diferir en el tiempo. La arquitectura de tu aplicación debiese ser lo más ignorante posible de la forma como esta será entregada. Debieras ser capaz de entregarla como una aplicación de consola, o como una aplicación web, o como una aplicación de escritorio, o inclusive como un web service, sin añadir indebidas complicaciones o cambios a la arquitectura fundamental.
De lo anterior se desprende que ni siquiera el hecho de que el proyecto sea una aplicación Web debiese importar al momento de definir una arquitectura.
¿Por qué es esto tan importante? Porque la tendencia natural de todos nosotros es ‘enamorarnos’ de los frameworks, lenguajes, tecnologías y paradigmas. Nos dan un martillo y andamos viendo clavos por todas partes. Aprendemos un conjunto de herramientas con las que llegamos a tener cierto éxito en un proyecto, para luego andar por la vida buscando el proyecto donde hacer uso de las primeras. No obstante, usar las mismas herramientas una y otra vez no es en verdad el peor problema. El peor problema es que tendemos a DISEÑAR nuestras soluciones EN FUNCIÓN de dichas herramientas, teniendo presente SUS limitaciones. ESTE es el pecado que te ruego, querido(a) lector(a), que no vuelvas a cometer.
Evita el Enamoramiento Tecnológico
Este ‘enamoramiento’ he podido observar que se produce principalmente por dos razones:
- Profesionales jóvenes descubren algún framework o herramienta que les permite crear todo aquello que no tenían idea de cómo hacerlo, o que les había costado mucho hasta entonces con otras herramientas. El ‘Time to Market’ es su prioridad. Descubren esta plataforma que les permite hacer todo más rápido, de forma más simple, con buena documentación en Internet y además con una gran comunidad dispuesta a responder todas sus dudas… Difícilmente lograrás hacer que este profesional mire a otro lado. Así es como tenemos a los fanclubs de Rails, Grails, Python, .NET, Spring, Yii, CakePhp, CodeIgniter, Symphony, Play, Sinatra por mencionar solo algunos. Estos excelentes profesionales jóvenes e inteligentes logran introducir el uso de estas plataformas en empresas de pequeño y mediano tamaño, o en startups. Estas empresas no ponen muchas trabas a la implementación de nuevas tecnologías, especialmente cuando ven que obtienen buenos productos en poco tiempo gracias a ellas.
- Profesionales más experientes, por otro lado, han aprendido con sus propios errores que el ‘Time to Market’ no es lo único importante. Se preocupan más por el resto del ‘Ciclo de Vida’ de la aplicación. Se preocupan que vayan a encontrar en el mercado profesionales no costosos que puedan mantenerla. Se preocupan de que puedan contar con empresas serias (y demandables) para que les den soporte en el momento que requieran. Y con mucha razón se preocupan de todo eso. Estos profesionales suelen elegir aquellas tecnologías y plataformas que llevan más tiempo implementándose en aplicaciones de misión crítica de grandes empresas. De hecho, el área de Operaciones de estas grandes empresas exigirán que se utilicen estas tecnologías más ‘confiables’. Y un profesional experiente, preocupado de mantener su trabajo, difícilmente se pondrá a discutir con Operaciones para que den soporte a una nueva tecnología que él no es capaz de hacerse responsable. Así es como encontrarás en las grandes empresas tecnologías como EJBs, WebSphere MQ, Java tradicional, .NET tradicional, Visual Basic, Delphi o PHP tradicional (por tradicional me refiero a la no utilización de frameworks adicionales). (Véase mi post anterior Luchando contra el Memento en la Informática)
Con el paso del tiempo, lo que he visto que suele pasar es que personajes del primer grupo se pasan al segundo. Lo que antes era innovador y ‘cool’ con el tiempo se vuelve tradicional y confiable. Al tiempo que siempre aparecerán nuevos y mejores paradigmas, frameworks y herramientas.
¿Cuál es mi punto entonces? Mi punto es que ambas visiones tecnológicas nada tienen que ver con la Arquitectura de cualquier Software. Y lo que suele en realidad ocurrir es que alguna de estas visiones se interpone en el camino de la elección de la mejor arquitectura para el desarrollo de aplicaciones, muchas de ellas de misión crítica, al interior de una compañía.
Considera la historia
La llegada de Internet hizo que las empresas desde hace 1 década empezaran a desarrollar una capa de aplicaciones PARA la Web. Con ello llegaron a probar diversas tecnologías y técnicas hasta encontrar aquellas que más les acomodaban: profesionales más abundantes en el mercado y por lo tanto más baratos, plataformas que les permitían hacer de todo con un solo lenguaje y un único IDE, estilos de desarrollo que servían para hacer tanto demonios como servicios como aplicaciones de escritorio como aplicaciones web, estilos de diseño que centralizaban la data en un solo lugar facilitando su administración y control, etc. Todo lo anterior logrando un nivel de desempeño relativamente aceptable para una carga de trabajo bastante pequeña (al menos en comparación con las demandas de hoy).
Estas aplicaciones PARA la Web fueron, durante al menos los últimos 10 años, un mundo aparte dentro de TI en la mayor parte de las empresas. Las metodologías, herramientas, procedimientos e inclusive proveedores eran diferentes para los sistemas de backoffice en relación al ‘Canal Online’ como aún suelen llamar algunos a este mundo de aplicaciones PARA la Web. No sintieron nunca que la Web en realidad les iba a tocar el core de sus aplicaciones ya existentes. Siguieron coexistiendo ambos mundos y evolucionando por separado.
Cuando tiempo atrás se dieron cuenta que ambos mundos (Backoffice y Web) debían comunicarse, empezó la ‘fiebre’ de SOA (Service-Oriented Architecture). De hecho, casi todo el mundo vivió practicamente lo mismo:
Partieron implementando los populares Web Services SOAP (Simple Object Access Protocol). Esta tecnología le permitió a todos rápidamente hacer que sus mundos interoperaran. Como suele pasar a toda solución simple y económica, evidentemente abusamos de ella. Al poco tiempo pulularon por todas partes estos servicios y se perdió su control. Muchos ya no sabían qué realmente hacía un determinado servicio o cómo reutilizarlo. Vi casos donde Operaciones tenía servidores que no sabían si podían bajarlos porque no tenían idea de quién consumía sus servicios ni para qué eran.
La preocupación general ahora pasó a ser la Gubernabilidad de los servicios (SOA Governance). Cómo administrar sus ciclos de vida desde un único lugar. Y todos empezaron a mirar a los Enterprise Service Buses de IBM, Oracle y en unos cuantos casos a Microsoft (o algún ESB Open Source) como la solución a todos sus problemas. Enfim, de una u otra manera las empresas lograron controlar sus Web Services.
No obstante, al solucionar el problema de las comunicaciones internas y la administración del ciclo de vida de los servicios, un problema mucho mayor se hizo evidente.
Los nuevos Clientes/Usuarios y la TransMedia
Para poder hablar de Arquitectura de Software, pienso que es preciso comprender cuál es la piedra en el zapato que tienen todos en este momento. Por eso tuve que contar un poco de historia.
Conté que existen estos dos mundos que han evolucionado por separado, a ritmos distintos, dentro de cada compañía: el Backoffice donde reside toda la data del negocio y donde se ejecutan los procesos más complejos y críticos de la empresa, en conjunto con aplicaciones internas que pueden conectarse directamente a este Backend. Y el Frontend Web que hoy es la cara hacia los clientes. ¡Ojo! Clientes que hoy en día ya se sienten Usuarios, no solo Clientes.
Del mismo modo como años atrás se hizo evidente la necesidad de que cada empresa, servicio o producto tuviese su sitio web (y era mal mirado el que no lo tuviera), hoy es mal mirado el que alguna empresa no tenga aplicaciones de autoatención disponibles en la Web. Los Clientes quieren ser Usuarios de estas aplicaciones. Quieren contar con funcionalidades de consulta de precios o de contratación de servicios y productos. Quieren consultar estados de cuenta. Quieren ver detalles de consumo. Quieren pagar sus cuentas. Quieren comprar y vender. Quieren opinar. Quieren consultar bases de datos de conocimiento para descubrir cómo resolver posibles problemas con los productos o servicios contratados. Quieren atención personalizada via chat. Quieren verificar factibilidades legales o técnicas. Quieren consultar direcciones de atención. Quieren comparar precios y calidades entre compañías. Quieren agendar atenciones a domicilio, etc, etc, etc.
Y estos nuevos Clientes/Usuarios quieren todos estos servicios disponibles en sus PCs del trabajo, en sus casas, en sus plasmas y en sus dispositivos móviles. Lo quieren ahora y lo quieren ya. Piensan: ‘si tengo acceso global e instantáneo a mares de información así como a redes sociales en forma gratuita, ¿por qué debo esperar menos de mis proveedores de seguros, cuentas corrientes, créditos bancarios, salud, comunicaciones, ente otros, ya que les pago grandes cantidades de dinero mensualmente?’
Es más, como lo señala Martin Fowler en su reciente post TransMediaApplication:
Yo considero el deseo de crear una aplicación móvil como una Idea Equivocada. Tal idea inmediatamente enmarca la aplicación móvil como algo separado del sitio Web, como también es equivocado pensar que simplemente estás desarrollando un sitio Web. En lugar de eso, debes empezar con el usuario, descubriendo qué es lo que él quiere hacer y cómo el software puede ayudarlo a lograr eso. Al pensar en estas cosas, todos debemos pensar en modo TransMedia – y por todos me refiero a todas las partes del equipo: Experiencia de Usuario, Arquitectura de Software, Administración del Proyecto… La aplicación, así como todo el equipo que la construye, deben ser vistos como un todo único, todos dedicados a hacer a los usuarios felices.
Por TransMedia, Martin Fowler se refiere a la experiencia del usuario que hace uso de distintos dispositivos, en diferentes contextos, de una misma aplicación. Como el caso de Netflix, por ejemplo, donde el usuario cuenta con aplicaciones para escritorio, Tablet, Smartphone y SmartTV. Todas le proporcionan una experiencia similar pero al mismo tiempo le entregan funcionalidades propias del contexto en que se encuentra el usuario.
Por lo tanto, tenemos hoy a un Cliente/Usuario que quiere funcionalidad sobre la Web, para sus distintos dispositivos y que le proporcionen la sensación de “Yo tengo el control” o “Yo gobierno“. Y tienen toda la razón. Viven en un mundo globalizado y tecnológico, por lo tanto es justo esperar que sus proveedores tradicionales se pongan a la altura de los tiempos y también les proporcionen servicios globalizados, tecnológicos y además bien diseñados.
Toda una generación de Gerentes Comerciales saben esto y presionan cada día a sus Gerentes Generales para que estos a su vez logren que TI responda a las expectativas. Pero TI no lo hace. TI no logra publicar en Internet toda esta funcionalidad esperada por los Clientes/Usuarios con el desempeño requerido.
La Arquitectura Correcta
Cuando las empresas le han exigido a sus áreas de TI que publiquen aplicaciones sobre la Web con funcionalidades como las listadas anteriormente, han terminado muy decepcionadas. Sucede que en ambiente de producción han descubierto que no son capaces de ofrecer un nivel de desempeño aceptable frente a una carga transaccional mucho mayor a la acostumbrada.
Así es como hoy vemos sitios bancarios, de compañías de seguro, de las áreas de salud, comunicaciones, retail y tantos otros con funcionalidad pobre e insuficiente. Son lentos y a menudo se caen de las maneras menos elegantes posibles. No pocos son lentos hasta para la funcionalidad más básica como consultar la última factura adeudada o el precio de un producto o servicio. Como son incapaces de manejar hasta las peticiones más simples, menos pueden ser proactivos en cuanto a ayudar al Cliente/Usuario a encontrar lo que busca, o a proponerle ofertas personalizadas inteligentes, etc.
De lo que puedo dar fe es que esto no se produce por falta de voluntad por parte de las áreas de TI. Es que simplemente su Arquitectura medular se interpone como una gran limitante. Así es, querido(a) lector(a). Por pura ignorancia, durante los últimos 15 años la mayor parte de nosotros hemos venido desarrollando el software de nuestros negocios bajo premisas y prioridades equivocadas.
Hemos descuidado completamente 2 principios, en mi humilde opinión, básicos para una Arquitectura que sea verdaderamente escalable, fácilmente mantenible y altamente extensible:
Armada a partir de Bloques de Abstracción adecuados
Hasta el presente día aún veo que la abstracción que más se maneja en muchas (demasiadas) empresas es la DATA. Para ilustrarlo, he sido testigo presencial del siguiente diálogo:
Subgerente comercial: “Necesitamos que nuestros clientes puedan ver por la página Web de la compañía el detalle de su consumo en el mes.”
Jefe de Proyecto de TI: “Ah eso es fácil. Es solo un SELECT que debemos hacer a la tabla XXXX buscando por el folio de la boleta actual. Claro que tendremos que crear un nuevo índice porque de lo contrario la consulta se pondrá más lenta de lo que ya es.”
Quisiera poder decir que esto es una caricatura de la realidad pero no lo es. Fue un diálogo verdadero en una empresa considerada líder en su sector. Uno de decenas que he presenciado en varias empresas conservando la misma temática.
Esto ilustra mi afirmación de que, para muchas empresas, la Data sigue siendo el centro de sus universos. Tal como afirmé al principio, la experiencia de muchos por varios años fue que con bases de datos relacionales pudieron resolver todos sus problemas, y por lo tanto no la cuestionan como la solución más adecuada a sus actuales y futuros problemas.
Así se entiende por qué ejecutivos internos que no son de TI en no pocas empresas se han sentido obligados a conocer de tablas, campos, filas, índices, procedimientos almacenados y bases de datos. Porque son las abstracciones que sus colegas informáticos les han enseñado a manejar al momento de determinar la solución a un problema de negocio. Peor aún, en muchos lugares todavía las principales herramientas de ejecutivos en general son aplicaciones como TOAD, DB Artisan, DB PowerStudio o SQL Server Management Studio. Como no cuentan con abstracciones superiores con las que trabajar, no les queda más que acceder directamente a la data en su repositorio original.
Para colmo, por Data me refiero a la estructura más simple y básica de todas: Data Tabular. Estructuras más modernas (estructuras orientadas a Grafos, Documentos, Clave-Valor o Familias de Columnas) y que se adaptan muchísimo mejor a ciertos Casos de Uso, son aún completamente ignoradas por la mayoría.
En consecuencia, las Reglas o Lógica de la mayoría de los Negocios actuales han ido a parar a los lugares más equivocados, donde no pertenecen:
Ni muy cerca de la Data
Esto es lo más común de verse. Lógica de Negocio (validaciones, cálculos y composición de información) en muchas partes se ejecuta en el lugar más rápido (hasta cierto umbral de demanda) pero al mismo tiempo menos escalable de todos: en el servidor de Base de Datos.
El gran problema de las Bases de Datos Relacionales es que estas no son capaces de sacarle provecho a la escalabilidad horizontal: tú no consigues mejor desempeño de una base de datos instalándola en dos máquinas. De modo que a menudo uno se encuentra con una sola máquina responsable de mantener alguna enorme base de datos de alguna empresa. Esta máquina por lo tanto tiene que ser poderosísima para cumplir con las solicitudes de todos los usuarios de la empresa. Conforme a ello las empresas invierten anualmente grandes sumas en esta máquina, en la de respaldo así como en los ambientes de desarrollo, testing y certificación. Desafortunadamente, esta arquitectura tiene limitaciones evidentes cuando pasamos a hablar de aplicaciones Web con decenas o cientos de miles de usuarios.
No obstante, lo peor ocurre cuando a estas máquinas que ya son bastante exigidas, les agregamos además lógica de negocio. Y eso es precisamente lo que ocurre cuando las áreas de Operaciones de las empresas determinan que la única forma de acceder a los datos de las tablas sea a través de Procedimientos Almacenados. Claramente se facilita la administración de la seguridad para ellos, pero sin darse cuenta abren la Caja de Pandora: toda una generación de profesionales educados por Oracle, Microsoft o IBM les enseñaron a programar lógica de negocio dentro de sus bases de datos. Después de años acumulando procedimientos almacenados, packages y funciones dentro de estas bases de datos, veo hoy a muchos de mis clientes sufriendo las consecuencias: teniendo que constantemente invertir en mejores servidores capaces de atender un nivel de demanda altísimo, y en ocasiones, con poco éxito.
Si ya sabemos que nuestros servidores de bases de datos son limitados, todos deberíamos estar preocupados ahora de QUITARLES responsabilidad. Si no nos queda otra opción por el momento que seguir manteniendo nuestra data bajo la arquitectura relacional, al menos quitémosles a esas pobres máquinas la responsabilidad de ejecutar lógica de negocio. Esta única acción de por sí extendería enormemente el tiempo de vida de tales servidores. ¿Qué hacer con la lógica de negocio? Evidentemente llevarla a modelos de dominio que pueden ser ejecutados en forma distribuida y replicada en granjas de servidores o Clouds de máquinas baratas y fácilmente administrables. Piensa que empresas como Facebook o Amazon ejecutan todo su modelo de dominio sobre infraestructuras de miles de servidores, pero con un costo unitario de entre 300 y 500 dólares apenas.
No quiero adelantarme en la conclusión. No obstante sí deseo que quede claro desde ya que ejecutar lógica de negocio en la misma máquina física donde reside la data es evidentemente más rápido, pero para una cantidad limitada de transacciones. Este límite es sobrepasado por lejos cuando publicamos aplicaciones sobre la Web. Para estos nuevos escenarios es vital considerar soluciones alternativas más escalables.
Ni muy cerca del Usuario
El error anterior en ningún caso excluye el cometer este otro: situar la lógica de negocio en el mismo frontend de las aplicaciones. Mi experiencia dice que no todos los que sitúan esta lógica en el frontend hacen lo mismo en el backend. Aunque sí TODOS los que tienen lógica de negocio en la base de datos, la complementan con lógica de negocio en el Front. Inclusive en las mismas vistas de usuario.
Esto también es incorrecto y lleva a la repetición una y otra vez de lógica del dominio en incontables lugares. Si la peor consecuencia del error anterior es la sobre exigencia de una única máquina, en este otro caso es la mantenibilidad de las reglas del negocio: cualquier cambio en ellas pasa a tener impactos que se escapan completamente al control de TI. Y cuando TI teme realizar modificaciones debido a que desconoce los reales impactos, quien sufre es el negocio directamente ya que no cuenta con la versatilidad necesaria para mantenerse competitivo en un mercado cambiante.
En el lugar que corresponde
Y si no es la Data el centro del Universo, ni tampoco las Vistas obviamente, ¿qué debería serlo entonces? Una vez más citaré a nuestro amigo Uncle Bob en su post La Arquitectura Limpia del mes de agosto de 2012:
Entidades encapsulan reglas de negocio Empresarial. Una entidad puede ser un Objeto con métodos, o puede ser un conjunto de estructuras de datos y Funciones. No importa qué sean mientras estas entidades puedan ser utilizadas por muchas aplicaciones dentro de la empresa.
Si no tienes una empresa, y simplemente estás escribiendo una aplicación simple, entonces estas entidades serán los objetos de negocio de tu aplicación. Ellos encapsulan reglas más generales y de alto nivel. Ellos son los menos probables de ser modificados cuando algo externo cambie. Por ejemplo, uno esperaría que estos objetos no fuesen afectados dado un cambio en la navegación de páginas o en la seguridad. Ningún cambio operacional de ninguna aplicación en particular debiese afectar la capa de entidades.
De manera que existe un nivel de Abstracción mucho más útil, escalable, extensible y reutilizable que tan solo tablas o procedimientos almacenados. Es la Abstracción de Entidades junto a la Lógica encapsulada en ellas. Al conjunto de estas Abstracciones o Entidades se les conoce como ‘Modelo del Dominio’. Este es un concepto antiguo, lo sé. Yo mismo lo vengo repitiendo hace una década en mis clases, charlas y asesorías. Y sin embargo aún no veo a una empresa grande que realmente esté acostumbrada a trabajar a este nivel de abstracción a escala corporativa. Jefes de Proyecto hábiles aplican esto en algunos de sus proyectos pero ni siquiera Arquitectos Corporativos se preocupan de mantener actualizados sus ‘planos’.
Domain-Driven Design, que ya cité al principio, es hoy en día el approach a la Ingeniería de Software que mejor guía ofrece respecto de cómo representar el conjunto completo de sistemas computacionales de una empresa, bajo un modelo de abstracciones orientado a las principales entidades y contextos de un dominio.
Uncle Bob una vez más expresa de manera muy simple y gráfica esta clase de Arquitectura de la que estamos hablando:

Bajo el paradigma popular de las tres capas, la Data suele figurar como la capa fundacional, por debajo de las demás capas como si fuera la más importante. En contraste, de acuerdo a la visión más moderna expresada en el gráfico, si no te fijaste todavía, las bases de datos aparecen en la última capa exterior, al igual que cualquier otro sistema externo al Dominio y al igual que las mismas interfaces gráficas de las aplicaciones. El centro de la Arquitectura Limpia son las Entidades del Dominio, las que a su vez encapsulan las reglas de negocio corporativas. Sigue a esta capa la de los Casos de Uso. Allí también residen Objetos pero estos representan a los Casos de Uso de las aplicaciones dentro de una empresa, encapsulando las reglas propias únicamente a estos Casos de Uso. Luego viene la capa de adaptadores hacia las interfaces externas. Allí se encuentran los Gateways, Controladores y Presentadores. Para finalmente, en lo más externo, ubicarse las interfaces gráficas, sitios Web, bases de datos, Web Services, enfim, todo lo que haga de Interfaz hacia actores o sistemas externos. Es también en esta última capa donde se ubicarán los Frameworks, plataformas de Integración (ESB o MOM) y otras herramientas.
Las dependencias son siempre desde afuera hacia dentro, nunca al revés. Cada capa conoce únicamente la siguiente capa hacia el interior del círculo. La figura que se encuentra abajo a la derecha de la imagen simplemente ilustra cómo es posible hacer que una capa interna pueda invocar a una más externa sin que se rompa la regla de Dependencia hacia el Interior: mediante la implementación de Interfaces y aplicando la técnica de Inyección de Dependencia, haciendo uso de estas interfaces.
Conceptual y Tecnológicamente Independiente
Ya vimos que una Arquitectura Correcta se arma a partir de Bloques de Abstracción adecuados. El segundo principio básico a cumplir es el desacoplamiento conceptual y tecnológico de nuestra Arquitectura.
Uncle Bob plantea en su post los aspectos fundamentales que debe proporcionar un estilo de Arquitectura:
- Independiente de Frameworks. La arquitectura no depende de la existencia de alguna librería de software cargada de funcionalidad. Esto te permite utilizar a los frameworks como herramientas, en lugar de tener que ajustar tu software a sus limitaciones.
- Testeable. Las reglas de negocio pueden ser testeadas sin la Interfaz de Usuario, Base de Datos, Servidor Web o cualquier otro elemento externo.
- Independiente de la Interfaz de Usuario. La UI puede cambiar fácilmente, sin que sea necesario cambiar el resto del sistema. Una Web UI podría ser reemplazada por una UI de consola, por ejemplo, sin tener que cambiar las reglas del negocio.
- Independiente de la Base de Datos. Tú puedes cambiar sin problemas desde Oracle o SQL Server hacia MongoDB, BigTable, CouchDB o cualquier otra cosa.
Volviendo al diagrama propuesto por Uncle Bob, refiriéndose a la capa más exterior de él, el arquitecto nos dice:
En esta capa es donde van todos los detalles. La Web es un detalle. La Base de Datos es un detalle. Nosotros mantenemos todas estas cosas afuera, donde pueden hacer menos daño.
Una última palabra sobre los Tests Unitarios
Lo único que quiero recalcar de todas estas definiciones simples y potentes de lo que debe ser considerado una Arquitectura Correcta, es la importancia de diseñar y construir unidades de software en conjunto con tests unitarios automatizados que las ejecuten.
Michael Feathers, otro arquitecto de renombre internacional, en su libro Trabajando eficientemente con Código Legado define como Código Legado aquél que no cuenta con tests automatizados. Tests automatizados, haciendo uso de buenas prácticas bien documentadas así como alguno de los frameworks XUnit open source del mercado, son probablemente la mejor técnica para:
- Diseñar software a nivel de detalle y luego construirlo.
- Integrar el código fuente de distintos miembros del equipo de desarrollo.
- Comprobar el avance real de un proyecto.
- Realizar pruebas de regresión sobre el software.
- Documentar el software.
- Enseñarle a un nuevo integrante del equipo (desarrollador o tester) de qué se trata el software.
- Tener el control del proyecto ya sea durante su construcción, o al mantenerlo durante el resto de su ciclo de vida.
Lo anterior explica mejor a qué se refiere Uncle Bob, en su lista de aspectos fundamentales de una Arquitectura que recién revisamos, cuando dice que esta debe ser Testeable.
Arquitectura y Agilidad
Por sugerencia de mi amigo Diego Dagum, arquitecto de software en USA, agrego esta sección que no estaba originalmente en mi post. Y él tiene toda la razón: no se puede hablar de Arquitectura de Software Corporativo hoy en día sin explicar su relación con el Movimiento Ágil.
No es novedad que una de las personas no informáticas que más ha influenciado el actual pensar de la Ingeniería de Software, o del Diseño en general, es Christopher Alexander. Este Arquitecto Civil austríaco ha propuesto, principalmente durante las décadas del 60 y 70, teorías originales aplicables al Diseño y a la Arquitectura. Estas ideas han inspirado a muchos arquitectos de software en el diseño de lenguajes de programación, en la formulación del paradigma de la Orientación a Objetos y en la identificación y uso de Patrones de Diseño de Software.
Adicionalmente a lo anterior, las ideas de Christopher Alexander han proporcionado un fundamento teórico potente para nuevas prácticas relacionadas con la construcción de software. A diferencia de las metodologías tradicionales donde el software es diseñado completo al principio (All Design Up Front), para luego ser construido a partir de la documentación del diseño, estas nuevas prácticas apuntan a ciclos incrementales, orgánicos y coherentes de construcción de software, con una fase de diseño por cada una de estas iteraciones.
El Movimiento Ágil, que encierra precisamente a estas prácticas en la forma de Metodologías y Frameworks, obedece a un conjunto de Principios que podemos encontrar en el Manifiesto del Desarrollo Ágil de Software. Este movimiento ha transformado completamente la manera de hacer Arquitectura de Software. Probablemente muchos de nosotros ya veníamos haciendo Arquitectura de Software de acuerdo a estas nuevas prácticas pero sin darle un nombre todavía.
Para entender mejor qué tiene que ver el Movimiento Ágil con la Arquitectura de Software, fíjate en estas palabras de Alexander tomadas de su libro “La Naturaleza del Orden”, refiriéndose al proceso (secuencia de pasos) de desarrollo de un sistema (en el sentido más amplio de la palabra):
Estos pasos [...] siempre parten desde la integridad del sistema tal como es en un determinado momento. Al siguiente momento, tomamos un nuevo paso – introduciendo una nueva porción de estructura [...] al entero sistema. La nueva estructura puede ser enorme, mediana o muy pequeña; puede ser física o abstracta; puede ocurrir en la tierra misma o en la mente de una persona, o en el entendimiento colectivo de un grupo de personas. Pero el punto es que a cada estado de cada proceso de creación, la porción de estructura que es inyectada para transformar y luego diferenciar el sistema completo respecto de su estado anterior, siempre extenderá, aumentará e intensificará la estructura de ese estado anterior al crear más y más fuertes centros de vida.
Es verdad que lo anterior puede sonar bastante teórico. Por eso agrego aquí un comentario más aterrizado hecho por otro arquitecto civil de renombre, David Seamon, respecto de las palabras de Alexander. Estas son algunas de sus conclusiones que seleccioné debido a su evidente aplicación en la arquitectura de software:
- El Arquitecto ya no es un artista descubriendo su diseño a partir de inspiración creativa. El Diseño es un proceso lento y gradual, que involucra tanto movimientos correctos como incorrectos. La inspiración permanece importante pero debe ser equilibrada con persistencia, sentido común y atención empática a las necesidades y limitaciones del mundo real.
- La Arquitectura ya no es Diseño sino Realización, lo que significa que ella ya no se da en una oficina, sino que a través de estudio, descubrimiento, construcción y revisión en terreno.
- El Arquitecto participa de todos los aspectos del desarrollo, teniendo al menos un conocimiento mínimo de elaboración y habilidades de construcción. Él o ella trabajan con los subcontratistas, poniendo atención contínua a la calidad de su trabajo.
- Clientes y usuarios deben ser involucrados durante toda la construcción. Diferentes participantes comprenden diferentes cosas, por lo tanto esta participación grupal a menudo lleva a descubrimientos y posibilidades que al Arquitecto no se le habrían ocurrido por sí solo.
Aplicando precisamente estas ideas, el Movimiento Ágil no ha eliminado el Diseño. Lo que ha eliminado es la ilusión de que es posible diseñar completamente un sistema antes de empezar su construcción. Tal como propuso Alexander, la Arquitectura ya no es una especificación a priori, sino una Visión de un Estado Futuro del Sistema (sea este un edificio, una ciudad o un software).
Esta Visión sirve de guía durante cada iteración de diseño-construcción-entrega. Hablo de iteración porque, especialmente en un sistema complejo, no es práctico pretender realizar un único salto desde el Estado Inicial hacia el Estado Final deseado. Deben haber pasos o estados intermedios pequeños pero completos a la vez. Ya sea que tomemos un único Caso de Uso o un grupo relacionado de ellos, diseñaremos y construiremos la estructura necesaria para avanzar desde el Estado Anterior hacia un Nuevo Estado del sistema donde se añade funcionalidad útil y verificable por el usuario. Al empezar el siguiente ciclo, diseñaremos a partir de lo anterior que construimos, tomando en consideración las lecciones aprendidas, realizando los ajustes necesarios, pero jamás olvidando la Visión que nos proporciona la Arquitectura del Sistema que nos dice hacia dónde nos dirigimos.
Lo anterior no solamente es correcto teóricamente, si aceptamos la propuesta de Alexander, sino que es también muy práctico. Mi experiencia me ha convencido sin dejarme dudas de lo ventajoso de este camino. El Diseño Evolutivo, cuando es enmarcado en una estricta disciplina y es realizado por todo el equipo de desarrollo en conjunto con testers y usuarios, produce éxito.
Para lograr el éxito, la Arquitectura del software ya no puede ser un documento redactado por una sola persona inspirada y creativa, que luego se le entrega a un equipo de desarrollo para llevar a cabo los requerimientos de dicho documento.
La Arquitectura debe ser un documento con una Visión de lo que se espera lograr, obedeciendo las sugerencias antes presentadas en este mismo post. El Arquitecto debe ser capaz de comunicar esta Visión a cada miembro del equipo. Y debe lograr involucrarlos a todos, junto con los usuarios, en cada una de las fases de diseño que se produzcan a lo largo de un proyecto. Liderará el diseño pero también acompañará la construcción, poniendo cuidadosa atención a la calidad de lo que realiza cada miembro del equipo. Proporcionará al equipo de un set de herramientas iniciales, aunque al mismo tiempo permitirá el espacio para nuevas ideas y nuevas herramientas, todo lo que el equipo de trabajo sienta que los potencia y ayuda a lograr de mejor manera la Visión compartida.
¿Vale la pena invertir en actualizar la Arquitectura Corporativa?
La verdad es que hoy en día no existe tal cosa como una Arquitectura Corporativa. Empresas medianas y grandes suelen tener algún motor de base de datos relacional potente en el backend. Es muy común ver a DB2, Oracle o SQL Server. Las que poseen plataformas propietarias IBM o HP, suelen exponer servicios cerca de la data, como dijimos antes, en la forma de programas Cobol o C. La integración desde otras plataformas es por lo general via algún Middleware basado en Mensajería como WebsphereMQ o Tuxedo. Las que cuentan con Oracle o SQL Server en el backend por lo general exponen sus servicios, también cerca de la data, en la forma de Procedimientos Almacenados. Estos son accedidos directamente por las aplicaciones mediante algún Proveedor JDBC u OLEDB.
Ahora bien, en el mundo aplicativo existe un popurrí de tecnologías que las empresas han estado tratando de reducir durante los últimos años. De modo que hoy nos encontramos con las industrias más grandes que han concentrado sus inversiones principalmente en plataformas Java, mientras que las menores se han ido por el lado Microsoft y .NET. Y digo industrias, no empresas, ya que las tendencias tecnológicas suelen darse a nivel de industria: la mayor parte sino todas las compañías de un mismo rubro acostumbran implementar las mismas tecnologías.
Evidentemente hay más que únicamente aspectos técnicos a tomar en cuenta al momento de decidir si se debe actualizar la Arquitectura Corporativa (o crear una). Siempre hay aspectos económicos, políticos, estratégicos y sociales que deben ser considerados.
No pretendo proponer un criterio universal, pero sí siento que es necesario hacer notar un aspecto que a menudo veo que es pasado por alto en las compañías: la diferencia entre el Software Utilitario y el Software Estratégico. Martin Fowler lo explica muy bien en su post UtilityVsStrategicDichotomy del año 2010:
¿Cuál es el factor que distingue a los proyectos utilitarios de los estratégicos? Para mí todo tiene que ver con que si la función de negocio que está detrás es un diferenciador para la empresa o no. Si la manera como realizas esa función es una parte crucial de lo que hace que la compañía sea mejor que su competencia, entonces el software que soporta esa función debe ser el mejor que se pueda conseguir. Note que esta distinción no tiene que ver con el software, sino que con la función de negocio. Es como lo escribió Ross Pettit: “Esto no es una separación de TI según la naturaleza de la tecnología, sino según lo que la tecnología hace por el Negocio”.
Luego explica por qué es importante esta distinción:
Una manera en la que esta dicotomía ayuda es al decidir si desarrollar software a la medida o instalar algún paquete del mercado. Ya que la definición de Utilitario es que no representa ningún diferenciador, entonces la opción obvia para estos casos sería comprar un paquete. Para una función estratégica sin embargo, tú no querrás el mismo software que tus competidores ya que esto entorpecerá tu habilidad de diferenciarte.
Neal Ford hace aún otra importante distinción en un post del 2009: lo que es estratégico para la compañía y lo que es táctico para TI. Muchos desarrollos de software que se realizan al interior de una compañía no necesariamente tienen directa relación con su estrategia de negocio, pero son vitales para que TI sea capaz de proporcionar la versatilidad que otras gerencias puedan requerir cuando el mercado lo exija. En esta categoría entran los desarrollos de software horizontal, los que son reutilizados en muchos sistemas tales como Frameworks de Seguridad, Herramientas de Integración, Motores Transaccionales, etc. Normalmente, esta clase de Software también amerita inversión por parte de la empresa, el que finalmente redunda en ahorro al momento de desarrollar o implementar nuevas aplicaciones que harán uso de estos servicios.
Conclusión
Para todo lo que tenga que ver con el Software Estratégico de una compañía, aquel que soporta las funciones de negocio que la diferencian de su competencia, es imprescindible que desde ya esa empresa, si pretende ser líder en su rubro de aquí a 5 años, esté invirtiendo en evolucionar su Arquitectura actual hacia lo que hemos definido en este post como una Arquitectura Correcta. Correcta no desde el punto de vista académico solamente, no por moda o por capricho, sino por los evidentes beneficios prácticos que he intentado explicar brevemente en este post: mejorar el desempeño al aprovechar el escalamiento horizontal (más máquinas pero a la vez más económicas), reducir costos al desarrollar y mantener los sistemas (modelos de dominio centralizados más simples de modificar y extender) y facilitar la implementación de nueva funcionalidad al separar responsabilidades en el software a nivel corporativo. Todo esto sin olvidar que la Arquitectura no es una especificación congelada sino una Visión que evoluciona en el tiempo, con la participación colectiva de todas las personas involucradas en los procesos del negocio: desarrolladores, testers, ejecutivos y usuarios. Todos trabajando para la felicidad de estos últimos.
En los próximos posts estaré mencionando aquellos paradigmas y tecnologías que, a mi parecer, se están imponiendo hoy como los más exitosos al cumplir con los objetivos recién tratados. También pretendo ahondar más en los textos de Christopher Alexander que siento que más deben afectar nuestra concepción de cómo diseñar y construir Software.