Tag Archive for architecture

El espejismo de la separacion por capas, toma dos

app_3Hace varios meses escribí un blog post (que quise luego transformar en serie y como cosa rara en mi por tiempo nunca llegue a continuarlo) en el que indicaba mi falta de amor a la palabra “capas”….

El concepto de “capas” o “layers” me parece desde unos años para acá tan ortodoxo, viejo, fuera de lugar, obsoleto, mal aplicado, afuera totalmente de contexto. La idea de capas tenía mucho sentido hace décadas atrás (tampoco décadas pero fue hace tiempo) cuando los programadores cavernícolas (en los cuales me incluyo yo picando piedra) teníamos que depender fuertemente en la base de datos, hacíamos las consultas en plano SQL, insertábamos directamente en plano SQL, y si mi DB me la movían literalmente movían mi aplicación.

Esto tenía todo el sentido del mundo en nuestras aplicaciones no tan complejas y sin mucha orientación lógica que hacíamos en aplicaciones desktops o web, o sea, en vez de escribir cientos de líneas SQL esparcidas por doquier en nuestro código de php (por ejemplo), mejor lo abstraíamos todo en un solo lugar donde estaba guardadito nuestro SQL, ahí en su cajita, donde nadie lo tocaba y si alguien lo tocaba era una vez (como que si tocar una consulta no involucrara cambiar algo… silly us). Esto se llevó un paso adelante y en vez de poner consultas como SELECT * FROM [tabla] mejor usamos SP’s, así que cambiamos eso por EXEC usp_MiConsulta, esto dio origen a otro problema, pero vamos a ir al grano primero.

En ese tiempo la gente comenzó a percatarse de algo, si abstraigo las consultas a la DB, luego las llamadas a la DB en otro lado, puedo entonces poner la “lógica” de negocio en otro lado y sobre ella hacer la UI. Esto tenía mucho sentido y asi nació el concepto de “layers”… Tiene sentido, tenía sentido en ese tiempo, teníamos aplicaciones con el “típico” color aqua y un par de botones con iconos de puertas y equis tachadas en primera plana, con una grid para mostrar facturas y un botón donde agregábamos una factura nueva (generalmente con el icono más o con un lapicito que aun no entiendo porque aparecía ahí).

Luego vino la moda SOA (que pareciera nunca acabar) y dijeron, va, ahora en vez de hablar directamente la lógica con la data, vamos a tener alguien en el medio que expone esa data por un servicio. Entonces hablamos de SOA… como ya no eran 3 capas si no 4 o más renombramos el modelo a n-Capas…. y aun me perfora el oído escucharlo….

He visto degeneraciones de este modelo, un “buen” ejemplo son las aplicaciones ejemplo de MS, donde abstraen todo a servicios que al final el mismo objeto desde el comienzo al fin es el mismo. Es increíble pero he visto a desarrolladores veteranos que aun insisten en usar su versión de servicio para exponer todo, pero esa es otra historia…

Nuevamente recalco, eso tenía sentido *en ese tiempo* los ORM’s o no existían o eran sumamente rudimentarios, la mayoría de db devs que habían estaban aún acostumbrados a hacer _todo_ en la DB (no, en serio, una vez vi una app que hasta el proceso de pago de paypal era hecho internamente en la DB), tenía sentido cuando tu aplicacion era la tipica aplicación con botones grandes y background aqua… Tenía sentido cuando decías que abstraías el acceso a datos en una clase que por lo general comenzaba por una pequeña clase con un par de métodos y terminaba como cientos… porque tal cosa como reutilizar el acceso a datos se tornó un santo grial.

Eso no tiene sentido HOY, cuando nuestros objetos son (o deberían ser) ricos en comportamiento, cuando modelamos en base a lo que _va a pasar y hacer nuestra aplicación_ no en cuanto a la data que va a contener la base de datos (puntos extras para el que comprenda la diferencia entre ambos approaches en la oración anterior). No tiene sentido hoy que nuestra “lógica de negocio” realmente puede ser embebida en el objeto del dominio o de negocio, donde hacemos una distinción entre lógica de negocio (o reglas del negocio) y lógica de presentación (que como dice el nombre solamente afecta la vista). No tiene sentido cuando no interactuamos contra solo una base de datos si no contra base de datos, archivos, servicios (y generalmente varios). No tiene sentido porque no le veo ni cara ni cuerpo a tener un ORM (por simple que sea) y envolver las mismas entidades y exponerlas mediante otras entidades que contienen los mismos símbolos, no tiene sentido hablar de capa de acceso a datos ya que tus Objetos de ORM no solamente viven ahí y pueden contener la lógica que tanto necesitas en la “siguiente” capa. No tiene sentido en un mundo donde el programador está acostumbrado (y hasta espera) que la consulta se genere automáticamente mediante Linq, no tiene sentido en un mundo donde ya no escribimos SQL a mano.

¿No te gusta un ORM porque tiene demasiada carga para lo que necesitas? bueno usa un MicroORM… y aun así sigues sin hablar de capa de datos, tal cosa ya no existe. Ni siquiera Microsoft con sus prácticas habla de layers…. Vamos, ahora ni en PHP puedes tener el coraje de decir que tienes que escribir SQL a mano, porque entonces abstraer todo en una “capa”, ¿quieren producir algo de misterio? Traten de preguntarle a un programador de Rails donde está su capa de datos, no existe, ¿porque?… No es necesaria tal separación.

Ahora, lo que si debes distinguir es el concepto de Tiers, una aplicación si va a tener varios Tiers, la base de datos (a menos que sea embebida) vivirá y es por definición un tier, ¿expones servicios? bueno, otro tier mas…. Un tier es una separación física de la cual no puedes deshacerte, una layer es una separación lógica que realmente no tiene sentido en un mundo ágil donde no usamos 6 meses “diseñando” la aplicación.

Algún día ordenare todos mis pensamientos y terminare escribiendo un poco más sobre porque el concepto de layer sigue siendo obsoleto, por lo menos para mí.

NOTA: Este fue un largo correo en la lista de Alt.Net hispano que termino siendo tan largo que llego a ocupar un blog post.

Caching and shared data

Today I had an interesting conversation with a friend of mine in the office, we argue about the definition of cache. For him a cache should guarantee the existence of an item in the cache. That means that once your application set the item in the cache the cache should guarantee that item will be there for another request. I don’t agree with that definition at all, I mean, if we look in Wikipedia for the word cache we found words like cache miss and cache hit and read that the main purpose of a cache is to speed up future request for the same data. When I told him this he gently answered back: no, that’s the definition of cache for memcache, not for a distributed cache engine. I mean, I’ve used memcache since the first released version from Danga (long time ago), but the only thing memcache did was to expand the definition of a local cache to distributed cache, not creating a new definition for cache.

Well, he mentions some samples using a shopping cart and Amazon and then I realized he was confusing the cache definition with the distributed key/value database definition. Funny enough I did a simple search in Google and I found this old article from MSDN Magazine http://msdn.microsoft.com/en-us/magazine/dd861287.aspx when as an example the author uses Velocity (in that time a cache engine from Microsoft) as a distributed cache for a shopping cart, clever, I should admit, but sadly the author was wrong, not in his approach but in his definition. I found another article (again from MSDN Magazine) where they mention Velocity as a good alternative for a distributed shopping cart (sounds familiar).

As far as I know Velocity is a distributed cache (as memcache) but with support for fancy stuff like transactions, versioning and notifications (very handy in a lot of situations). I know, maybe they look as the same but there is a big difference between a distributed key value database and a distributed cache. A good definition of both is found here http://wiki.toadforcloud.com/index.php/Survey_distributed_databases#Distributed_Memory_Caches :

Distributed caches prompted developers to view distributed databases in a new way, by inverting the concept of a distributed cache. Instead of providing a caching layer to an existing data store, some new distributed databases treat the distributed hash table as the database, backed by a persistent store. Such implementations do not require a backend SQL database but instead provide their own persistence. This gives rise to the key/value database.

Yes, a distributed key value database looks a lot like a distributed cache, but they are used as primary data store not just to make your request faster or as a hit or miss cache mechanism. If you put persistence medium to a distributed cache (like memcached) then you create a distributed key value database (as memcachedb)

Amazon uses this trick and they developed their own distributed key value database, Dynamo, which has its own cache engine to speed up the request for common and heavily used items (including their shopping cart and preference storage).Something very interesting with Dynamo is the fact that even they cannot guarantee the existence of an item in the storage mainly because the distributed nature of the engine, it will replicate when the engine has time to do it.

Is Microsoft Velocity a distributed cache or a distributed key value database? From the MSDN definition I will tell it is a distributed memory cache engine, but from the samples and usage we should guess it is a distributed key value database. Who knows…. (if somebody from the Velocity development team read this blog please enlighten me!)

Mapeo, DTO’s y ViewModels en ASP.NET MVC

Los DTO’s –Data Transfer Objects- (algunos los llaman ViewModels/EditModels según el uso para el que existan) nacen por una razón específica: El modelo de lo que ves en la vista no representa directamente tu modelo de negocio. Mi ejemplo tradicional siempre ha sido el formulario de Login/Usuario/Contraseña.

Con el pasar del tiempo mi postura hacia este tema ha sido variada y se ha hecho bastante flexible. Por ejemplo, si tu modelo y tu aplicación es lo suficientemente sencilla y sabes que luego de eso jamás se va a modificar ni cambiar entonces es suficientemente fácil quedarte con el modelo y permearlo hacia la vista y vice versa, eso es precisamente lo que hace la generación Rails/Django/Whatever y lo que solemos hacer con MonoRail y Castle ActiveRecord, ¿la razón? simple, el modelo es sencillo, el dominio es sencillo y no es un proyecto complicado.

Para bien o para mal, en el entorno en que muchos se mueven no se ven cosas tan estáticas y los modelos y reglas de negocio son mucho más complejos siendo generalmente nuestros modelos de negocio , de hecho, si trasladamos eso a una visión de diseño orientado a servicio las cosas cambian aún más (ni hablemos de una "DDD shop"), lugares donde vemos que esta regla se revienta es en sistemas empresariales al estilo CRM/ERP o las siglas que sean…

En el contexto de una aplicación MVC se sobreentiende que el viewmodel es un concern de la vista, por lo tanto esta restringido a los conceptos de presentación. Recordemos también que un controller también es un concern de la vista (si, para aquellos que siguen creyendo que el controlador es la lógica de negocio, les vuelvo a romper el corazón en este momento), un buen lugar para que vivan los viewmodels es dentro de la aplicación MVC, surge el problema entonces, ¿cómo mapeo de un modelo de negocio al modelo de la vista?, bueno, les presento un par de ideas.

Usando el mapper como un servicio

Podemos usar un mapper automático como nuestro intermediario en el controlador entre el modelo de dominio y el viewmodel y de esta manera separar e injectar el mapper en el controlador

public class OrdersController : BaseController {
    readonly IOrdersRepository _ordersRepository;
    readonly IOrdersMapper _mapper;

    public OrdersController(IOrdersRepository ordersRepository, IOrdersMapper mapper) {
        _ordersRepository = ordersRepository;
        _mapper = mapper;
    }

    public ViewResult List() {
        var orders = _ordersRepository.FindAll();
        View(_mapper.Map(orders));
    }
}

Usando un Application Service

En este caso el Application Service se encarga de tomar las decisiones y luego retornar hacia el controlador los resultados, en este caso el controlador no sabe nada de la entidad original del dominio ni sobre el repositorio original, este es sumamente flexible cuando nuestro dominio original suele cambiar drásticamente o tomar decisiones muy complejas para delegárselas al controlador. En este caso es posible que a su vez el mapper sea inyectado y sea una dependencia del servicio. De hecho, podría ser que el servicio no use un mapper para nada, si no que simplemente arme el resultado usando varias uniones de otros resultados sobre la marcha (usando LINQ por ejemplo).

public interface IOrdersService {
    IEnumerable<OrderView> GetOrders();
}

public class OrdersController : BaseController {
    readonly IOrdersService _orderService;
    public OrdersController(IOrdersService orderService) {
        _orderService =  orderService;
    }

    public ViewResult List() {
        var orders = orderService.GetOrders();
        View(orders);
    }
}

Delegando el mapeo a un ModelBinder y ActionFilter

Debo admitir que aunque este es uno de mis resultados o formas favoritas de hacerlo en una aplicación MVC, lo siento a mi criterio demasiado “opionated” (entiéndase, fumado o cargado). En este escenario no es responsabilidad directa ni de un mapper ni de un servicio el retornar los resultados esperados, si no de un Model Binder junto con un ActionFilter en ASP.NET MVC. El controlador luciría algo así:

public class OrdersController : BaseController {
    readonly IOrdersRepository _ordersRepository;

    public OrdersController(IOrdersRepository ordersRepository) {
        _ordersRepository = ordersRepository;
    }

    [Automap(typeof(Order), typeof(OrderView)]
    public ViewResult List() {
        var orders = _ordersRepository.FindAll();
        View(orders);
    }
}

Este último caso es bastante flexible pero involucra que conozcamos bien que es un Model Binder y un ActionFilter, claro, nada que un par de minutos al frente de Visual Studio no pueda solucionar :)

Debo admitir que el caso de usar un Application Service me parece más natural si nuestra aplicación es simplemente un front end a una infraestructura orientada más hacia servicios que hacia un modelo directo de consumo (entiéndase, cosas como un ERP/CRM que probablemente usemos sus interfaces por otro lado y no solamente en nuestra aplicación de “CRUD”) y es mucho más flexible para casos en que necesitamos aislar completamente la “orquestración” del resultado del “despliegue” del resultado, suena extraño al principio pero se me ocurren bastantes casos donde esto se puede presentar.

Debo hacer notar que estas observaciones son meramente orientadas al contexto de una aplicación en ASP.NET MVC y no directamente se pueden trasladar a una aplicación o a un Tier en WCF, en este caso lo único que debemos compartir entre servicios es su esquema, no sus objetos.

Como siempre, espero sus comentarios o críticas al respecto, siempre son bienvenidas, recuerden, estamos en este barco del aprendizaje todos juntos como marineros.

¡Saludos!

UPDATE: Mi amigo José Romaniello me comenta del uso de una interface estilo IMapper en vez de una especializada para mapeo (como lo es IOrdersMapper), este patrón de uso lo considero igual al uso de una especializada, por lo tanto no la incluyo.

UPDATE 2: No incluyo implementaciones definidas de como crear estos mappers, para esto se puede hacer de forma directa o usando una herramienta de mapeo de clases como Automapper, pero eso lo dejo para otro post futuro.

El espejismo de la separación por “capas”

Algo que comúnmente escucho en el círculo de desarrolladores (especialmente de .Net) es la frase “esto va en la capa de datos” o un “esta regla de negocio esta en la capa de negocio” y hasta un “mira, esta hecho pero aún no están bien separadas las capas”.

Esta palabrita, “capas”, es una de esas buzzwords de arquitectura microsoftica que nos han quedado grabadas en el cerebro, y que debido a que ha sido usada por tanto tiempo, ya la decimos instintivamente y hasta llegamos a creer que si un developer no habla en “capas” no es de respetar.

Comencemos a analizar lo que nos venden cuando hablamos de “capas”. Por lo general la terminología de capas se aplica a la típica arquitectura jerárquica de tres niveles, denotando responsabilidades diferentes y niveles de acceso variables en cada una de ellas, siendo la más conocida de todas la arquitectura de “tres capas”: Data Layer, Business Layer, Presentation Layer.

IC351011

Personalmente creo que este tipo de “ensamblaje” cobra bastante sentido si desarrollabas hace más de 5 años atrás, es decir, los ORM eran “escasamente” conocidos, los DataSet’s reinaban en el mundo de Ado.Net, los webservices no eran más que una extensión de la ASP.NET framework, el desarrollo en Windows y Web se limitaba en su gran extensión a arrastrar y soltar controles sobre un lienzo y crear un test era cosa de escribir en un papel y decirle a alguien que “probara la aplicación”… ¡ahhh, épocas lejanas aquellas! (bueno, creo que mucho de lo que menciono aquí aún esta presente en la lucha hasta el sol de hoy, pero ese es otro tema).

Actualmente muchos siguen desarrollando de esa manera, algunos han llevado esto aún más lejos y se han atrevido a hablar de arquitecturas de dos capas y hasta de n-capas… Hay libros, guías (como esta) y muchísimos posts en internet conversando de como usar Nhibernate o la Entity Framework en un entorno de n capas, como concurso, mientras más capas tenga tu aplicación, mayor será tu “mérito”.

He llegado a entender a aquellos defensores de las arquitecturas por capas, y en base a ello he formulado un conjunto de opciones por las cuales aún hablamos acerca de “capas”

  • Han tanta lógica en la base de datos que hay que distinguir las reglas embebidas en la base de datos de aquellas embebidas en cualquier otro lugar, por lo tanto, hablamos de las reglas de la “capa de datos”
  • La base de datos es mi salvador, por lo tanto debo separarla y distinguirla del resto de código “mortal” de la aplicación
  • La presentación de los datos es tan compleja, que bueno, el codebehind es inmenso y merece tener su propia “capa” debido al tamaño
  • Sigo usando DataSets o procedimientos almacenados que son leídos por DataReaders y al final debo manipularlos para sacar los datos de una factura, consumidor o lo que sea, por lo tanto tengo que distinguir esas responsabilidades en su propia “capsula”
  • No sé que rayos es un Tier y a falta de mejor palabra le llamo Layer

Como sea, pronto conversaremos de porqué el concepto de “capa” está un poco pasado de moda y las opciones que tenemos a la mano para reemplazar la ya vieja arquitectura por capas por una mucho más holística basada en modelos de comportamiento y responsabilidades modeladas a base del dominio y no por imaginación de un arquitecto.

Como siempre, estoy abierto a comentarios en la zona de comentarios, twitter, mail o cualquier otro medio por el cual esporádicamente puedan encontrarme.

¡Hasta la próxima!

No uses la base de datos como tu modelo

Bueno no se si realmente el título del post esta relacionado con el contenido, en realidad este post debería llamarse: “Mantenibilidad vs. el Point and Click Developer”. Una de las cosas con las que me enfrento día a día por mi apoyo a NHibernate es la típica pregunta: “Pero NHibernate no tiene un ‘arrastrar la tabla y soltar sobre el designer’ como DbLinq”

Esta pregunta realmente es algo compleja de responder, usualmente respondo algo como: “Si basas tu dominio en tu esquema de base de datos entonces simplemente quedas atado a tu esquema de datos”. Claro, siempre me regresan una increíble cantidad de respuestas y comentarios indicándome que “No hay tiempo” algo como “Modelar un dominio?”

En este caso en específico quiero hablar de “dominio” como las pocas o muchas reglas de negocio que hay o existen dentro de una aplicación. Mi fanatismo por NHibernate se basa no en que es “la última moda”, sino en la flexibilidad que tiene para no atarme a la base de datos, sino “adaptarme” a ella. Verán, esto lo explico de una manera bien sencilla: Con un arrastrar y soltar de la tabla de la base de datos a la aplicación y que me “autogenere” las entidades estoy atado al esquema de la base de datos, NO a las reglas de negocio existentes; con diseñar mis entidades de dominio (objetos que se aplicarían en las reglas de negocio) y luego atarlos a la base de datos, mis reglas de negocio, mis entidades de dominio, mi funcionalidad NO esta atado a cambios en el esquema, y no tendría porqué cambiar mi esquema de datos al cambiar reglas de datos. Ante esto alguien me respondió una vez: “Pero la mayoría de veces ya tienes la base de datos, no tienes ni siquiera permiso para modificarla”, pues respondo que en este caso el tener un buen ORM te facilita las cosas, ya que tus cambios en el negocio no se reflejan en tu contenedor de datos.

Algunos pueden abogar: “pero no hay tiempo para entregar una aplicación a tiempo si nos ponemos a ver ese tipo de cosas”, pues probablemente no si te la piden de hoy para mañana pero el tradeoff creo que vale la pena. Hace un tiempo vivía bajo el espejismo de “La entrega es lo importante, hay que hacerlo a toda costa y si hay que sacrificar que el codigo es un desorden vale la pena para la entrega”, pero después de varios años y proyectos he aprendido gran parte de la lección, lo importante al final es la mantenibilidad ya que no importa CUANTO hemos trabajado en una aplicación para su entrega, lo ÚNICO inminente es que al cliente se le ocurrirán cambios. Creo que todos hemos escuchado historias como: “Me dijeron que iba a ser temporal esta aplicación y ya lleva años modificándose” o quien no conoce el típico caso de la aplicación de Access que creció y ahora es un eterno martirio modificarla?

Mi último caso que pasé en carne propia sucedió ya hace varios meses: un cliente me pidió una app relativamente sencilla, pedía unos datos, usaba un par más, enviaba un par de correos e interactuaba con una simple app en Silverlight a través de un servicio WCF. Nada complicado en los requerimientos iniciales. Se firmó el contrato y decidí comenzar probando la ASP.NET MVC (en ese tiempo estaba en el CPT5 recuerdo). Aunque no era mi primera vez con una MVC Framework, era mi primera vez con una app Silverlight de ese tipo (sorry, no puedo dar mas detalles :P ), y como los controladores eran suficientemente sencillos y el tiempo de entrega eran simplemente 5 días, decidí saltarme todos mis principios y “trabajas” y hacerlo con DbLinq y una DB sencilla de datos (los datos de la DB eran sumamente simples, un esquema pequeño sin mucho problema). La aplicación se entregó en el tiempo requerido y todo funcionaba rebien…. ¿Que pasó al final? los requerimientos cambiaron, la aplicación no fue tan “temporal” como habian propuesto y las reglas de negocio comenzaron a cambiarse… Al final de todo, una pesadilla de mantenimiento durante los siguientes dos meses…. Morajela:NUNCA usar KISS como una excusa para no hacer bien las cosas.

Si tu aplicación es simple, sencilla y no requiere mucha “ciencia”, esta bien, usa DbLinq, la Entity Framework, NHibernate o lo que quieras usar para conectarte a la base de datos (esta bien, si quieres hasta puedes usar SqlCommands o los horribles DataSets), pero JAMAS dejes que tu base de datos dictamine como debe ser tu aplicación.

Espero sus comentarios al respecto, creo que sobre esto hay mucha tela que cortar.