Un Viejo Antipatrón: “Too Much Architecture” (Demasiada Arquitectura)

(El siguiente post, originalmente publicado en este blog, cuenta con una versión en inglés adaptada para aspirantes a arquitectos, disponible en SkyScrapr: http://www.skyscrapr.net/blogs/solution/archive/2006/08/28/282.aspx)

 En  Ingeniería de Software al menos, y me imagino que en todas las otras ciencias, existen ideas, conceptos y paradigmas que son fáciles de entender de entrada, pero no tan fáciles de implementar en la práctica

El primer ejemplo que quiero mencionar, es el paradigma Orientado a Objetos (OOP). Yo entendía bárbaro que Triángulo, Rectángulo y Pentágono heredan de polígono, que Cuadrado hereda de Rectángulo mientras que Isóceles, Escaleno y Equilátero heredan de Triángulo, etc
Pero después no era capaz de hacer sólo una aplicación sencilla que me pida ingresar una frase y me devuelva el palíndromo… Digo, lo hacía, pero el único objeto que aparecía era un objeto que modelaba el programa entero, y no había gran diferencia entre el método que tomaba un string y devolvía el string palíndromo, de la función en Lenguaje C que hubiera hecho lo mismo con char* ("char asterisco", puntero a carácter)
Sin embargo, no había dudas de que la programación orientada a objetos era más natural que la estructurada, que el mundo está lleno de objetos cuya utilidad se puede aplicar en más de un contexto y que, por ende, debía ser posible modelar objetos reusables
No hay dudas de que la programación Orientada a Objetos es necesaria. Pero no nos engañemos: es más compleja, no menos, que la estructurada. Entonces al rescate llegaron los Patrones de Diseño: objetos ya premoldeados, con cierta conducta o al menos cierto rol a ocupar en su relación con otros objetos, para usar ante situaciones que solían presentar en forma recurrente
Y de vuelta lo mismo: nos prestaron el libro de Gang of Four (GoF), despues incluso nos lo compramos, nos leímos casi todos los patrones. Creacionales, Estructurales, de Comportamiento… Todos coherentes, todos nos resultaron hasta familiares o, al menos, en todos los casos nos pareció recordar un contexto pasado en que lo pudimos haber aplicado…
Pero después, cuando nos largaban solos para armar la aplicación… cómo era? Qué difícil, no? Veintitantos patrones y no sé cuál cazzo agarrar!

Y así estuve un tiempo hasta entrar, como les pasa a varios aún hoy, en el segundo estadío: vamos a aplicar los patrones como sea, porque si la aplicación no usa patrones… es porque algo estamos haciendo mal. "Vos metele Singleton a todo", "hice un adapter buenísimo! te independizás de todo!". De todo menos de tener que adaptarte a tu adapter

De nuevo, me corto la lengua antes de decir que no hay que usar patrones. A lo que voy es a que es fácil caer en la tentación de abusar y, como cualquier medicamento, el que exagera la dosis convierte al remedio en una nueva enfermedad

Dos adicciones de los últimos tiempos, digamos, de este nuevo siglo, parecen ser

-La manía de querer usar siempre la última versión de todas las cosas: del framework .NET, de Spring, de Eclipse, de lo que sea, sin medir si realmente vamos a mangiar de entrada sus beneficios. En muchos casos ni siquiera tenemos claros esos beneficios cuáles son, o quizás los conocemos pero no si realmente nosotros tenemos un issue fuerte ahí

Estos días hablo mucho con Claudio, el arquitecto de una financiera santiaguina que parece estar muy desvelado por el desparrame de tecnologías alrededor de .NET 2.0 (las software factories de patterns & practices, el upgrade a .NET 3.0 CTP, LINQ, etc) sin medir del todo si con las mejoras de un mainstream .NET 2.0, el que se lanzó a finales del año pasado, no es más que suficiente
Insisto: yo no estoy en contra de la modernidad. Pero si en el laburo te pidieron que saques algo andando, probar cosas nuevas es copado, siempre y cuando te ayuden a sacar lo que te pidieron en el laburo mejor ("mejor" es difuso de definir, pero suele ser un ponderado entre "fácil de mantener", "rápido en términos de mercado", etc)
La otra adicción del nuevo milenio parece ser Object Relational Mapping (O/R-M). Como con OOP, patrones de diseño, etc, vuelvo a reiterar que no me planto contra esta tecnología. Digo: si después, como he visto en 50 mil foros de discusión (y no miento), te vas a estar preguntando cómo hago para no tener que cargar veinte mil objetos si lo único que quiero es mostrar código y descripción en una tabla… Revisá bien qué tan listo estabas para subirte a O/R-M y si de veras, así como están los mappers de hoy, son la solución que necesitás o un nuevo problema que vas a tener que resolver

(Jesse Tower escribió)

Hola todos,
A lo mejor alguno me pueda dar alguna guía para el problema que enfrento. Estamos construyendo una aplicación web empresarial estándar, 3 capas usando nuestra propia capa de mapeo objeto/relacional

Varias páginas web han sido identificadas para optimización en nuestro sistema, en la medida en que se vio que reciben un montón de tráfico del usuario, y que todas ellas contienen un número considerable de GridViews complejos. En cada carga de página, hay un montón de contención en la base de datos en la medida en que saca los datos necesarios y construye el grafo de objetos de dominio. Por ejemplo, varios de los GridViews despliegan datos de entidades anidadas en otras entidades, lo que deriva en un montón de carga perezoza (lazy-loading) transcurriendo detrás de la escena

Me gustaría optimizar algunos de los GridViews en esas páginas construyendo vistas de la base de datos, que seleccionen sólo las columnas necesarias que necesitan desplegarse. Después escribiría clases mitad entidad mitad dominio para visualizar. Estas clases serían usadas principalmente en desplegado de datos en esas páginas, y por eso serían en cierto modo centradas en el caso de uso

No obstante, no puedo encontrar por ningún lado artículos o ejemplos que me permitan intuir cómo esto me va a impactar en el resto del sistema. Cómo debería modelar las clases entidad para la vista, siendo que contienen campos duplicados de otras entidades? Hay algo que necesite revisar para cuando introduzca esas entidades disjuntas en el diseño del sistema?

Alternativamente, podría no calentarme tanto, y simplemente saltearme nuestra lógica de dominio y capas ORM, accediendo así la vista en la forma antigua de cargar un DataTable usando un DbCommand, o incluso atando controles SqlDataSource a las GridViews en cuestión. Después de todo, estamos con los plazos recortados para distribuir un producto que funcione. Pero tengo miedo de que esto resulte en otro eje de ortogonalidad, si se quiere, en el diseño del sistema, y de esta manera me puede conducir a más dolores de cabeza de mantenimiento en el futuro

Algún comentario acerca de cómo debería proceder? Gracias

(Diego Dagum escribió)

Jesse
Espero serte útil con mis reflexiones acá. Te agradezco porque vos me sos útil dandome el ejemplo que necesitaba para explicar por qué O/R-M es un arma de doble filo

Primero que nada, la idea de usar mapeadores O/R es no perder mucho tiempo escribiendo largas lógicas de acceso a datos (seguramente no tan complejas pero largas en líneas de código y, así, en tiempo). Entonces, si entender lo bonito, lo malo y lo espantoso de los mapeadores O/R es complejo y toma mucho tiempo, supongo que entendés que estás reemplazando un problema viejo y conocido por otro nuevo y desconocido

Hay algunas claves que rescato de tu post

  • Contención en la base de datos por construir grafos de objetos
  • Intenciones de optimizar mediante vistas de la base de datos
  • Y lo fundamental (lo dijiste vos, no yo): centrado en casos de uso

Simplicidad es la respuesta. Simplicidad es uno de los pilares de la metodología eXtreme Programming (un proceso de desarrollo de software con énfasis en los entregables, similar que tu contexto). Habitualmente yo modelo la lógica de dominio en clases más relacionadas con el proceso que con las entidades. Quiero decir, prefiero el enfoque dirigido por los datos. Este enfoque implica modelar las entidades mayormente reflejando el esquema de la base de datos (por favor, no una copia exacta, pero considerando cómo los datos están organizados en el repositorio de persistencia)

Este enfoque tiene sus contras porque es en cierto modo acoplado, pero la alternativa es -en mi opinión- peor. La alternativa es el enfoque dirigido por los objetos, que implica modelar entidades sin considerar el esquema de la base de datos (cerrando la brecha en la capa de acceso a datos, ya sea mediante código, a través de mapeadores O/R, frameworks de persistencia como ADO.NET o algún otro mecanismo). El enfoque dirigido por los objetos no está acoplado

Cuanto menor la brecha entre las entidades y el esquema de la base de datos, más delgada la lógica de acceso a datos y he aquí la razón por la cual prefiero el enfoque dirigido por los datos

Si seguís ese patrón, podés asociar GridViews directo a las tablas de la base de datos (y esa tarea es gratis en Visual Studio 2005). Visual Studio 2005 genera todas las líneas de código necesarias y es muy rápido. Admito que, desde un punto de vista arquitectónico, no hay demasiado código para reusar. Pero si el tiempo apremia, Jesse, alineá la tecnología con el negocio primero, antes de que el negocio se encargue de la tecnología

Este ensayo es obsoleto en términos de tecnologías aplicadas, pero útil en términos de conceptos, y ultimamente está siendo varias veces recomendado en este foro

Diseñando Componentes de Capa de Datos y Pasando Datos a través de las Capas

Espero estar dándote soluciones y no nuevos problemas

(Jesse Tower escribió)

Concuerdo con varios de tus puntos. Primeramente que el framework .NET, y ADO.NET en particular, son hoy por hoy inadecuados para desarrollar soluciones que empléen cierta forma de O/R-M. Tenés que hacer un cachito de esfuerzo o comprar un componente de un tercero para dejarlo andando. Lo que sea, tu recomendación es un poco tardía para mí, puesto que acá ya tenemos una base de código establecida. Si yo pudiera empezar de nuevo, probablemente al menos reconsideraría el camino que tomamos al construir esta aplicación. Esto amerita la pregunta: por qué tomamos el camino que tomamos, en primer lugar? Por qué no usamos simplemente las herramientas que ya están ahí? Son suficientemente buenas, después de todo, no?

Creo que la respuesta a esa pregunta es un tanto subjetiva, y depende de las necesidades de tu aplicación, y llegado el momento, de las necesidades de tus clientes. En nuestro caso, necesitábamos desarrollar un sistema que pudiera bancarse un monto significativo de cambios en reglas y requerimientos de negocio. El sistema necesitaba quedar listo a la posibilidad de incorporar cierto número de subsistemas. Las arquitecturas OO bien diseñadas y altamente desacopladas son adecuadas para manejar esto. Tengo la impresión de que este aspecto de la orientación a objetos fue enfatizado en base al así llamado beneficio del reuso de código por colegas y universidades. Muchos instructores y profesores dicen verdades parciales tales como que "la orientación a objetos es buena, porque hace a tu código más reusable", en tanto que se pierden de apuntar a los otros beneficios, así como a las desventajas (mayor complejidad interna, mayor tiempo gastado de entrada para obtener un sistema andando, etc). Quiero decir, vamos, en realidad, podés escribir cierto código orientado a objetos no reutilizable

Tal como está ahora, es realmente simple agregar un nuevo conjunto de servicios de negocio a la aplicación, sin que eso impacte en el resto del sistema existente. Ése fue uno de nuestros primeros objetivos, y yo pienso que lo cumplimos. La "dolorosa" que nos llegó ahora es por el lado del rendimiento

Supongo que uno de los problemas de O/R-M, y del desarrollo dirigido por entidades en general, es que conllevan un riesgo de terminar enfocándote demasiado en las entidades y sus relaciones. Es fácil olvidarse de la riqueza de otros patrones, idiomas, etc, que tenés en tu caja de herramientas OO, listas para disponer. Qué hay para contar de los objetos de tipo creacional o de comportamiento?

Tengo que admitir, me metí en este brete durante este proyecto. Dejé que O/R-M me cegara. Resigné un montón de fines de semana buscando y tratando de imaginarme qué debería hacer cuando llegue el Lunes. Definitivamente no puedo borrar todo el código que desarrollamos laburando duro. Pero lo que voy a hacer es esto:

Primero, voy a refactorizar parte del código del controlador en las páginas conflictivas para llevarlas a clases de la capa de servicios, empleando inyección de dependencias. Yo puedo después escribir versiones especializadas, donde haga falta, que accedan a una vista de la base de datos optimizada. Sí, nuestra aplicación no implementa actualmente mucho de una arquitectura orientada a servicios; la lógica de dominio está fuertemente acoplada a la capa de presentación. Mirando hacia atrás, pienso realmente que pudimos haber cosechado un montón de beneficios buscando un diseño SOA, pero ahora es demasiado tarde. Quizás para la segunda iteración

Segundo, voy a implementar caché secundario en esos objetos de capa de servicio

Con suerte, probando un poco, puedo hacer caer la penalización de rendimiento a niveles irrelevantes

Interesante, no? El foro siguió aunque lo que quiero destacar es lo fácil que es "hacer la difícil". Arrivederci

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

2 respuestas a Un Viejo Antipatrón: “Too Much Architecture” (Demasiada Arquitectura)

  1. Luis dijo:

     
    ONE SECOND IS ENOUGHT…PARA SABER QUE HASTA EL NEO…Y EL MAS VIEJO OLD….
    COINCIDEN SIEMPRE EN UN PUNTO…  
    INTERSECCION…O ESENCIA:
    Lo mas sencillo…si funciona…
    mejor.
    eso es lo mas cercano a la perfeccion informatica…
    obtener el maximo rendimiento…
    gastando el minimo esfuerzo.
     
    sin encender el sistema…por muy complejo y perfecto que sea…
    no arrancara.
     
    y las cosas mas complejas y bellas….
    siempre estan..en la ecuacion mas pequeña.
    esa que dice el viejo dicho…
     x+y=z
     
    pero lo EFECTIVO. Y SUPERIOR..
    ES LO QUE A CADA UNO LE FUNCIONA…
    YA YA SABES….
    A UNOS LES VA BIEN UN SOFTWUARE
    Y A OTROS LES VA MEJOR OTRO.
     
    EL CASO..ES CONSEGUIR LO ELEGIDO.
    EL SISTEMA…ES LO MISMO.
     
    USATE EL QUE NECESITES…
    QUE LO IMPORTANTE..
    AL FINAL….
    ES QUE TE SALGA BIEN.
     
    NO EL TIEMPO O EL RECORD DE VELOCIDAD.
     
    A MI EL QUE ME FUNCIONA ES EL PROGRAMA BASIC…
    Y CUANDO ME FALLA TODO…
     
    ARREGLO PRONTO..
    REINICIAR…
    Y LISTO.
     
    O SI TE FALLA UN MODO ES PECADO PASARTE AL OTRO?
    NUNCA SE PIERDE NADA.
    QUE CADA MAÑANA SALE EL SOL DE NUEVO.
    Y SE COMIENZA DE CERO.
    CON EL SOFTWARE ..
    IGUAL..
     
    TE BLOQUEO LA MAQUINA?
    APAGAS…Y REINICIAS CON OTRO MAS SENCILLITO.
    SEGURO QUE NO TE FALLA .
    ¿PQ?
    PQ YA LO TIENES BIEN CONOCIDO.
    Y TE SABES TAMBIEN SU RENDIMIENTO…
    QUE HASTA TE SABES DONDE FALLA…
    ASI…NO HAY PERDIDA.
     
     
    JAMAS.
    LO OLVIDEMOS.
    PARA USAR EL MAS RENUEVO Y COMPLEJO SISTEMA DEL MUNDO….
     
    LO PRIMERO..
    INSPIRAR,….EXPIRAR…
    RETOMAR AIRE..
    UN TE BIEN CALENTITO..
    O FRIO..DA IGUAL..
    YA ALE..
    A PROGRAMAR.
    PQ SIN LO BASICO…(respirar)…
    DE QUE SIRVE EL CONOCIMIENTO COMPLEJO?
    PERO…NUNCA ES TARDE…
    SI LA RISA…ES BUENA…
    Y SANA.
     
    ¿O ERA LA PIZZA? YA NO RECUERDO,…NI QUE ME PASO AYER…;-)))

  2. Claudio dijo:

     
    Vale compa, será alcance de nombre el mío??🙂
     
    Si comparto plenamente tu punto de vista, solo que aveces me cuesta bajar el artista que llevo dentro🙂, en todo caso es entretenido para mi ver como se pueden hacer mejor las cosas, por lo que seguiré obsesionado (fuera de horario laboral obvio) y por ende molestandote por msn🙂
     

Responder

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