Feeds:
Entradas
Comentarios

Archive for julio 2010


Continuando con el tema de los servicios web, en este post voy a hacer una introducción a REST. Os prometo que este será breve (para mis estándares) y en próximos post nos metemos más en detalle. Lo primero es aclarar que REST no es una tecnología, ni siquiera una arquitectura, sino una familia de arquitecturas. Cualquier arquitectura de servicios distribuidos que cumpla con una serie de requisitos se puede considerar como una arquitectura REST. Estos requisitos o propiedades son los siguientes:

  • No se publican servicios RPC. En arquitecturas REST, los servicios no publican un conjunto arbitrario de métodos u operaciones. Por ejemplo, en REST no podemos publicar una interfaz «IGestionEmpleados» con métodos «addEmpleado», «removeEmpleado» o «buscarEmpleadosEnEdadDeJubilacion».
  • En REST lo que se publica son recursos. Un recurso se puede considerar como una entidad que representa un concepto de negocio que puede ser accedido públicamente. Un ejemplo de recurso sería simplemente «EmpleadosDeLaEmpresa» y otro podría ser «Empleado número 33»
  • Cada recurso, como buena entidad que se precie, y de acuerdo a los principios de OO, posee un identificador único y global, que lo distingue de cualquier otro recurso, aunque ambos tuvieran exactamente los mismos datos. En el caso de «Empleado 33», este sería diferente de «Empleado 40», aunque tuvieran el mismo nombre, sueldo, etc.
  • Cada recurso posee un estado interno, que no puede ser accedido directamente desde el exterior. Lo que sí es accesible desde el exterior es una o varias representaciones de dicho estado. Por representación se entiende un formato de datos concreto usado para la transferencia de una copia del estado público del recurso entre el cliente y el servidor. La implementación del recurso decide que información es visible o no desde el exterior, y que representaciones de dicho estado se soportan. Una representación de «Empleado 33» podría ser un documento XML con la información accesible de este. Otra representación sería un documento HTML y otra podría ser un JSON. No sólo podemos representar el recurso como datos estructurados, hay que echarle imaginación. Podríamos pedir por ejemplo, una representación en formato imagen PNG del recurso, tal vez esto devolvería una foto del empleado, o un gráfico de su productividad o su huella dactilar.
  • Si no podemos definir operaciones arbitrarias sobre el recurso, ¿cómo podemos operar con él? En REST todos los recursos comparten una interfaz única y constante. Todos los recursos tienen las mismas operaciones. Las operaciones nos permiten manipular el estado público del recurso. En un sistema REST típico se definen cuatro operaciones.
  • CREATE. En esta operación el cliente manda al servidor una petición para crear un nuevo recurso. Opcionalmente el cliente puede mandar una representación del estado inicial de este recurso. El servidor responde con el identificador global del nuevo recurso.
  • DELETE. En esta operación el cliente elimina un recurso del servidor. El cliente necesita saber el identificador del recurso.
  • READ. Con esta operación el cliente puede leer una representación del estado de un recurso, identificado con su identificador global. El cliente puede especificar que tipos de representaciones entiende. Aquí lo que ocurre realmente es que se copia el estado del recurso en el servidor y se pega en el cliente. Ambas copias del estado no se mantiene sincronizadas. El servidor puede cambiar el estado real del recurso y el cliente, de forma independiente, puede modificar su copia local del estado del recurso.
  • UPDATE. Como el servidor y el cliente tienen una copia diferente del estado, el cliente puede usar esta operación para sobrescribir o grabar su copia del estado en el servidor. De esta manera se puede actualizar el estado del recurso con las modificaciones hechas en el cliente.
  • La implementación del servicio es libre de prohibir alguno de estos métodos para un recurso en concreto. También debe definir el modelo de datos que se va a publicar y que representaciones soporta. Lo que no puede hacer es inventarse operaciones de forma arbitraria. Las operaciones son siempre las mismas.
  • Los distintos recursos se pueden interrelacionar y referenciar entre si mediante sus identificadores globales.

Una confusión típica es pensar que REST no es más que un CRUD llevado a la web, ¿no será mi BBDD relacional un sistema REST? No exactamente. Es parecido, pero existen algunas diferencias sutiles e importantes entre un CRUD simple o una BBDD con una arquitectura REST:

  • Al contrario que en un CRUD típico, como una BBDD, el servidor puede soportar muchas representaciones de un mismo recurso: xml, pdf, png, gif, excel, html, json, texto, comaereas, churros binarios, etc.. Hay pocas BBDD que hagan esto.
  • No penséis que las operaciones REST se limitan a hacer CRUD tradicional, no se trata solo de persistir nuestros cambios. Cuando hacemos un UPDATE, nuestra implementación del recurso además de grabar el estado en soporte persistente, debe hacer otras cosas, como validaciones de negocio o actualizaciones en otros recursos para mantener la consistencia global del sistema. Esto sí que se parece a una BBDD con triggers e integridad referencial, pero no es CRUD en el sentido de que no nos limitamos a grabar y ya está. Una DAO es CRUD, un recurso REST no (excepto en los casos más simples).
  • Los recursos mantiene interrelaciones entre si. La topología de estas interrelaciones es compleja, puede ser un grafo arbitrario, con ciclos, o un simple árbol. Es más, los recursos de nuestro sistema se pueden interrelacionar con recursos en sistemas de terceras partes, ya que el identificador es único y global.

Algunos estareis pensando: «¿Existe en la actualidad alguna arquitectura REST? Estas cosas tan modernas tardan un tiempo en madurar, y yo no quiero usar una tecnología que esté verde». Pues resulta que REST es un enfoque maduro con un claro ejemplo existente en la actualidad: la world wide web, o web a secas. Veamos si la web tiene propiedades REST:

  • La web está compuesta de recursos, cada página web puede considerarse un recurso.
  • Cada recurso tiene un identificador único global, que es su URI (o URL para los antiguos o IRI para los más modernos). Usando una URL podemos llegar a cualquier recurso en la web.
  • Dada una URI, y mediante el protocolo HTTP, podemos operar sobre estos recursos. La operación a realizar se especifica mediante el verbo HTTP. Mediante cabeceras especiales como Accept o Content-Type se puede especificar que representaciones entienden el servidor y el cliente y que representación se usa en un mensaje concreto para transporta el estado del recurso.
  • El verbo GET hace la operación READ.
  • El verbo DELETE hace la operación DELETE.
  • El verbo PUT se usa normalmente para hacer UPDATE
  • El verbo POST se usa normalmente para hacer CREATE.
  • Las representaciones a usar se especifican mediante los llamados tipos mime. La mayoría de los tipos mime son estándares, como xml o json. El usar tipos mime estándar facilita la interoperabilidad.

La aplicación cliente típica de la web es el navegador. Los navegadores se dedican a hacer GETs sobre URIs para obtener representaciones de las distintas páginas web. En el caso habitual cada página sólo admite una representación, típicamente HTML o PDF o texto plano o imágenes. Pero eso no significa que una misma URI no pudiera soportar distintas representaciones.

Lo interesante de todo esto es que la web es un ejemplo perfecto de servicios distribuidos a nivel global totalmente interoperable (o casi). La web, y el protocolo HTTP es una arquitectura REST. La web son servicios REST que en general sólo soportan HTML. Casi cualquier página HTML es interoperable con casi cualquier navegador, y casi cualquier página HTML puede interoperar (referenciar) con otra página HTML construida por un tercero. Es sorprendente que con este claro ejemplo, presente en nuestro día a día, llegada la hora de pensar en como hacer servicios web, no se viera lo que tenemos delante de la cara, sino que se inventara algo como SOAP y WSDL. Mmmm, sospechoso.

Como veis podemos usar HTTP, URIs y tipos mime, para publicar servicios de datos, no meras páginas, que soporten multitud de representaciones y sean conformes a los principios REST. A este tipo de servicios de datos es a los que comúnmente se llaman servicios REST. Sin embargo aun tengo que contar por qué desde mi punto de vista los servicios REST son mejores que SOAP. Las razones son varias:

  • HTTP es un protocolo que sigue los principios REST, por lo tanto hacer servicios REST es algo que aprovecha toda la infraestructura de la web ya existente: cache, proxies, firewall, compresión, etc. No se trata de inventar un protocolo y ver como meterlo con calzador para que encaje dentro de HTTP, sino usar el propio HTTP.
  • La posibilidad de usar múltiples representaciones o formatos de datos, de forma natural, es una ventaja indiscutible. No hay que extender ningún protocolo, o limitarse a XML, el protocolo HTTP ya lo soporta de forma natural. Si usamos un poco de imaginación esto puede ser una característica muy potente.
  • Los servicios REST tienen menor acoplamiento que los servicios basados en SOAP. Esto lo veremos en futuros posts.
  • No necesitamos herramientas complejas, ni montones de código generado e inmantenible. Un simple framework nos basta. Para sistemas sencillos no necesitamos ni eso.
  • Una aplicación AJAX o un móvil tienen la capacidad computacional suficiente para actuar como cliente de servicios REST.
  • Es autodescubrible, no se necesita algo como un WSDL. Esto lo veremos también en futuros posts.

En el próximo post pienso aplicar de forma más concreta todos estos principios al mundo de las aplicaciones empresariales, y veremos como de sencillo es publicar y consumir un servicio REST. Así que ya sabéis, si queréis hacer servicios web usad los mismos principios que hicieron la web posible, usad REST.

Read Full Post »


Hola a todos, lamento no haber escrito un post la semana pasada, pero la celebración de la copa del mundo de fútbol, junto con algunos imprevistos, lo impidió. Con este post pienso comenzar una serie que trate sobre como hacer servicios web usando el enfoque REST, de paso descansamos un poco de todo el tema del Agile y el TDD, aunque no os preocupeis ya volveré a dar la brasa sobre esos temas.

En este primer post de la serie pretendo hacer una introducción a los servicios web y explicar por qué la tecnología SOAP y WSDL (junto con toda la pila WS-*) no es una buena aproximación a la implementación de servicios web. Para ello tendremos que aclarar primero una cuestión fundamental, ¿qué entendemos por servicio web? Un servicio web es una pieza de software que posee las siguientes propiedades:

  • Proporciona una funcionalidad de negocio.
  • Esta funcionalidad es accesible en remoto a través de la web. Ojo, accesible a través de la web, no a través de un protocolo especial, ni de una infraestructura especial, ni en una topología de red especial. Fijaos que esta condición excluye tecnologías como por ejemplo CORBA, ya que ésta última no usa protocolos web. Esta condición garantiza que la invocación de un servicio web se pueda realizar aprovechando la infraestructura de la web ya existente, sin necesidad de instalar nada especial. La tecnología elegida para publicar servicios web debería aprovechar lo mejor posible la infraestructura web ya existente, para conseguir una mejor interoperabilidad y calidad de servicio.
  • Proporciona una interface bien definida, ocultando la implementación real. El servicio puede estar implementado en cualquier tecnología, por ejemplo COBOL. La tecnología real de implementación, y los detalles de ésta, no son importantes y no deben ser visibles al consumidor del servicio.
  • Interoperable, el proveedor del servicio y el consumidor pueden estar en tecnologías distintas, y aun así poder interactuar. Como comenté anteriormente no debería ser necesario montar una infraestructura especial para que un cliente pueda invocar a un servicio.

Desde el punto de vista del nivel de interoperabilidad de los servicios web, yo distingo tres categorías:

  • Privados. El servicio web sólo va a ser consumido por clientes desarrollados por la misma organización que lo creó.
  • Públicos. El servicio web, puede además ser consumido por clientes de otras organizaciones, con los que previamente se ha negociado el modo de acceso. Como caso típico tenemos los escenarios B2B. Un ejemplo es el tarificador de seguros que es llamado por un portal de búsqueda para comparar precios para tu seguro del automóvil.
  • Globales. El servicio web puede ser consumido por cualquier cliente en el mundo. No es factible realizar una negociación sobre el modo de acceso al servicio. Normalmente en este caso se crea una página web documentando la API del servicio y qué protocolo se va a usar. Algunas organizaciones como eBay, Amazon, Google, Yahoo, Facebook o Twitter necesitan este nivel de interoperabilidad.

Es claro que cuanto mayor nivel de interoperabilidad queramos alcanzar, necesitamos un menor nivel de acoplamiento entre el consumidor y el proveedor del servicio. El acoplamiento será mayor cuanta más información necesite el cliente para poder invocar al servicio. Cuanto mayor acoplamiento, mayor cantidad de documentación tendrá qué leer el desarrollador del cliente, y más esfuerzo se necesitará para la programación de éste. El hecho de que los servicios web oculten los detalles de su implementación a través de una interface es bueno en este sentido, ya que el cliente no necesita saber detalles sobre cómo implementa el servicio su funcionalidad para invocarlo. Otra buena práctica de desacoplamiento es que el servicio sea stateless, de esta manera el cliente no necesita almacenar el estado de la conversación para poder invocar al servicio correctamente, sólo necesita comprender los parámetros que va a enviar.

Armados con estos conocimientos básicos estamos en condiciones de comparar distintas tecnologías para construir servicios web. Nos fijaremos en la capacidad de la tecnología para usar la infraestructura web, si es capaz de ofrecer una interfaz que oculte la implementación, si permite el uso de distintas tecnologías en el lado cliente y servidor, y el grado de interoperabilidad que puede proporcionar, es decir, el nivel de desacoplamiento que ofrece.

Analicemos la tecnología más popular para hacer servicios web, la pila WS-*. La pila WS-* es un conjunto de protocolos y estándares para realizar servicios web basados en XML. La verdad es que son muchos protocolos y estándares, y bastante complejos, tantos y tan complejos que yo no conozco dos implementaciones completas de la pila WS-* en funcionamiento e interoperables entre si a todos los niveles. Sin embargo, dentro de todos estos estándares, nos podemos fijar en los dos más usados (y casi los únicos): SOAP y WSDL.

SOAP nos permite invocar procedimientos remotos usando XML. Actualmente SOAP se ha extendido para que soporte adjuntos binarios. La verdad es que si ya de por si, el XML es un formato de datos muy poco conciso, el formato SOAP es bastante verbose (al igual que mis posts). Esto evidentemente es un problema cuando queremos trabajar con anchos de banda reducidos (modems, móviles 3G, etc.). Otra característica importance de SOAP es que es neutral con respecto a la infraestructura. Esto te permite invocar procedimientos remotos a través de distintos protocolos, como por ejemplo SMTP, MQSeries, y como no, HTTP. Fijaos que SOAP no fue diseñado para aprovechar HTTP, sino que permite usar HTTP entre otros protocolos. ¡Qué chulo! debieron de pensar los arquitectos de SOAP. Bueno, lamento comunicar que a mi lo que me interesan son los servicios web, lo que me interesa es invocar a un servicio de la forma más eficiente usando la web, el hecho de que SOAP pueda invocar servicios no web me parece irrelevante, no me interesa. El hecho de que SOAP sea neutral con respecto a la infraestructura, evita que éste pueda aprovechar cualquier ventaja de la infraestructura web, e incluso en algunas ocasiones puede provocar problemas.

Por otro lado, tenemos WSDL, que es un formato XML que te permite describir, de forma declarativa, el modo de acceso al servicio. El WSDL es el documento o contrato que debe distribuirse a todos los clientes para que éstos tengan toda la información necesaria que les permita acceder al servicio. También es usado por los frameworks de publicación de servicios web y por las herramientas de generación de código, tanto a nivel cliente como servidor. En un documento WSDL hay que definir varios artefactos: tipos de datos, mensajes, operaciones, portTypes, bindings, ports y services. Casi nada. Los tipos de datos se definen con XML Schema, recordemos que SOAP sólo usa XML. Los mensajes definen los documentos XML que van a moverse entre el cliente y el servidor. Para definir un mensaje hay que especificar de que partes o secciones se conforma este y de que tipo de datos son cada una de estas secciones. Las operaciones definen parámetros de entrada y salida y posibles excepciones. Cada parámetro y excepción debe corresponderse con un mensaje. Por fin llegamos al portType, que es simplemente la interfaz del servicio, es decir, el conjunto de operaciones que soporta el servicio. Hasta aquí la parte «abstracta» o lógica del WSDL. Daos cuenta de todo lo que hemos tenido que definir para especificar una interface. Si os fijais el enfoque real de todo esto es RPC, aunque existan cosas como «SOAP Document binding». Ahora viene la parte «concreta» del WSDL. Como SOAP es neutral al protocolo tenemos que definir que protocolos se va a usar y como se va a usar. Para ello tenemos los bindings, que define el protocolo a usar (en este caso siempre SOAP) y como se va a codificar los mensajes usando SOAP (RPC o Document), para cada mensaje y operación. Después está el port, que define la dirección donde se va a publicar cada binding, dirección que depende del protocolo de transporte usado. En caso de usar HTTP, será una URI. Finalmente el servicio es el contenedor de todos los ports disponibles. Imaginaos escribir todo esto para un sistema de verdad, imaginaos tener que leer todo esto para consumir un servicio. Como veis en un WSDL hay mucha información y muy compleja, lo que genera mucho acoplamiento entre el consumidor y el proveedor del servicio.

Bien el resultado de las primeras versiones de esto del SOAP y del WSDL a nivel de interoperabilidad, fueron… como decirlo… una buena pifia. Basicamente la interoperabilidad era muy limitada. La complejidad del estándar llevó a implementaciones de distintos fabricantes no interoperables. Debido a esta situación se sacó otro estándar el WS-I Basic Profile, encargado de aclarar y simplificar SOAP y WSDL para una mayor interoperabilidad. En el fondo se recomienda usar una versión restringida de SOAP y aclara aspectos del WSDL. Con el tiempo, y este nuevo estándar, se ha llegado a conseguir una interoperabilidad aceptable, desde mi punto de vista se puede conseguir interoperabilidad a nivel público, pero a nivel global es más discutible.

El nivel de complejidad de estos estándares hace que un programador normal no sea capaz de publicar un servicio web o de consumirlo. La única manera práctica de trabajar con esta tecnología es usar herramientas potentes de generación de código en conjunción con un framework potente. Este enfoque tiene varios problemas a mi manera de ver las cosas:

  • Normalmente estas herramientas suelen costar dinero. Afortunadamente esta circunstancia está desapareciendo.
  • El código generado por las herramientas es siempre inmantenible.
  • La configuración generada por las herramientas suele ser inmantenible.
  • El WSDL hay que escribirlo. Aunque lo hagas con un editor visual, tienes que seguir entendiendo como combinar portTypes, messages, ports, etc. Este WSDL hay que mantenerlo después.
  • En el caso de que puedas generar el WSDL a partir de la interfaz que hayas programado en tu lenguaje favorito, tienes que cerciorarte que sigue WS-I Basic Profile, para que sea interoperable.

Desde el punto de vista del mantenimiento surge el problema de que nadie entiende nada de lo que hace el sistema, es muy difícil de razonar lo que está ocurriendo. Es curioso, hace unos meses ayudé a un compañero a resolver un bug en un web service basado en SOAP. Aparte de que fue infernal, lo gracioso es que para poder averiguar donde estaba el fallo, tuvimos que rastrear los mensajes HTTP, para averiguar que una cabecera estaba siendo enviada mal, y pudimos cambiar el binding del WSDL para arreglarlo. Es irónico, se supone que SOAP te esconde del HTTP, pero tuvimos que aplicar nuestros conocimientos de HTTP para poder averiguar donde estaba el error. No quiero saber lo que hubiera pasado con alguien que no supiera HTTP.

Otro problema de SOAP es que consume bastantes recursos de computación, con lo que es difícil que pueda ser usado por clientes como móviles o aplicaciones RIA (recordemos que el JavaScript no es muy rápido que digamos en los browsers actuales). Esto es un fallo grave, ya que lo ideal es que una aplicación móvil o RIA pudiera acceder a servicios web.

En resumen, los problemas de SOAP/WSDL son:

  • Es complejo y difícil de entender.
  • Necesitas un framework complejo.
  • Necesitas una herramienta compleja para que te genere el código, código generado que es inmantenible.
  • No funciona muy bien con dispositivos móviles y aplicaciones RIA basadas en javascript.
  • Es ineficiente desde el punto de vista del ancho de banda.
  • Sólo sirve para XML (con adjuntos binarios)
  • No aprovecha la infraestructura web, como caches, negociación de formatos, negociación de idioma, seguridad, sistema de concurrencia optimista, etc. Por supuesto no es firewall friendly. Aunque lo hayan vendido como tal, no lo es. SOAP usa el protocolo HTTP como un mero medio de transporte. No aprovecha sus características, y subvierte la semántica de este último. Esto hace que las llamadas SOAP sean «opacas» desde el punto de vista de la infraestructura web, como caches o firewalls. De hecho necesitas un nuevo tipo de firewall, el firewall de aplicación, que entienda SOAP y que necesita parsear todo el cuerpo de la petición para poder aplicar reglas de seguridad. Adios a securizar por URLs, puertos y verbo HTTP.
  • El programador necesita ser un «master del universo» y saber rezar.
  • Rellene aquí su experiencia de terror favorita con SOAP:__________________________________

Debido a todas estas complicaciones, algunos movimientos como SOA y BPM no han tenido una implantación real (aunque sí fingida) en las empresas. Si ya hay problemas para usar SOAP para comunicación punto a punto, imaginaos la que se monta con todo esto del SOA, ESBs y BPM. Es una pena, porque los conceptos de SOA y BPM son realmente valiosos, el fallo ha sido basarlos en una tecnología que no es la adecuada: SOAP.

Consciente de todos estos problemas, algunos arquitectos con sentido común, y algunas empresas que necesitan interoperabilidad global empezaron a impulsar un nuevo (en realidad viejo) enfoque para la construcción de servicios web. Este enfoque es REST. En el próximo post voy a explicar de que va esto de REST y qué es lo que tiene de bueno. Como veremos en el siguiente post la principal ventaja de REST es que… «it just works», ah no, que eso eran los apple.

Los que piensen que esto del REST es una patraña, debeis tened en cuenta que:

  • Está en uso por las empresas más grandes del mundo a nivel global, y a ellos les funciona.
  • Algunas grandes empresas, que venden SOAP, ahora están empezando a vender REST
  • La última versión de WSDL, WSDL2.0, ahora soporta no sólo SOAP sino también REST. Además WSDL2.0 ha sido simplificado, eliminando por ejemplo, el concepto de mensajes, y ha sido modificado para que sea más REST friendly.

Curioso este movimiento hacia WSDL2.0 ¿Debemos usar WSDL2.0 para nuestros servicios REST? No gracias, no necesitamos WSDL. Como veremos los servicios REST son autodescubribles y basado en estándares, y no necesitamos ningún WSDL, ni similar, para poder trabajar con REST. Desde mi punto de vista WSDL2.0 es una acción desesperada para intentar salvar SOAP/WSDL y la pila WS-*.  Bueno, hasta el próximo post, donde nos meteremos en faena con esto del REST.

ACTUALIZACION: Hoy en el trabajo un compañero me ha contado una historia de terror. Un WSDL de un proyecto al pasarse por la herramienta de generación de código JAVA, ha generado más de treinta mil lineas de código. En fin, para los que penseis que soy exagerado.

Read Full Post »


… y lo sabéis en el fondo de vuestro corazón, ¿o no? Bueno, a lo mejor sí que existen, pero a mi me parece que no. En este post os voy a contar mi punto de vista sobre esto de los proyectos cerrados ¡ Bien, hoy no hay TDD, menos mal ! Creo que es importante tratar este tema de los proyectos cerrados, sobre todo en relación a las metodologías ágiles, ya que está muy extendida la idea de que dichas metodologías no pueden aplicarse en proyectos cerrados. Mi idea es que eso de los proyectos cerrados no existe, y que cuando se dice que un proyecto es cerrado en realidad estamos soltando una buena mentira.

¿Os acordais del teorema CAP? Bueno, pues lo que voy a contar a continuación se parece mucho. A alto nivel y desde el punto de vista de planificación y preventa de un proyecto hay tres variables: el alcance, el tiempo de entrega y el coste unitario. Veamos que son estas tres variables:

  • Alcance. El alcance es la cantidad de funcionalidad o de historias de usuario que va a tener el proyecto. También se puede interpretar como el tamaño del proyecto. En los proyectos de alcance pequeño sólo hay que implementar unas pocas funcionalidades, en los de alcance grande tenemos una lista de requisitos grande (o unos pocos requisitos enormes). Algunos factores no funcionales, como la complejidad de las tecnologías implicadas en el proyecto, o la complejidad a nivel de interlocución, también pueden afectar al alcance.
  • Tiempo de entrega. Cuanto tiempo tenemos para terminar el proyecto.
  • Coste unitario. El coste de mantener un equipo de trabajo y toda su infraestructura por unidad de tiempo. Cuanta más gente en el equipo, mayor coste unitario. Cuantas más máquinas y más caras, más coste unitario. Cuantas más licencias de pago tengamos, más coste unitario. No confundir con el coste total, que lo da la suma del coste unitario a lo largo de todo el proyecto.

Bien, todo sencillo. En este contexto podemos definir un proyecto cerrado como aquel que tiene un coste unitario, tiempo de entrega y alcance fijo. Sin embargo esto en la práctica no existe. Un proyecto cerrado sólo podría existir en un mundo estático, donde el entorno no cambia y las cosas son totalmente predecibles y repetibles, y el mundo real no es así. En la realidad las necesidades de negocio cambian durante el desarrollo de los proyectos, los clientes y usuarios se equivocan y cambian de opinión, la productividad de un equipo de desarrollo cambia con el tiempo. Sólo un novato puede pensar que un cliente no va a cambiar de opinión o que un acta de reunión se va a respetar (en Alemania tal vez, en España no). He visto demasiadas actas de reunión y contratos y análisis funcionales haciendo compañía al papel higiénico (hay que reciclar). Todo esto lo sabe la gran mayoría de los profesionales y por ello en la práctica tenemos mecanismos de defensa como:

  • Las notas de cambio de alcance y la gestión del cambio. Es el mecanismo de defensa típico del proveedor. ¿Que el cliente cambia el alcance? Pues pagas dinero. La opción de quitar alguna funcionalidad a cambio no es tan popular.
  • Las cláusulas de penalización si un proyecto se retrasa. Con esto el cliente se defiende tanto de un proveedor en el que no confia como de posibles retrasos debido a imponderables.
  • Precio total del proyecto cerrado. Como el anterior permite al cliente defenderse de proveedores malvados o ineptos o simplemente ante cualquier tipo de desgracia acaecida durante el proyecto.

Fijaros en la contradicción, todo el mundo habla de que los proyectos de verdad son cerrados, pero todo el mundo asume que habrá retrasos, malentendidos, incompetencia, imponderables y cambios de necesidades de negocio. Todo el mundo hace proyectos cerrados, pero a la vez usan tácticas de defensa. El problema real es que la gente tiene en cuenta la realidad, pero las metodologías tradicionales no. Las metodologías tradicionales asumen que una vez pasada la fase de análisis de requisitos (o preventa como se llama en España), se puede hacer un proyecto cerrado, ya que presuponen que el mundo es estático e inamovible. Como la realidad es caótica y cambiante, pero todos se empeña en usar metodologías pesadas, se producen estas contradicciones. Usar metodologías basadas en concepciones irreales es peligroso para tu negocio, no me extraña que la mayoría de los proyectos no sean exitosos. En vez de usar metodologías que no se ajustan a la realidad y que tienen una visión inocente respecto al nivel de caos de un proyecto real, es más eficiente usar metodologías diseñadas con la cruda realidad en mente, y que se basan en aceptar el cambio y gestionarlo. ¿Cúales pueden ser estas metodologías? Mmmm, ah, sí, eso raro del agile.

Visto que el caos de la realidad nos impide tener proyectos cerrados, ¿qué hacemos? Tal vez no podamos cerrar las tres variables, pero si algunas de ellas y jugar con las demás. Veamos que posibilidades tenemos:

  • Alcance abierto, coste unitario y tiempo de entrega cerrado. Este tipo de proyectos es el clásico ejemplo en las metodologías ágiles. Se tiene un tiempo de entrega cerrado, ya que en estos casos el time to market suele ser vital en el negocio. Dada una estimación del alcance, se propone un equipo cerrado (coste unitario cerrado). Se cierra el equipo ya que normalmente añadir o quitar miembros a un equipo suele ser malo para la productividad (costes de formación, ponerse al día con el proyecto, etc). Durante el proyecto se acepta cualquier cambio de alcance, pero al acabar el tiempo pactado, se entrega. Esto permite ofertar a coste total cerrado. El proyecto se considera exitoso si el alcance conseguido es similar al estimado. Más vale estimar bien, sino el cliente quedará descontento.
  • Alcance cerrado, coste unitario cerrado y tiempo de entrega abierto. Como ya he comentado con anterioridad este caso no se produce en el mundo real, excepto tal vez, en proyectos pequeños, debido a que el alcance siempre cambia, ya sea por cambios en necesidades de negocio o por malentendidos. Aun suponiendo que el alcance es cerrado, el que el tiempo de entrega sea abierto, implica que la eficiencia o productividad del equipo varía o se ha estimado mal la capacidad del equipo. Otra posibilidad es que el time to market no afecte al valor del proyecto, pero esto es poco realista. En este caso el coste total del proyecto es abierto, ya que no sabemos por cuanto tiempo vamos a tener al equipo trabajando.
  • Alcance cerrado, coste unitario abierto y tiempo de entrega cerrado. De nuevo como el anterior este caso no es muy real, tal vez se puede dar en aplicaciones pequeñas pero con un time to market muy estricto. Para conseguir llegar a la entrega se invertirán los recursos que hagan falta. De nuevo el coste total del proyecto es abierto.
  • Alcance y coste unitario abierto, pero tiempo de entrega cerrado. Se corresponde con un proyecto crítico, no sabemos exactamente lo que se va a implementar, pero tiene que estar listo en una fecha concreta. Para conseguirlo se pondrán todos los recursos que sean necesarios.
  • Alcance y tiempo de entrega abierto, pero coste unitario cerrado. Esto es un proyecto sin prioridad ni ningún tipo de urgencia. Puede ser un proyecto personal o entre amigos.

El tipo de proyecto que os podéis encontrar más frecuentemente en la realidad es el primero, el que deja abierto el alcance y cerrado lo demás. Qué casualidad que es el tipo de proyecto en el que se centran las metodologías ágiles. Este tipo de proyectos tiene unas cualidades muy interesantes: el coste total es cerrado y por otro lado se ajusta mejor a la realidad. Esto es bueno para el proveedor, ya que evita entrar en perdidas y puede asegurarse un beneficio económico. También es bueno para el cliente, pero sólo si el alcance conseguido es suficientemente bueno.

Esta circunstancia pone al cliente en una posición de debilidad con respecto al proveedor. Muchas consultoras sin escrúpulos se aprovecharon de esto en el pasado. Por eso los clientes ahora demandan «proyectos cerrados». Lo que en realidad hacen es protegerse contractualmente. Es muy raro que un cliente admita «alcance abierto» debido a esa debilidad. Sin embargo si la relación cliente/proveedor es de una gran confianza y la experiencia pasada sea buena, si puede admitir este modelo de proyecto con alcance abierto, al fin y al cabo lo que le suele interesar al cliente es protegerse de proyectos que no se acaban nunca y que consumen dinero sin fin. Si el fracaso del proyecto no supone un gran perjuicio para el cliente, aumenta la posibilidad de que éste se preste a un contrato abierto. Otro caso es el de los proyectos internos, donde es absurdo penalizarse a uno mismo, y es mejor aceptar la realidad. En este caso el poder hacer «lo máximo posible» en un tiempo y coste acotado es bastante atractivo.

En el resto de los casos el cliente querrá un modelo de penalización o bien de precio cerrado. Esto no significa que no tengamos un proyecto con alcance abierto, sino que tenemos un contrato cerrado. Sólo debemos aceptar contratos cerrados si estamos muy seguros de poder cumplirlos o si estamos muy desesperados. Para tener esa seguridad nuestra organización debe ser lo suficientemente madura como para poder hacer estimaciones certeras. En este caso se trata de estimar el alcance, y en función de esta estimación saber que coste unitario hay que invertir para cumplir los plazos. Esto no es fácil, sobre todo si tenemos en cuenta que el coste unitario no afecta de forma muy predecible a la productividad del equipo. Podemos gastar mucho pero mal, por ejemplo comprando caras licencias de productos que no son adecuados o poniendo un pelotón de becarios en vez de unos pocos desarrolladores expertos.

En cualquier caso debemos estar preparados para lo peor. Sabemos que aunque el proyecto sea abierto el cliente normalmente se protegerá con un contrato cerrado, asi que ¿qué puede ocurrir si fracasa el proyecto? Es decir, ¿que pasa si el alcance logrado no da el valor suficiente al cliente? En estos casos el cliente tiene diferentes mecanismos para protegerse:

  • Si lo más importante para el negocio es alcanzar un nivel de funcionalidad aceptable, se da un tiempo extra al proyecto, a cambio de una penalización económica debido a los «daños» de no tener el sistema a tiempo.
  • Si lo que realmente importa es el time to market, se pone en producción pero se penaliza al proveedor en función de la cantidad de funcionalidad que falte, para compensar los inconvenientes de que el sistema no tenga suficiente funcionalidad.
  • Precio cerrado. El proyecto es precio cerrado, y el cliente no te pagará ni un céntimo más del pactado. Si el time to market es lo importante tendrás que aumentar el coste unitario para reforzar el equipo. Si lo importante es la funcionalidad, tu equipo estará más tiempo del planificado. Combinaciones de ambos escenarios son bastante típicas. Todo esto puede lleva a proyectos con poca rentabilidad o pérdidas si no consigues estimar bien.
  • Te demandan y/o devuelves el dinero más el perjuicio recibido por el cliente debido a no conseguir tener la aplicación.
  • Si aplicas una metodología que lo permita, se puede abortar el proyecto en cuanto se vea que se va a fallar. Las metodologías ágiles son especialmente adecuadas en este sentido. Si se falla al principio, el cliente aun está a tiempo de contratar a otro, con lo que tiene menos perjuicio. Desgraciadamente en España es raro ver proyectos abortados aunque claramente se encaminen al fracaso.

¿Cómo afrontamos los contratos cerrados? ¿Nos rendimos y hacemos lo «mismo de siempre»? Muy al contrario, lo ideal en estos casos es usar metodologías ágiles, aunque la idea parezca de poco sentido común. Desde el punto de vista de los contratos cerrados, las metodologías ágiles son muy eficaces, ya que nos permiten gestionar el riesgo mejor y por otro lado nos permiten tener estimaciones precisas. Uno de los pilares de dichas metodologías es el uso de ciclos de feedback frecuentes, lo que nos permite:

  • Enterarnos rápidamente de los cambios de alcance. Mediante entregas frecuentes y desarrollo incremental el cliente tiene acceso rápidamente a la funcionalidad con lo que nos puede advertir de los cambios de requisitos. Este es un mecanismo muy útil para mitigar uno de los riesgos más típicos: construir funcionalidad que el cliente no quiere.
  • Aceptar cambios e implementar la funcionalidad más importante primero. Cuando se llegue a la fecha de entrega, al menos se habrá cubierto la funcionalidad más importante, con lo que la posibilidad de fracasar disminuye.
  • Mediante las reuniones diarias nos enteramos de los posibles impedimentos al proyecto, lo que nos permite tomar acciones correctivas, mitigando riesgos tecnológicos y organizativos.
  • Análisis de viabilidad frecuente. Por ejemplo, en Scrum, podemos decidir al final de cada iteración o sprint, cancelar el proyecto, de acuerdo al feedback del usuario y de los equipos de desarrollo.
  • Las estimaciones mejoran más rápidamente, ya que al tener un feedback más rápido, tenemos más datos y por lo tanto podemos ajustar mejor las estimaciones. Con una metodología pesada el feedback es al final del proyecto, y las estimaciones sólo se pueden ajustar al final del proyecto. En Scrum ajustas las estimaciones al menos una vez por iteración (sprint). En kanban, una vez cada vez que se termina una historia de usuario.

También hay que tener en cuenta que cada sprint o iteración se puede considerar como un proyecto en si mismo, pero de alcance muy pequeño y duración corta. Si el alcance es pequeño y la duración corta,  pensar que el alcance está cerrado, sí es una buena aproximación a la realidad. Al contrario que en un proyecto real, durante un sprint, hay muy poco tiempo, y por lo tanto poca probabilidad de que el alcance del sprint cambie. Podemos considerar pues, que cada sprint es un verdadero proyecto cerrado en el sentido estricto del término. De esta forma gestionar un sprint sí es sencillo, comparado con gestionar un proyecto. De todas formas, en proyectos muy cambiantes (o altamente caóticos), el alcance cambia incluso durante el sprint. En estos caso Scrum puede que no sea la mejor opción, y habría que utilizar enfoques más ágiles todavía, como kanban o el agilismo minimalista.

Como vemos, los proyectos cerrados no existen, pero los contratos cerrados sí, lo que hace los proyectos sean arriesgados para el proveedor. Sin embargo el mito de que una metodología ágil no es útil con contratos cerrados se cae bajo su propio peso. Al contrario de lo que muchos piensan, las metodologías ágiles permiten una mejor estimación y gestión del riesgo de un proyecto con contrato cerrado, además de incorporar de forma natural la gestión del cambio. Tal vez, cuando tu cliente vea que no lo engañas y que cumples tus contratos, te deje hacer un «contrato abierto».

Read Full Post »