BeCodeWeek : Día 2

Hoy he tardado casi dos horas en escribir el post del día 1, así que esta noche me he traído el portátil. Quizás no me de tiempo a escribirlo todo, pero sí lo más importante.

Hoy he acabado bastante cansado a pesar de haberme levantado “a mi ritmo”. Bueno, tardé bastante en llegar al taller, pero es que el concepto Metro no se maneja mucho por la zona; tampoco es que yo pusiera mucha atención al concepto Callejear. Así que pasó lo que tenía que pasar.

Miguel Angel estaba terminando de preparar el backlog en el que trabajamos ayer mientras yo escribía el post del día 1, aun así contrastamos un par de dudas sobre cómo enfocar las tareas de la primera historia de usuario. Yo esperaba terminar pronto pero, la verdad, Xavi es bastante ruidoso. Por suerte, mañana estará casi todo el tiempo fuera, así que podremos concentrarnos sin problema. Eso sí, cuando vuelva está claro que tendré que ponerme los cascos. :-P

Después de publicar el post me senté un rato con Xavi para que me ampliara sobre sus planes para dominar el mundo, con unas patatas fritas y una litrona. Eso sí, entre papa y papa: SOAUI y otras lecciones de arquitectura. Además, es evidente que Xavi tiene clarísimas las fuerzas que hacen funcionar un producto y se le ilumina la cara cuando habla de cómo hará funcionar su próximo proyecto.

Después de comer me quedé con Miguel Angel para empezar la primera historia de usuario. Menos mal que él ya había empezado antes de comer porque avanzamos muy poquito. Mi desconocimiento de Javascript, de Mootools y del dominio del problema a resolver hicieron que no avanzaramos mucho. Xavi dice que, además, también influye mi habilidad natural para cuestionarlo todo. (Él lo dice con otras palabras, pero mi ego me impide reproducirlas). :-P

Xavi y Emma nos hicieron llegar tarde a la reunión de . Miguel Angel se ha propuesto recuperar la actividad del grupo. Para ello cuentan con el apoyo de Emma y de Ricardo Borillo. A Ricardo le voy avisando desde ya que le voy a grabar un muy pronto. Tenemos mucho de qué hablar. El grupito que se juntó era una mezcla de “veteranos” y “novatos”. Para mi fue estupendo ver caras nuevas. El final de la reunión terminó con una retrospectiva en la que tomaron varias acciones (con sus respectivos responsables). Entre ellas, Miguel Angel, se encargará de crear un site para el grupo donde poder ir anunciando la siguiente reunión.

Tras la reunión: cena, ducha, blog y a la cama. (No sin antes tener con Emma una conversación sobre SOA mientras revisaba mis viejas entradas en el blog y me instalaba Jasmine para mañana no estar demasiado pez)

 

P.S.

Tengo el teléfono estropeado. Nunca os compréis un HTC Tattoo. Tendré que buscarme un teléfono nuevo. ¿Sugerencias? Igual hago como Xavi y vuelvo a un concepto más básico de teléfono-que-sólo-sirve-para-hablar.

Servicios autónomos

Hace un par de semanas escribía sobre un curso al que asistí impartido por Udi Dahan y recibí varios comentarios que me pedían los ejemplos que usó Udi para explicar su enfoque SOA basado en el diseño de servicios autónomos en vez de en la reutilización de servicios. Hoy he estado tomando café con mi paisano Jose Carlos del Arco, miembro del comité organizador de JSWEB (Jornadas Científico Técnicas en Servicios Web y SOA) y hemos hablado (¡por supuesto!) de todo esto (y sobre más cosas, claro). Así que no me queda otra que rebuscar entre el desorden de mi mesa dónde demonios dejé esas notas y tratar de explicarlas. Por suerte, este fin de semana pasado he recuperado mi antiguo escáner y creo que podré escribir un poco menos. :-)

Recordemos que Udi plantea que nuestros servicios deben ser diseñados para ser autónomos. Esto es, para que colaboren con otros servicios, pero que no estén acoplados a ellos (o que el acoplamiento sea el mínimo posible). Para ello trata de que la mayoría de las colaboraciones se hagan asíncronamente (“fire and forget”) y que los datos no sean compartidos sino que haya siempre una única autoridad certificadora de los datos (sólo un servicio escribe y el resto sólo lee). Para lograr que los cambios en los datos estén disponibles en el resto de servicios propone suscripciones a los eventos de cambio en los datos que cada cuál necesita.

Vamos al ejemplo y lo veremos más claro. Cuidado, es un ejemplo para ilustrar la idea de fondo. No lo toméis al pié de la letra.

Supongamos tres departamentos en una empresa (ventas, almacén y marketing).
Supongamos que trabajamos para el departamento de ventas para implementar una aplicación web que permita comprar nuestros productos desde internet. ¡Qué original! ¿Verdad?

La solución que propondríamos sería implementar la aplicación web como más bonita y usable resulte, pero que componerla teniendo en cuenta nuestra orientación a servicios. Así, el catálogo de productos es “propiedad” del Departamento de Ventas, pero el precio y disponibilidad no. Por tanto, para mostrar esta información que nos es ajena tendremos que realizar peticiones a otros Departamentos, es decir, llamadas a los servicios de marketing (para el precio) y de almacén (para la disponibilidad).



Udi, durante el curso, nos habló de cómo se componían las UIs de sitios como eBay o Amazon. Todas tenían en común que se componían a partir de llamadas a diferentes fuentes. Fijaos que hay partes de la UI que son muy estáticas (o casi), como las categorías de productos. Esa parte de la UI puede ser perfectamente el resultado de una llamada a un servicio. A nuestra aplicación web le viene a dar bastante igual si esta semana hemos empezado a vender “palos de fregona”, simplemente debería ser una nueva categoría y poco más, porque nuestra aplicación sabe vender productos que tenemos en nuestro catálogo.

Pero vayamos un poco más “adentro” de la capa de presentación (o incluso podríamos hablar de las aplicaciones, sin más). Los servicios se diseñarán e implementarán buscando que sean autónomos, es decir, que no requieran de otros para completar sus responsabilidades.

En nuestro ejemplo, el proceso de compra de un producto requerirá de la colaboración con otros servicios. Será necesario conocer el precio de un producto o las promociones o el precio de envío por correo urgente… Pero esto no quiere decir que nos tengamos que quedar esperando a que cada uno de los servicios nos responda.

En la figura 1 vemos cómo se suscribe el servicio de Ventas a los otros dos servicios. Así, obtiene los datos que necesita para operar de manera autónoma.



Paso 1) Ventas se suscribe al valor de los precios que posee el servicio de Marketing
Paso 2) Marketing informa de los precios a Ventas (porque éste no tiene ningún precio anterior)
Paso 3) Ventas se suscribe al valor de disponibilidad (“stock”) de los productos que posee el servicio de Almacén
Paso 4) Almacén informa de las cantidades disponibles en almacén de los productos en el catálogo


Por tanto, nuestra aplicación de Ventas puede mostrar toda la información necesaria para que un usuario inicie la compra de productos. Y dado que estamos suscritos a los cambios que se puedan producir tanto en los precios como en las cantidades disponibles, siempre (con un cierto margen) tendremos la información más actual: que es la única que necesitamos. Ahora veremos qué ocurre durante el proceso de compra.



Paso 1) El usuario (la aplicación) ya tiene toda la información necesaria para realizar el pedido e inicia el proceso de compra llamando al servicio de Ventas.
Paso 2) El servicio de Ventas hace sus comprobaciones, entre las que está el comprobar si hay “stock”, y calcula el total de la factura. Todo esto lo puede hacer porque es autónomo.
Paso 3) El servicio de Ventas informa al servicio de Almacén de que hay un pedido que debe ser servido. Lo hace asíncronamente, es decir, no espera a que el servicio de Almacén haga lo que tenga que hacer. Simplemente se asegura de proporcionarle toda la información necesaria para que se pueda realizar el proceso de empaquetamiento y envío del pedido al cliente.
Paso 4) El servicio de Almacén reduce (en su base de datos) el valor del stock de los productos involucrados en el pedido.
Paso 5) Dado que el servicio de Ventas está suscrito a los cambios de disponibilidad de los productos, recibe un mensaje con estos datos actualizados.

Como véis, el proceso de venta de un producto se puede realizar sin necesidad de esperar la respuesta de ningún otro servicio. Es más, el servicio de Almacén podría estar “apagado” y eso no nos afectaría para nada. El paso 3 se “encola” y el servicio de Almacén ya lo consumirá cuando sea. Por otro lado, si los valores de “stock” se mantienen sin cambios durante mucho tiempo, se planteará la decisión de negocio de qué hacer en esos casos: asumir que hay disponibilidad, que no hay disponibilidad, quedarnos con el último valor conocido…

Lógicamente, hay consideraciones a hacer en el caso de que “no todo vaya como la seda”. Hay que definir operaciones de compensación, por ejemplo. Pero si os fijáis, estaremos hablando realmente de automatizar operaciones que ya (probablemente) se están realizando de manera manual en el negocio actual. Por tanto, estaremos alineando la técnica con el negocio. Y demonios, ¿no es de eso de lo que tendríamos que estar hablando?


SOA no va de reusar

El pasado día 7 asistí a un curso de un día sobre SOA organizado por iMeta e impartido por el reconocido Udi Dahan. Por cierto que fue en las instalaciones de Microsoft en “La Finca”. Uuuuyyy, qué miedooorrr… Bueno, tampoco es para tanto, soy muy Linux y muy Java, pero tampoco soy tan “talibán” como para no “entrar en la boca del lobo”. :-)

Bueno, bromas aparte, la organización de iMeta fue muy buena (el catering estuvo a la altura, je, je) y Udi Dahan es toda una garantía. Además, como Hadi Hariri (de iMeta) me había explicado, el curso no estaba centrado en ninguna tecnología en particular. Yo, por si acaso, advertí de mi “orientación ideológica” en mi presentación. Por cierto, pensé que mi inglés estaba más oxidado, aunque al final de la tarde ya no daba pié con bola… :-(

Pero vamos al tema. Udi Dahan es muy conocido en ambientes SOA (Service Oriented Architecture) y DDD (Domain-Driven Design) porque tiene un enfoque diferente al SOA de otros autores. Durante el curso le pregunté directamente por esto y sobre cómo se encaja con la visión de, por ejemplo, Thomas Erl. Udi me contestó que simplemente no encajan: el enfoque de Erl se centra en reusar, mientras que el de Dahan se centra en la autonomía de los servicios y el principio de única responsabilidad (single responsibility principle). En un correo posterior, Udi me ha aclarado que, según él, Thomas Erl ve los servicios más como construcciones de software, mientras que él los ve más como construcciones de negocio (implementados mediante varias construcciones de software).

No hace mucho leí “Implementing SOA” de Paul C. Brown, y hay muchas más coincidencias con Dahan que con Erl. Y eso que de Erl tengo nada más y nada menos que tres tochacos que voy a tener que rifar, salvo que el último, “SOA Design Patterns” me sirva para algo más que para hacer bulto en la estantería. :-/

Todo esto que resumo en apenas dos frases queda bastante claro a lo largo del curso porque Udi dedica bastante tiempo a explicar que al reusar realmente incrementamos el acoplamiento mientras que lo que realmente buscamos cuando decimos que queremos reusar es reducir el esfuerzo  empleado al desarrollar las aplicaciones para nuestros clientes. Por ello explica que, aunque sea paradójico, aquellas piezas de código en las que empleamos mayor esfuerzo, y que por tanto serían las que más nos interesaría reusar, suelen ser aquellas que son más específicas y que son las más dificiles de reusar puesto que están fuertemente acopladas al negocio que resuelven. Y por otro lado, resulta que nos empeñamos en que todas nuestras aplicaciones compartan componentes y diseños poco acoplados al negocio (es decir, que no aportan valor de negocio por sí mismos) con el objetivo de que sean lo más reutilizables posible. Pero parece que nos olvidamos de que, hagamos lo que hagamos, en algún punto de nuestro código tendremos que acoplarnos al negocio puesto que para eso desarrollamos software: para resolver problemas de negocio.

Udi nos presenta los conocidos cuatro principios de la orientación a servicios (según Microsoft):
  • los servicios son autónomos
  • los límites son explícitos
  • los servicios comparten esquemas y contratos, no clases
  • la compatibilidad de un servicio se determina en base a una política


y se centra en la autonomía de los servicios. Nos explica cómo alcanzar esa autonomía de una manera genuína, llegando hasta el extremo de que cualquier servicio se pueda implementar con el diseño que se quiera y sin la obligación de compartir siquiera la misma base de datos.


- ¡Eh! ¿Qué ha dicho? ¿Qué no se comparte la base de datos?
- ¿Y qué pasa con las restricciones de integridad? ¿Qué hago con mis foreign keys?


Muchos le preguntaron a Udi por esto. Je, je, yo ya sabía por dónde iba él porque esta discusión me la conozco de cuando estaba en Degesys, aunque allí no llegamos a ninguna conclusión (al menos mientras yo estuve). El caso es que la respuesta es bien fácil: las restricciones de integridad en la base de datos sólo sirven para acoplar servicios entre sí. Así que tú verás si quieres estar acoplado o no… :-) Claro, para conseguir esta autonomía hay hacer concesiones:

  • no tenemos un único modelo de datos compartido por todos los servicios
  • no tendremos un estado coherente de los datos al que estamos acostumbrados
  • tendremos que asumir un cierto nivel de redundancia en nuestros datos almacenados


¿Cómo se consigue esto? Pues Udi lo resuelve de una manera muy sencilla a la vez que elegante:

  • los datos son “propiedad” de una única fuente autorizada, es decir, cada dato en la base de datos sólo es manipulado por un único servicio
  • los servicios interesados en algún dato se suscriben a los cambios que publicará su fuente autorizada y guardan una copia local del dato (a modo de caché)


Esto, si no estoy equivocado, se viene conociendo como Event-Driven Architecture (EDA).

Pero Udi no nos contó sólo que la manera de implementar SOA es haciendo EDA, sino que insistió en que un servicio debe ser concebido desde el negocio y que se implementa íntegramente desde la UI hasta la BD. Para ello nos explicó diferentes maneras de componer la UI, pero todas evitando el concepto de página monolítica. Y recalcó que no tenemos que tener una única capa técnica consistente, sino que podemos decidir usar diferentes soluciones técnicas para cada problema de negocio. Claro, lo difícil es que hay que acertar en definir los “bounded contexts”, y sólo podremos acertar si tenemos claro que éste no es un trabajo tecnológico sino de análisis del negocio.


- ¡Vaya, claro, por eso hablan tanto del alineamiento de IT con el negocio cuando se hace SOA!
- ¡Ahora lo entiendo!
- ¡Y yo que pensaba que todo esto de SOA iba de reusar componentes tecnológicos y poner webservices por doquier!


Si estáis interesados, otro día puedo recopilar más notas y recordar algunos de los ejemplos que usó Udi en el curso.

¡Ah! Y que no se me olvide. Gracias a Hadi por el detalle que tuvo conmigo para Agile Spain. Lo dejo ahí porque si queréis enteraros tendréis que asistir a la charla que darán Juan, Agustín y Leo sobre “Introducción a Scrum”.