Diseño incremental de software a partir de las interacciones (parte 1)

Este post viene a cuento de que me quedé sin hacer la charla de la Bilbostack 2019 por andar pachucho durante varias semanas, teniendo que cancelar el compromiso al no haberme recuperado a los pocos días del evento. Me quedó el contenido a medio preparar y tenía la espinita clavada de compartir mis ideas sobre el tema.

Dibujo representando la autosimilaridad de Lean Startup, ATDD y TDD

¿Qué narices es eso del diseño incremental?

Ahora que “agile” (nótese el entrecomillado ;)) es mainstream, parece que se va asumiendo en muchos sitios que hacer software de forma iterativa ayuda a hacer mejor software. Cada cierto tiempo hay entregas que permiten validar si se va por un camino correcto o no, comprobar malos entendidos, ver problemas que han surgido, adaptabilidad a cambios…

Lo que bajo mi percepción no es tan mainstream es la parte de incremental, cuesta más hacer vertical slicing. En mi opinión esto suele ocurrir por falta de habilidades o conocimiento de prácticas relacionadas con Extreme Programming, como son test first o el propio diseño incremental.

Aunque siempre hay que hacer un esfuerzo inicial para poder sentar algunas bases respecto a la visión del producto, qué problemas o necesidades se quiere resolver, la arquitectura de alto nivel, etc.; muchas veces se peca de querer bajarlo demasiado en detalle desde el inicio, pretendiendo tener una foto de cómo va a ser la solución y adivinar el futuro.

No olvidemos que, cuando desarrollamos un software, hoy sabemos menos que mañana. En cada iteración que pasa, más aprendemos sobre el negocio, conocemos mejor las herramientas y la tecnología, intentamos mejorar como equipo, etc.

Así que una cosa que debemos tener clara es que, si queremos que nuestro software dure, tenemos que enfocarnos en diseñar software que acepte cambios. Aceptar la incertidumbre frente a tratar de adivinar problemas futuros.

¿Y lo de diseñar a partir de las interacciones?

Pues básicamente enfocar el diseño de software desde cómo se va a utilizar, ya sean personas que interactúan a través de una UI u otros sistemas que lo hacen usando algún tipo de API.

Seguramente resulta familiar el término API first, que es una aproximación similar. Empezar definiendo cómo se expone el software partir de un contrato e ir haciendo Outside-In hacia la implementación y modelado más interno.

En el caso del diseño a partir de las interacciones nos abstraemos de los detalles de un API. Anteponemos la definición de la interacción a la del API ya que esta no es nada más que un detalle técnico de cómo se expone la interacción al mundo.

Y cuidado: No podemos caer en la trampa de definir pobremente esas interacciones, sin descubrir el negocio que hay debajo y acabar pensando que sólo son CRUDs. Nunca es un CRUD: reglas de negocio, efectos colaterales, integraciones con terceros…

Descubrimiento de producto

Antes de identificar las interacciones, un trabajo importante es lo que se suele llamar descubrimiento de producto. Algunas cosas que necesitamos saber: objetivos de negocio del producto, quiénes son los usuarios y sus motivaciones, dependencias técnicas u organizativas, posibles restricciones, identificar a los stakeholders…

Es un tiempo dedicado a analizar y entender los problemas para poder enfocar mejor la solución, ya que no hay nada peor que descubrir que hemos contruido algo que nadie quiere.

Hay multitud de actividades que se pueden usar dependiendo del contexto (producto, equipo, negocio…): business model canvas, value proposition canvas, entrevistas, user personas, mapa de stakeholders, mapa de empatía, benchmarking de producto, customer journey map… o usar un paquete de este tipo de actividades como design sprint, agile inception deck o lean inception.

Estas actividades, muy estilo design thinking, se han quedado relegadas habitualmente a la gente de UX, negocio o gestión de producto, ya que a los técnicos típicamente no nos ha preocupado demasiado o no se nos ha incluido.

Participar en estas actividades nos ayuda a entender infinitamente mejor las necesidades durante la evolución del desarrollo del producto, además de facilitarnos el planteamiento inicial de la arquitectura de software a alto nivel. Y es que hacer diseño incremental no quiere decir que no hagamos un trabajo previo.

Formalización del backlog

Para poder organizarnos y priorizar debidamente necesitamos tener disponible algún tipo de backlog de producto, de modo que lo oportuno es hacer un volcado de product backlog items (sin preocuparnos demasiado del tamaño) como complemento a las diferentes actividades de descubrimiento que se hayan podido realizar.

A mi personalmente me gusta el terminar visibilizándolo en un formato estilo user story map. Aunque siempre he omitido la parte de journey, simplemente me gusta verlo organizado en dos dimensiones: funcionalidad/tema y prioridad agrupada en swimlanes.

Me parece muy interesante organizar las swimlanes como must, could y nice to have, al menos como organización incial o de cara a implementar un MVP. Otras veces, teniendo razonablemente claro el alcance final, las he utilizado directamente para definir releases o entregas parciales tentativas.

Refinamiento de historias de usuario

Ya con la prioridad, sabemos por donde hay que ponernos a aterrizar esos product backlog items y formalizarlo en una o varias historias de usuario. Recordemos que una historia de usuario no es sólo completar una plantilla, debería ser siempre un artefacto que sirve como recordatorio de (o excusa para) una conversación sobre ella y que además debería tener unos criterios de aceptación específicos.

Además de en las dailies o conversaciones más informales entre los miembros del equipo, habitualmente estas conversaciones deberían ocurrir más intensamente en algún tipo de sesión de planning, de la que deberíamos extraer los criterios de aceptación de las historias de usuario en las que vayamos a trabajar próximamente. Esas sesiones pueden contener ejercicios de estimación como planning poker o de refinamiento como example mapping.

Personalmente me gusta bastante el example mapping porque ayuda a estructurar las conversaciones, desgranando las historias de usuario en forma de reglas, dudas y ejemplos que ilustran las reglas.

Specification by Example

Las reglas forman parte de los criterios de aceptación de una historia, mientras que los ejemplos nos marcan la especificación y nos sirven como primer paso para hacer Specification by Example (prefiero ese nombre que Behaviour-Driven Development) con el que dirigir el diseño incremental de las iteraciones.

Como herramienta para hacer Specification by Example suelo utilizar cucumber, de modo que las especificaciones terminan en el típico formato gherkin Given/When/Then.

Evidentemente se pueden utilizar otras herramientas para esto, pero ¿por qué cucumber?:

  • Al separar las especificaciones como texto plano, permite colaborar fácilmente con perfiles no técnicos para elaborarlo o validarlo.
  • Ayuda forzarse a utilizar lenguaje ubicuo que deberíamos haber ido desarrollando (quizá incluso mantengamos un glosario de términos).
  • Queda como fuente de verdad y sirve como documentación viva. Si una funcionalidad cambia, quedará reflejado el cambio.
  • Facilita hacer ATDD separando claramente el ciclo de especificación del de desarrollo.
  • Permite implementar tests automáticos a distintos niveles. Pudiendo hacer tests sólo de la lógica de negocio, desde la UI, a través de un API…

A partir de las historias de usuario y de las especificaciones con ejemplos tendremos identificados los casos de uso o interacciones, el alcance bien definido y habremos trabajado el lenguaje ubicuo.

Este tipo de prácticas hacen más eficiente el proceso de desarrollo, aumentando la calidad del producto y evitando retrabajo a causa de malosentendidos.

Próximamente

Espero escribir al menos un post más, tratando la parte más técnica a través de un ejemplo práctico sobre:

  • Implementar tests automáticos desde especificaciones gherkin con cucumber.
  • Artefactos tácticos de Domain Driven Desing.
  • TDD Outside-In, empezando desde las interacciones o use cases.
  • Arquitectura hexagonal/clean, escapando de frameworks.

Otros recursos

En forma de cursos, posts y videos relacionados que tengo repartidos por ahí:

Maven multimodule y attached tests

En mi vuelta al mundo java, una de las cosas que he retomado es el utilizar de forma habitual proyectos maven multimodule, lo que facilita controlar mejor las dependencias y segregar el empaquetado.

Así podemos hacer separación de responsabilidades dependiendo de nuestros intereses. Por ejemplo, algunos escenarios por los que podríamos querer usarlos serían:

  • Partir en vertical una aplicación por temas funcionales.
  • Publicar de forma independiente una librería que sale de nuestro proyecto para reutilización de terceros.
  • Partición horizontal de una aplicación o servicio: core, diferentes APIs, persistencia…

El último escenario es el que he empezado a utilizar de forma habitual, separando el modelo de dominio de los detalles de implementación de infraestructura y mecanismo de entrega. Así evitamos en lo posible tener dependencias en los módulos core a través aproximaciones de arquitectura hexagonal.

El problema que surge frente a tenerlo en un sólo módulo maven es lo respectivo a la duplicidad en cuanto código de test.

Un ejemplo es reutilizar algunos helpers de tests. En nuestro caso, implementaciones de patrones que nos facilitan la mantenibilidad como el builder o el object mother. Tener objetos fake (puede que incluso algún dummy) para usarlos como colaboradores y desacoplarnos de las implementaciones reales. O tener especificaciones en lenguaje gherkin desde el módulo core, para que sean compartidos con los módulos responsables de tener implementados los tests de cucumber.

Gracias a Maven JAR Plugin podemos evitar estas duplicidades, ya que nos permite empaquetar los tests de un módulo en un JAR sin tener que mezclarlo en los paquetes de código de producción.

Por ejemplo, para compartir los tests del módulo core deberíamos configurar la construcción del JAR de test de este modo:

<project>
  ...
  <build>
   <plugins>
     ...
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>3.1.1</version>
       <executions>
         <execution>
           <goals>
             <goal>test-jar</goal>
           </goals>
         </execution>
       </executions>
     </plugin>
   </plugins>
  </build>
</project>

Mientras que en los módulos que queramos usar el JAR de los tests deberemos incluir la dependencia así:

<project>
  <dependencies>
  ...
    <dependency>
      <groupId>com.danilat.killerapp</groupId>
      <artifactId>core</artifactId>
      <version>X.Y.Z</version>
      <type>test-jar</type>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Con esto ya podemos reutilizar los helpers de test o especificaciones de cucumber en diferentes módulos de maven.

Un repaso a mi 2018

Este año tuve un cambio vital importante que vino dado por una combinación de circunstancias y tras un par de meses de conversaciones, terminé mudándome en Junio a A Coruña para trabajar en Zara.com. Así que cuando estuve repasando hace unos días los objetivos del año anterior, pasó lo que era de esperar, que fue bastante fiasco:

En Coding Stones como muchas otras empresas (aunque jamás nos constituyéramos como una), no conseguimos llegar y superar el tercer año de vida. Con las reglas de juego que nos marcamos sabíamos que era un modelo difícil, exige a los socios estar muy alineados y cuesta horrores vender a los clientes. Para mí haber formado parte de esta banda-cooperativa fue una experiencia que me hizo crecer en muchos aspectos, resulta imposible no tener morriña de mis exsocios de vez en cuando.

Respecto a Outreach Tool una de cal y otra de arena. El software tras la reescritura es mucho más extensible y pude ir implementando cambios y mejoras más fácilmente, aunque con mi cambio profesional se quedaron bastantes cosas en el tintero, principalmente relacionadas con temas del rediseño de UI. Ahora mismo la evolución (y explotación) del software está un poco en el limbo, quizás puedan seguir haciéndolo otras personas.

A pesar del parón en febrero por la lesión de una costilla flotante durante una sesión de guanteo, los primeros meses del año tuve una muy buena rutina de entrenamiento y empecé a sentir que (además de mantenerme bien físicamente) técnicamente mejoré bastante. Pena que con el lío del cambio de ciudad no reservé apenas tiempo para buscar un gimnasio en el que seguir aprendiendo, finalmente en noviembre encontré uno que pintaba muy bien, aunque aún he ido muy poco.

En 2018 no hice charlas como tal, sólo la que preparé con la excusa del lanzamiento del curso de Codely de BDD con Cucumber. Facilité coding dojos en el trabajo y en la CommitConf, además del Global day of Code Retreat en Coruña. Experimenté con el formato screencast y me moló bastante. Pero apenas escribí 2 posts en el medium de Coding Stones, este me gustaría escribir más. De nuevo formé parte de la organización del Startup Open Space Zaragoza.

Lo de sacar un DNDzgz como PWA quedó en un fail total. Tengo una versión funcional desplegada que les pasé a un puñado de amigos pero le faltan afinar muchas cosas, así que por el momento se queda como otro petproject que iré tocando cuando me de el puntazo de mejorar algo.

Y bueno, ni mucho menos fue un objetivo, pero algo tendré que contar de Zara.com. Llegué con la idea de dedicar la mayor parte de mi tiempo a hacer producto e involucrarme hasta la cocina en todo lo que me dejaran y fuera capaz respecto a ello. Esto es que no quiero sólo desarrollarlo, sino estar desde las fases de conceptualización y aterrizaje hasta el aprendizaje de tenerlo en producción, y acompañar en hacerlo crecer y evolucionarlo. En el camino estoy haciendo variedad de trabajo, yendo desde cuestiones puramente técnicas hasta temas más relacionados con producto o gestión, así que no me aburro ;)

Como de costumbre, más cosas del año y sin ningún orden en particular:

  • Leí mucho este año, pero casi todo fueron libros técnicos.
  • Estuve unos días en Roma.
  • Repetí participación en Movember.
  • No fui a tantos conciertos como en los últimos años, pero fui a un buen puñado.
  • Fui a algún partido a la Romareda y a Riazor (aunque no pudo ser al Depor-Zaragoza).
  • Pude asistir a BilboStack, From The Trenches en Donosti, NOS Day y XantarJ en Santiago, Software Crafters Madrid y Monitoring Day en Zaragoza.
  • Vi un par de veladas de boxeo y me quedé con ganas de ir a alguna grande.
  • Por avisado que fuera, me sorprendió lo masificada de la noche de San Juan en Coruña.
  • Volví a tener vértigos.
  • Colaboré (poco) con la fundación canem.
  • En verano hice unas vacaciones típicas aragonesas: costa daurada y fiestas del pueblo.
  • Al fin vi el Guernica de Picasso.
  • Montamos un eventito con Cachirulo Valley.
  • Hice un curso de product owning con las buenas gentes de Makoto.
  • Sobreviví a 3 bodas.
  • Vanessa también se vino a vivir a Coruña.
  • Me hicieron una fiesta de despedida sorpresa que lo moló todo.

Objetivos 2019

  • Patear la zona noroeste de la península. Tanto zonas costeras atlántica y cantábrica como visitar ciudades y pueblos más hacia el interior; son zonas que apenas he tenido oportunidad de conocer.
  • Colaborar con grupos locales a través de talleres, coding dojos… Ya tengo algunas cosillas medio apalabradas con varias personas que organizan iniciativas por aquí.
  • Conseguir tener una rutina de entrenamiento similar a la que tuve los primeros meses de 2018 para al menos recuperar técnica y aprender trucos nuevos.
  • Escribir una media de un post al mes. Llevo un tiempo en el que me apetece escribir sobre varios temas sobre los que voy trabajando, pero aunque no sean temas muy sesudos sé que me cuesta horrores y termino no dedicándole tiempo.

Respecto a mi actual trabajo, más que marcarme objetivos lo que tengo son retos. Retos que me resultan muy interesantes para este 2019, junto a varios que se avecinan en el horizonte y otros que seguro que irán surgiendo.

¡Feliz an nou!

El juego de la vida en la Commit Conf

En Junio se acababa la fecha límite para enviar propuestas a la Commit Conf, el viñarock del software (evento organizado por las mismas personas que Codemotion hasta 2018). No me apetecía proponer una charla, más a tanto tiempo vista celebrándose en Noviembre; pero finalmente me animé a enviar una propuesta de coding dojo para practicar TDD y pair programming a través del juego de la vida de Conway.

Tuve bastantes dudas en hacerlo: Lo propuse en una ocasión en un evento de agile y no cuadró, así que no tenía claro como encajaría en un evento más técnico pero un tanto generalista. Sólo había participado/facilitado coding dojos en eventos pequeños. La kata da más juego con más tiempo, a partir de 4 iteraciones o así suele haber más mezcla y se va observando mucha evolución en las soluciones. Y que podía ser un fail tanto por soledad como por superpoblación ;).

Así que procuré poner una descripción para todos los públicos y finalmente la aceptaron.

Aunque es una kata que había practicado bastante y la había facilitado en un par de code retreats la prefería rodar. Tuve la oportunidad de hacerlo en un coding dojo interno con compañeros de Zara.com, y me tomé como cierto rodaje las 2 primeras iteraciones en el Global day of Code Retrat de A Coruña.

De modo que pude acortar y refinar un poco la pequeña presentación para ayudarme a contextualizar, ya que suponía que habría gente que nunca habría participado en un coding dojo o hubiera utilizado katas como ejercicios de práctica deliberada.

Y mientras que en los code retreats prefiero ir improvisando constraints dependiendo de lo que se va viendo en cada iteración. En este caso como no había mucho tiempo ni margen de maniobra, preferí llevarlo preparado en la presentación.

Siendo el segundo día del evento y a primera hora de la mañana había alrededor de una treintena de personas. Y que en general vi a la gente muy concentrada en el ejercicio, mucha comunicación entre pares y tríos, personas desconocidas relacionándose entre ellas, gente descubriendo el testing automático o haciendo sus pinitos con TDD, programando en distintos lenguajes…

Como anécdotas os diré que yo tenía que gritar para dar instrucciones y a veces me sentía ignorado (eso que no tengo mal volumen de voz), y que uno de los fotógrafos de la organización me preguntó si era algún tipo de concurso al ver a todo el mundo tan engorilado.

Así que, aún más acordándome de mis dudas en Junio, al acabar me quedé con un buen sabor de boca :).

Un repaso a mi 2017

Vuelta al ejercicio de pensar en lo que dio de sí el año, enfrentarlo respecto a los objetivos auto-propuestos en el enero anterior y plantear algunos nuevos para este que acaba de empezar. Así que vamos a ello.

Con Coding Stones trabajamos en un par de productos bastante grandes; o al menos bastante más grandes de lo que podríamos haberlo hecho individualmente como autónomos. Aparte de mucho trabajo en el backend, tuvimos que seguir poniéndonos las pilas en el frontend para tener un flow similar al de back. Durante el año también salieron algunas formaciones y acompañamientos sobre cuestiones metodológicas y temas de arquitectura/testing en frontend. Además a finales de año grabamos varios cursos con los amigos de Codely TV. Así que hemos conseguido la continuidad que nos habíamos marcado.

En OutreachTool hemos conseguido tener una aplicación web que nos ha permitido hacer varias consultorías evitando usar las hojas de cálculo que tan dolorosas resultaban a mis compañeras. La segunda mitad del año nos centramos más en automatizar el delivery final (generación de KPIs como presentación, informe…) que en mejorar la experiencia de uso de la herramienta, así que el reto para este año es ese, que consultores que no estén relacionados directamente con la empresa empiecen a usar la herramienta. Así que objetivo cumplido, pero igual un poco a medias.

Aunque he vuelto a jugar a fútbol, aún sigo arrastrando muchas molestias de mi lesión en el cuádriceps, así que me lo estoy intentando tomar con calma. Sí he conseguido una rutina relativamente buena yendo a entrenar a boxeo, creo que técnicamente se va notando.

Además de organizar el Startup Open Space Zaragoza, estuve en eventos varios: BilboStack/ElComité, T3chfest Leganés, meetup de DevScola, Lechazoconf, UXSpain, Pamplona Software Craftsmanship, TheAntiEvent, Barcelona Software Craftsmanship, Women Tech Makers, Codemotion Madrid… en alguno de ellos contando cosillas sobre Clean Architecture, Jobsket, alternativas a las estimaciones y JS/testing.

También tocaron algunas visitas a Valencia, Madrid y Barcelona por trabajo. Aprovechando una boda, conocí Mérida. Empalmé un par de semanas de vacaciones entremezclando mi pueblo, unos días de playa y una visita a Mallorca donde pude conocer a parte de la comunidad agile balear, así que sí hice vacaciones de verdad.

Donde más he fallado ha sido en los proyectos más personales: para experimentos varios hemos usado Mosica pero nunca me puse en serio en la versión 2, por contra a final de año le he estado dedicando tiempo a otro side-project. Estuve hablando la posibilidad de mentorizar a un dev, pero finalmente no fuimos capaces de darle forma a cómo hacerlo y se terminó diluyendo; sigue siendo algo que me molaría hacer, pero esta vez no me lo voy a plantear como objetivo, y si surge genial.

Y de nuevo, ahí va un popurrí desordenado:

  • He conocido alguna persona que vale muy mucho la pena.
  • Sin seguir siendo un gran lector, volví a leer bastante y variado: Técnicos, relatos, ensayos, filosóficos, novela…
  • En algunos viajes he podido ir viendo a un buen número de amigos y amigas.
  • Seguimos con la buena costumbre de caballeretes de juntarnos casi todas las semanas a cenar.
  • Estuve con varios amigos un finde de Pirineos Sur.
  • Además de nuevo pude pasármelo genial en un buen puñado de conciertos.
  • Vi nacer MulleresTech y disfruté de su primer evento.
  • Han empeorado mis resacas, por eso voy saliendo menos o con el freno más echado.
  • Me invitaron al Calderón y a San Mamés.
  • Una vez más participamos en Movember.
  • De las tripas, sigo parecido.
  • Seguí un curso de escritura creativa… pero no practiqué.
  • Cambié de gimnasio, creo que acertadamente.
  • Volví a ir de escalada.
  • Fui escribiendo en el medium de Coding Stones y muy poco aquí.
  • Volvimos a estar unos días de retiro en Alcañiz.
  • Empecé a trabajar en una nueva versión web del DNDzgz.
  • Este final de año (e inicio de 2018), he estado preparando un pequeño evento con Cachirulo Valley.

Objetivos 2018

  • Afianzar Coding Stones. Después de este año de continuidad, creo que hay que terminar de demostrar la sostenibilidad de nuestro modelo. Tenemos algunos leads muy interesantes, pero hay que concretarlos y ver qué tal siguen saliendo las cosas.
  • Reescribir parte del core de OutreachTool, hay que pagar deuda técnica para poder aumentar la velocidad de desarrollo y soportar mejor los cambios que vamos a introducir. Ahora mismo este es nuestro principal impedimento a nivel de producto.
  • Como comentaba más arriba, mejorar la UX de OutreachTool para hacer que el software lo puedan utilizar consultores externos.
  • Por razones varias terminé el año algo cansado de preparar e impartir charlas, al menos ahora mismo no me apetece nada hacerlo próximamente. Así que para este año me he propuesto dejarlo bastante de lado, quiero escribir más y probar algún formato diferente. Quizás el podcast, llevo ya un par de años pensando en hacer algo.
  • Mejorar, o al menos dar continuidad, la rutina de entrenamiento. Y si empiezan con los interclubes, quizás participar en alguno.
  • Lanzar el nuevo DNDzgz como PWA en el próximo par de meses.

Tengo más ideas que me gustaría llevar a cabo este año, pero no me las quiero poner como objetivos. En realidad son varias cosas que me apetecen mucho hacer pero o bien no quiero meterme ninguna presión, que ya está bien con lo que hay, o dependen principalmente de cuestiones bastante ajenas a mi control.

¡Feliz an nou!