En varias entradas de este blog se ha abordado el tema de los principios de SOA, los 5 principios de Gartner, lo que no se debe hacer en SOA, etc. Sin embargo, tal vez todos estas entradas se quedan un poco en el terreno de la teoría. Es por eso que en esta, se intentará aplicar estos principios sobre un ejemplo práctico. Un ejemplo, por supuesto enormemente simplificado, que define la funcionalidad necesaria para una Agencia de Viajes.

maleta para el viaje

La funcionalidad de negocio necesaria sería la siguiente:

  • Un paquete de viaje sería todo lo necesario para que un turista pueda llevar a cabo sus vacaciones: billetes de avión, estancia en hotel y coche de alquiler.
  • Cada oficina de la agencia ejecuta un programa cliente que necesita esta funcionalidad de la aplicación de reservas de la organización.
  • Además de las oficinas de la empresa, también se debe dar servicio a una cadena de hipermercados que vende nuestros viajes con su marca, aunque en este caso no se ofrecen los coches de alquiler.

Con estos sencillos requisitos vamos a ver qué servicios de negocio se identifican. Como primer aproximación podría bastar con un único servicio:

  • reservar: un único servicio que da soporte a toda la funcionalidad requerida. Permite reservar el servicio que queramos (avión, hotel, coche…)
    • parámetros de entrada: una estructura de información genérica en la que se puede indicar los hoteles requeridos, los viajes de avión, los coches de alquiler. Esta estructura consistirá en una lista de pares de datos del tipo “nombre”, “valor”.
    • parámetros de salida: una lista de confirmaciones de todas las reservas que forman el paquete

Si examinamos este servicio siguiendo los principios anteriormente referidos, nos encontramos lo siguiente:

  • sentido para el negocio. El servicio “reservar” es demasiado genérico. Al menos debería tener un “apellido”, un sustantivo que definiese algo mejor la funcionalidad que va a proporcionar. De cara al negocio, nuestra empresa “reserva hoteles”, “vende billetes de avión” o “gestiona el alquiler de coches”. El servicio “reservar” es demasiado genérico.
  • no es modular. No tiene cohesión interna ya que se dedica a cosas muy dispares. No tiene nada que ver reservar un avión con reservar un coche de alquiler.
    Por otra parte, tampoco logra un mínimo acoplamiento con sus clientes, ya que el mensaje de entrada hace referencia a una estructura común para todos los servicios. Esto añade dependencias que no son necesarias. Por ejemplo, un cambio en la forma de reservar el coche de alquiler puede afectar a los clientes que no usan esta funcionalidad pero se ven afectados porque usan el mismo servico
  • no tiene el interfaz claramente definido. Al ser una estructura genérica para todas las funcionalidades no es posible indicar el tipo del parámetro de entrada. Por ejemplo, para el billete de avión necesitamos el parámetro “clase” del tipo “turista, business, primera” sin embargo tendremos que mandar un parámetro del tipo “nombre = tipo” y “valor = turista”.
    Al no estar el parámetro definido no es posible realizar validaciones automáticas de formato o del valor que puede llevar (en este caso es un tipo enumerado con tres posibles valores). Además no puede se descrito en el fichero WSDL (en el caso de que sea un web services), es decir, no es posible identificar automáticamente el tipo de este campo. En su lugar, será necesario proporcionar información adicional para que el programador del cliente pueda usarlo (lo normal sería enviar un documento word que acompañe al descriptor del servicio). En realidad, el descriptor del servicio, describe más bien poco.
  • seguridad: al ser un único servicio no se puede limitar el acceso a diferentes clientes. Por ejemplo, necesitamos que nuestra red de oficinas puede invocar las tres funcionalidades (aviones, hoteles y coches de alquiler) mientras que nuestro socio  (el hipermercado) no debería poder invocar al alquiler de coches.
    Como sólo tenemos un servicio, no es posible lograr este nivel de autorización con los estándares de seguridad declarativa (por ejemplo en JEE) teniendo que programar una solución ad-hoc para controlar el acceso de manera programática.
  • distribuible. Si bien el servicio “reservar” se puede implementar como un servicio web y por lo tanto es distribuible, esto es, se puede desplegar en otra máquina e invocado de manera remota.
    Sin embargo, no tiene toda la flexibilidad que nos podría otra implementación. Es posible, por ejemplo, que la demanda de reserva de billetes de avión sea diez veces más que la de alquiler de vehículos. Si en lugar de ser un sólo servicio fuesen tres se pondría desplegar el servicio más demandado en una máquina más potente o en un mayor número de máquinas que el resto de servicios, logrando una mayor eficiencia y calidad de servicio de nuestra infraestructura.
  • no es intercambiable. Al tener un sólo servicio con un contrato poco definido nos impactaría mucho un posible cambio. Por ejemplo, en un hipotético caso, nuestra compañia compra un software estándar para la gestión de flotas de vehículos de alquiler. Con una verdadera orientación a servicios, en el que las tres funcionalidades no estuviesen en el mismo servicio, sería sencillo cambiar el servicio de alquiler de coches por este paquete comercial. Sin embargo, con esta implementación es muy difícil teniendo un impacto importante en el resto de funcionalidad que proporciona la empresa estando expuestos a errores y pérdida de servicio. En realidad, un cambio en el servicio de alquiler de vehículos no tendría que afectar al Hipermercado ya que no usa este servicio, pero no será así.
  • no es compartible. Imaginemos que nuestra organización llega a un acuerdo económico con otra empresa para proporcionarle billetes de avión. Esta nueva empresa tendría que implementar la invocación a nuestro único servicio, teniendo que lidiar con parámetros (los de la reserva de hotel y coches) que en realidad no le interesa para nada. Tal vez, en este caso, habría que decirle: tienes que mandarme 50 parámetros pero 40 tienen que venir vacios ya que no te hacen falta.
  • composición. Imaginemos que nuestro área de negocio quiere sacar un nuevo producto al mercado que consiste en “escapada cultural”. Combina los billetes de avión, hotel para un fin de semana y entradas a un musical de moda. ¿como compondríamos este nuevo servicio basándonos en el servicio ya disponible anteriormente? como es tan genérico y con un interfaz tan poco definido la cosa se complicaría innecesariamente.

Teniendo todo esto en cuenta, ¿como serían los servicios de negocio que implementaríamos en nuestra empresa? Los principios de orientación a servicios y también el sentido común nos dicen algo parecido a lo siguiente:

  • reservarBilleteAvión
    • parámetros de entrada: fechaSalida, fechaVuelta, origen, destino, tipo, escalas (si/no)
    • parámetros de salida: horaSalida, fechaSalida, horaVuelta, fechaVuelta, numeroAsiento, localizador
  • reservarHotel
    • parámetros de entrada: fechaSalida, fechaEntrada, númeroHabitaciones, ciudad, categoría
    • parámetros de salida: nombreHotel, localizador
  • reservarCocheAlquiler
    • parametros de entrada: fechaDesde, numeroHoras, tipoCoche, tipoSeguro
    • parámetros de salida: modeloCoche, lugarRecogida

Contrariamente a la aproximación de un sólo servicio, con el planteamiento de tres servicios:

  • sí tiene sentido para el negocio
  • es modular, tiene cohesión (cada servicio se dedica a una cosa) y expone al consumidor únicamente la información que necesita (bajo acoplamiento)
  • cada uno de los servicios tiene el interfaz (el contrato con el cliente) claramente definido
  • se puede securizar de manera independiente. Por seguridad declarativa se puede impedir el acceso desde el hipermercado al servicio de alquiler de coches
  • es distribuible. Cada servicio se puede desplegar en una máquina diferente
  • se puede sustituir un servicio por otra implementación sin afectar al resto.
  • lo puede invocar cualquier aplicación dentro o fuera de la organización
  • se puede fácilmente construir (componer) un nuevo servicio más complejo a partir de los servicios anteriores.

Espero que este ejemplo sirva para remarcar que lo primero que se necesita para lograr una Arquitectura Orientada a Servicios es identificar y diseñar los servicios. Si estos no están correctamente definidos no podremos implantar SOA en la organización de una manera efectiva.

Si encuentras interesante esta entrada puedes compartirlo…

Share

Anuncios