Layers vs. Tiers: la Parábola de Shemp y Curly

 En  Arquitectura de Software hay tríos famosos, similares pero no idénticos, que erróneamente se los trata como uno solo. Me refiero concretamente a
  • Arquitectura en 3 capas (3-layered architecture)
  • Arquitectura en 3 partes (3-tier architecture)
  • Y en menor medida, el patrón de arquitectura Modelo-Vista-Controlador (Model-View-Controller architecture pattern)

Y admitidamente, parecidos cierto que son. Pero iguales iguales no. Veamos entonces las diferencias de cada uno de ellos

 

Arquitectura en 3 capas (layers)

En este tipo de arquitectura el reparto de responsabilidades es, en primera instancia, lógico. Y aunque posiblemente también sea físico, eso no es mandatorio. Las tres capas, son las archiconocidas

  • Presentación, que recibe eventos del usuario a través de la interfaz presentada (de ahí el nombre), y también formatea los resultados a desplegar (digo desplegar para no repetir presentar… de ahí el nombre de nuevo)
  • Negocio, o también Lógica de Dominio, el dominio del problema de negocio por el cual tuvimos que hacer esta aplicación
  • Acceso a Datos, mal llamada Datos a secas como si los datos vivieran en esta capa. En esta capa simplemente hay lógica que lleva a trae información entre la capa de negocio y los repositorios o sistemas externos donde los datos se almacenan. Acá tenemos conectores, pools de conexiones, lógica de paginado, cachés, y seguramente también aquí resolveremos el desajuste por impedancia entre objetos de dominio y registros de las base de datos

Las motivaciones para aplicar este estilo arquitectónico se suelen fundamentar en Mantenibilidad y Reusabilidad. Mantenibilidad porque, al emplearse las APIs en una forma cohesiva: las APIs de interfaz de usuario en la capa de presentación, las de manipulación de XML y bases de datos en la de acceso a datos, etc, esto permite dividir mejor los equipos de trabajo según dominio de dichas APIs. Y Reusabilidad (si el día de mañana queremos cambiar, por ejemplo, de repositorio de datos, seguramente el impacto se concentra en la capa de acceso a datos pero no en las otras dos)
Sin embargo, me atrevería a decir que si nos damos una recorrida y preguntamos a los que deciden optar por arquitectura en tres capas, por qué lo hacen, varios simplemente responderán "qué sé yo… supongo que porque ahora los libros hablan de hacerlas así, no?"

Ahora voy a decir esto y me van a querer saltar a la yugular varios, pero lo digo igual

"Una aplicación stand-alone perfectamente se puede regir por el modelo arquitectónico de las 3 capas Presentación, Negocio y Acceso a Datos"

(Diego Dagum, arquitecto de software, siglo XXI dC)

No me peguen, soy Giordano! Dije stand-alone y hasta los cinco Rocky de Stallone me querían pegar. Pero sí, insisto en que la división en capas es una división lógica a la hora de codificar las clases de la aplicación, para abaratar sus costos de desarrollo y su posterior mantenimiento. Lo que pasa es que todo este momento en que estuve hablando de "tres capas", seguramente estuviste pensando que me refería al estilo de arquitectura que sigue ahora

 

Arquitectura en 3 partes (tiers)

Acá sí estamos hablando de una separación física en procesos, es decir, la ejecución está distribuida. Así, las partes son

  • Cliente o Front-End, que engloba la infraestructura de hardware y software donde se ejecuta la interfaz de usuario. También se suele referir a ellos como Canales (recordar este dato)
  • Middleware, capaz de recibir a través de la red, y mediante uno o varios protocolos de transporte (HTTP, TCP, etc), uno o varios protocolos de mensajes (XML, SOAP, propietarios, etc) requerimientos desde los distintos canales, habilitandose así el concepto de Arquitectura Multicanal (clap clap clap!! fiiiii fiiiii fiuuuu!!! clap clap clap clap!!!)
  • Back-End, normalmente una base de datos, aunque definitivamente puede ser otro proceso, incluso mucho más complejo que nuestra aplicación entera. Por ejemplo, un sistema mainframe con módulos de negocio madurados durante décadas. En ese caso nuestra aplicación es apenas si un habilitador de canales otros que las terminales bobas (dummy terminals, IBM-3270 por ejemplo). Canales móviles con hardware diferente (notebooks WiFi, celulares, etc) y procesos diferentes (aplicaciones de escritorio, aplicaciones embebidas, aplicaciones web, etc)
    Si el back end es una base de datos, es la base de datos en sí, no la capa de acceso a datos del estilo de arquitectura anterior

Normalmente las motivaciones que llevan a aplicar este tipo de arquitectura tienen que ver con Escalabilidad, Seguridad y Tolerancia a Fallos. Definitivamente también este tipo de arquitectura habilita reuso, ahora a nivel de procesos. Y me la juego ahora con mi segundo postulado

"Una aplicación distribuida según el modelo de 3 partes Front-End, Middleware y Back-End, puede no tener una clara división lógica en Presentación, Negocio y Acceso a Datos"

(del mismo autor)

A ver, a esta altura creo que ya me vas pescando la idea y no me vas a querer atacar ni nada por el estilo. Pensemos en una aplicación web. El cliente en este caso es el navegador (browser), el middleware un servidor web, y el back-end una base de datos. El servidor web recibe requerimientos HTTP, y los satisface accediendo a la base de datos
La capa de presentación está resuelta parte en el navegador (DHTML: HTML, CSS, JavaScript), parte en los PHP, ASP, ASP.NET, JSP, etc (de las poquitas opciones que existen para desarrollar aplicaciones web)
Levante la mano quién alguna vez no terminó codificando en la página web -consciente o inconscientemente- toda la lógica de acceso a datos? (Dale, salí con las manos en alto que te descubrieron… seh seh seh, lo hiciste sólo para probar rápido pero después lo ibas a emprolijar, y como habían otras urgencias y eso en definitiva funcaba, lo dejaste así no más… Quedate tranquilo que no sos el único. Digo: no sos el único que dice que fue por eso. Andáaaaaaaa…)

Tercer y último postulado

"Una aplicación puede tener, simultáneamente, Arquitectura en n capas y en m partes, sean n y m igual a 3 o no"

(otra vez yo, la tercera es la vencida)

A ver, no es uno o el otro. Es eventualmente uno indistintamente de la presencia o no del otro. En el ejemplo de la aplicación web que daba más arriba podríamos tener

  • La capa de presentación, parte en el navegador cliente (lógica en JavaScript), parte en el middleware servidor (páginas Velocity, ASP.NET, JSP, etc)
  • La capa de negocio pueden ser clases simples (los POJOs de Java o sus equivalentes POCOs de .NET -la C es por CLR, la máquina virtual de .NET-). O bien EJBs, Serviced Components. Esta capa, en este ejemplo de aplicación web, se ejecuta en el mismo middleware. Sin embargo y por cuestiones de performance, parte de la lógica de negocio se puede replicar otras partes (tiers). Un ejemplo típico: el front-end web valida en JavaScript que la forma de pago no quede en blanco porque el negocio dicta que sí o sí alguna forma de pago hay que elegir, y no queremos pegarnos un pique hasta el servidor para descubrir que un campo de ingreso obligado quedó sin llenar. Te pongo otro ejemplo más peludo: la validación JavaScript calcula la edad según la fecha de nacimiento, y si es menor que 18 años no le permite continuar la transacción porque el negocio dice que para hacer esa transacción hay que ser mayor a 18 años (de nuevo, si bien el middleware tiene esa validación adentro, no queremos pegarnos un pique hasta allí para mejorar la experiencia de usuario). Si bien la parte del león de la lógica de negocio va a estar en el middleware, un poquitín de redundancia en el front-end que evite viajes innecesarios va a mantener el buen clima laboral con los usuarios (para muestra, acordate la vez aquella que fuiste a hacer una compra por internet, cargaste todos los datos, incluyendo la tarjeta de crédito, dirección, todo; los datos viajaron al servidor -sí, incluyendo la tarjeta de crédito, dirección, todo- y te los devolvieron rebotados porque decían que el dígito verificador del documento era inválido. Grrrrr!!!)
    Y si la queremos complicar un cachito más, podría haber un poco de lógica de negocio en procedimientos almacenados en la base de datos. Para algunos hacer eso es pecado mortal. Yo no hago juicios de valor a priori. Dependiendo del caso puede estar muy mal, o bien puede ser lo menos malo, como en los ejemplos que veíamos del navegador
    Esto que voy a contar puede sonar inverosímil, pero yo participé de un proyecto donde la lógica de negocio estaba en el front-end y en el back-end, pero no en el middleware. Los que conozcan el sistema ALTAIR (back-end disponible en mainframe) y su front-end conocido como "Terminal Financiero Corporativo" podrán dar fé de que no miento. Esta situación de tener la lógica de negocio principalmente en el back-end es típico en corporaciones que comenzaron por el mainframe, y fueron incorporando la arquitectura multicanal a posteriori
  • La capa de acceso a datos, siempre en el ejemplo de la aplicación web, viviría en el middleware. NO EN LA BASE DE DATOS. Y de nuevo puede haber algún que otro engendrito: el navegador cliente puede estar ejecutando accesos directos a datos a través de algún APPLET (no, si seguro que eso nunca se vio. Tenés razón, disculpame)

Como último comentario, atención si vamos a considerar que 3-capas y 3-partes son más o menos lo mismo. Cruzar de una capa a otra puede alcanzar con una simple llamada a un método, todo dentro de un mismo proceso de ejecución. Cruzar de una parte a otra definitivamente es algo que no vamos a lograr con una simple llamada a un método. Por lo menos, APIs de orden superior como .NET Remoting o Java RMI, sino Servicios Web va a ser necesario. Ojo al piojo y a leer bien la letra pequeña del contrato

 

Modelo – Vista – Controlador (MVC)

Este patrón, aunque en menor medida, también a veces es confundido con conceptos "Arquitectura en 3 capas" o "3 partes". Hago mi mea culpa: yo lo confundía con "3 capas". La realidad es que está asociado a 3 capas, podríamos decir que suele estar presente allí donde está 3 capas, pero es más bien una distribución fina de la secuencia de ejecución entre que se produce un evento en la capa de presentación y este es atendido en forma completa. Las partes intervinientes son

  • Vista, el componente que recibió el estímulo (un botón en un formulario, un check box, etc) y generó un evento que puede involucrar el estado de los otros controles del formulario. La Vista pertenece claramente a la capa de presentación. Respecto de la arquitectura en 3 partes, la Vista está enteramente en el cliente y suele estar presente en parte del middleware
  • Modelo, componente asociado a entidades del dominio (los típicos que siempre pongo como ejemplo: el cliente, la factura, sus ítems, etc). No los procesos de negocio pero sí las entidades. Respecto de la arquitectura en 3 capas, entonces, el modelo incluye parte de la capa de negocio (entidades, no procesos) y toda la capa de acceso a datos. Respecto de la arquitectura en 3 partes, el Modelo se despliega (deployment) sobre el back-end entero, y también parte en el middleware (la parte que respecta a las entidades de negocio y la capa de acceso a datos)
  • Controlador, el componente que falta: el que se asocia a los procesos de negocio (el Modelo sólo se intersecta con las entidades de negocio). El Controlador recibe el evento que la Vista generó y moviliza procesos del negocio que terminan cambiando el estado en el Modelo. Estos procesos de negocio suelen estar alineados a los casos de uso de la aplicación. Respecto de la arquitectura en 3 capas, el Controlador está mayormente en la capa de negocio aunque puede tener una participación menor en la capa de presentación (según cada canal cliente, la pieza que recibe el evento que genera la Vista). Respecto de las 3 partes, el controlador suele estar mayormente en el middleware aunque en menor tiene cierta presencia en el front-end

 

Conclusión

Este post quizás te pueda parecer muy teórico. Como que da mucha vuelta sobre conceptos que, bien o mal entendidos, no hacen mayormente al fondo de la cuestión. Sin embargo creéme que todo esto que te conté, y cómo relacioné las distintas vistas arquitectónicas fue consecuencia de lo que la práctica me dejó entender. Lo que he llegado a practicar hasta ahora porque sin duda que, cuanto más lo siga practicando, mejor lo voy a seguir entendiendo

Las distintas vistas no son antagónicas, no son alternativas que se excluyen mutuamente. Son diferentes maneras de resolver aspectos diversos en sistemas empresariales. Se pueden tomar todas o algunas de las tres en la medida en que se entiende el valor que aporta cada una (y espero que este post te haya ayudado a ver el valor concreto que cada perspectiva te entrega)

Para finalizar, en Wikipedia todavía creen que 3 capas y 3 partes son lo mismo. Fijate si no en http://en.wikipedia.org/wiki/Three_tier

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

3 respuestas a Layers vs. Tiers: la Parábola de Shemp y Curly

  1. Jose Mariano dijo:

    Bien dicho/escrito. Ojala muchos gerentes / responsables de desarrollo tuvieran las ideas tan claras. O por lo menos, se molestaran en que alguien se lo explique.🙂

  2. paulo dijo:

    Como siempre un muy esclarecedor artículo Diego, yo la verdad por falta de tiempo no he podido implementar algo de forma completa con MVC, pero si he podido experimentar con Castle Project, este framework en algunas cosas está muy verde, pero como para comenzar esta bien, espero en el futuro con algo más de tiempo dedicarme a implementar algo aunque sea chiquito con MVC, como para ampliar un poco el horizonte.

  3. Diego dijo:

    Genial, Paulo. Uno de los creadores de Castle está por publicar un artículo en http://msdn.microsoft.com/architecture sobre Inversion of Control (IoC), usando Castle como ejemplo práctico. Lo estuve revisando y se ve bastante bunito

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