Análisis forense de un YAGNI

«You Aren’t Gonna Need It» o «No vas a necesitarlo». Una de las reglas que todo aquel que se dedica al desarrollo de software debería tener presente en todo momento. Y no me refiero sólo a programadores o arquitectos, sino también a Product Owners que destrozan su producto llenándolo de funcionalidades banales.

No voy a extenderme mucho en el concepto. Hay mucha literatura por ahí. Sólo quería explicar un caso concreto que me comentaba un buen amigo hace poco. De como uno de esos YAGNIs le explotó en la cara recientemente. Como todos los accidentes, nunca hay una sóla causa, por lo podríamos argumentar que no toda la culpa fue del YAGNI. Pero lo cierto es que si alguien se hubiese planteado la necesidad de esa nueva funcionalidad antes de implementarla, probablemente no estaríamos hablando de esto ahora.

Os pongo en situación. Un sistema promocional requiere aplicar una promoción cuando se produce una determidada condición. Esa promoción siempre tiene un importe fijo. El mismo para todos los clientes y mercados. Nadie de negocio ha planteado nunca cambiar esa condición, no está en ningún backlog, nadie lo pidió y no parece que vaya a cambiar en un futuro próximo.

La cafetera.

Pero resulta que una conjunción lunar hace que un colaborador del equipo muy espabilado, voluntarioso e implicado con el proyecto, aunque algo joven e inexperto en el producto y en las técnicas de programación, tenga una conversación informal con el product owner. Y en lugar de hablar de futbol, se plantean que estaría bien parametrizar ese importe por tipo de cliente y mercado. Y se ponen manos a ello.

La zorra y el avestruz.

El resto del equipo, que está ocupado en otras tareas, no aprecia los riesgos de la modificación. Tampoco se ha hecho un grooming ni se ha planificado en ningún sprint, por lo que el desarrollo pasa bastante desapercibido.

Los spaghetti

Parece que el código del producto no es especialmente sencillo. Esta parte es bastante monolítica y tiene implicaciones con el sistema de pagos y los flujos principales de operación del producto. La modificación inicial era bastante sencilla, básicamente un «cuando pase esto, le ingresas esta cantidad al usuario». Pero al parametrizar esa cantidad por tipo de usuario y mercado, se añade más entropia a la ecuación. Y el código monolítico lleno de casos de uso que violan el principio de responsabilidad única tampoco ayuda.

Las caches las carga el diablo

Mi amigo no puede entrar en muchos detalles, pero resulta que, por circunstancias del producto, averiguar a que mercado pertenece el usuario para entregarle la cantidad que corresponde es tarea complicada computacionalmente. Por lo que alguien en el equipo propone cachear esos datos.

Nuestro voluntarioso programador, después de escuchar las críticas y consejos de un equipo de desarrollo que tampoco tiene muchas ganas de dedicar tiempo al problema, decide hacer su enésimo cambio e implementa esa cache. Y considera que el punto adecuado para guardar esa información es en el flujo de autenticación, ya que, a fin de cuentas, todos los usuarios se autentican en algún momento.

Y aquí tenemos el gran amplificador del problema. Lo que debería ser un caso de uso que ocurre esporádicamente, acaba afectando a uno de los flujos más importantes y usados de cualquier aplicación: el login.

¿Que me decías, cariño?

Cuando un coche sale malo suele decirse que aquello de «seguro que lo fabricaron el lunes a primera hora». En software, estos errores suelen aparecer los viernes, cuando los programadores quieren cerrar sprint y el product owner quiere explicarle al jefe lo listo que es y las cosas chulas que ha implementado el equipo.

Y aquí tenemos a nuestro voluntarioso colaborador pidiendo un code review a sus compañeros un viernes a primera hora de la mañana, todos ellos con el café en mano y pensando en el fin de semana.

Y resulta que la pull request, que ya llevaba varios días desarrollo y cayó en el sprint un poco torcida es aprobada sin demasiadas comprobaciones. Los test pasan, el proceso de integración continuo hace lo suyo y los cambios suben a producción sin que nadie sospeche el infierno que se va a liar en los próximos minutos.

Me gusta el olor de Napalm por la mañana

Lo que podía haber sido un viernes tránquilo se convierte pronto en un pequeño infierno. El error afecta el login de los usuarios, pero no falla siempre, sólo con algunos. La cache alimenta la entropía. No todos los usuarios fallan, y no fallan siempre. A veces falla el login, a veces la aceptación de GDPR, otros usuarios pierden su configuración de idioma. Las consecuencias son algunos clientes enfadados, medio equipo buscando e intentando corregir el problema. Gente dejando de hacer otras tareas importantes pero menos prioritarias, jefes cabreados que huelen la sangre y aprovechan para sacar los trapos rotos.. En resumen, mucha gente enfada por culpa de algo que no debió implementarse nunca.

Conclusiones

Los errores nunca vienen sólos. Por lo general, se acumulan varios pequeños errores que originan un gran problema. En este caso, hay algunas causas evidentes.

  • Tareas sin análisis previo o no «groomeadas».
  • Inexperiencia del desarrollador, tanto en el producto como en las técnicas de ingeniería.
  • Poco apoyo por parte del resto del equipo. Por falta de voluntad, o incluso por desconocimiento de la existencia del riesgo.
  • No construir usando pequeños incrementos de valor. Según parece la rama de desarrollo vivía sóla desde hacía varios dias e incluía múltiples funcionalidades. Eso dificulta las code reviews, molesta las subidas a producción y en general, cabrea al equipo.
  • Malas revisiones de código por parte del equipo. Por la razón que sea, los miembros más expertos del equipo no supieron aportar su conocimiento en la revisión de código.
  • Pero sobretodo, el error principal es la existencia del YAGNI en si mismo.

Es posible que toda la cadena de fallos lleve a otro error similar algún día, pero al menos será porque se estaba intentando aportar nueva funcionalidad.

El número de líneas es un gran determinante sobre la complejidad del software. Y la complejidad de un software tiene costes directos, medidos en euros. Un software complejo genera errores y hace más caro el desarrollo. Es mala idea engordar el código con funcionalidades innecesarias.

En este caso, TODA la funcionalidad que necesitaba negocio en el momento acual era añadir una constante con el valor 10 en alguna lugar del código. Como mucho, parametrizarlo en una configuración. 30 minutos de desarrollo, no más.

Volviendo a los orígenes

Recientemente leía un artículo en meneame en el que se trataba la poca calidad del código que escribían alumnos de últimos cursos y en cierta manera abogaban por volver a trabajar en entornos donde la memoria y el tiempo de proceso eran mucho más caros que hoy.

Reconozco que el artículo me tiró un poco para atrás al principio, pero luego recordé dos o tres experiencias en mi vida que me hicieron estar bastante de acuerdo.

El jodido VAX de la Salle

Cuanto cursaba el primer curso de Telecos en la Salle Bonanova hacíamos las prácticas de programación en C, en un supermaquinón host que llamaban el VAX (ahora se que aquello no era más que un juguete grande, aunque muy caro https://es.wikipedia.org/wiki/VAX).  El tema es que teníamos que usar el editor vi por narices, no había otro. Además, estaba mal configurado el terminal y no había manera de usar las flechas de teclado. Y lo más divertido, teníamos 60 compilaciones por práctica. A partir de ese número, el sistema te penalizaba con 60 segundos, más 10 segundos extra por cada compilación que pasase de 60.

Había prácticas donde fumabas un cigarro en cada compilación. Sobra decir que te mirabas muy bien el código antes de mandar a compilar.

Al año siguiente, cuando dejé Telecos y pasé a estudiar Informática Superior en la UAB, las prácticas de programación me parecían un juego de niños.

Un ejemplo de overkilling, o como matar moscas a cañonazos

La segunda experiencia relacionada es un proceso batch que metía datos en un mysql. Un compañero (y supuesto technical lead del equipo) se empeñó en programarlo con un comando de symfony usando doctrine. Doctrine no es especialmente bueno en ese tipo de tareas, ya que, salvo que lo ajustes adecuadamente, intenta guardar en memoria todas las entidades que ha creado.

Aquel proceso duraba casi una hora y solía romperse a la mitad por falta de memoria.

Siempre pensé, en realidad estoy convencido de que era así, que aquel tech lead no usó doctrine por que creyese que era lo más óptimo, sino porque no sabía trabajar bien a nivel de SQL. Le daba tanto terror (opinión mía) que prefería implementar un mostruo en lugar de bajar de nivel y hacer las cosas fáciles, sencillas y óptimas.

El cerebro acorchado

De eso no hablaba el artículo, es una reflexión personal. Muchas veces he tenido la sensación de que llega un día en que el cerebro empieza a acorcharse. Se acomoda y no admite nuevos conocimientos. empezamos a creer que solo existe una manera de hacer las cosas y somo impermeables a nuevas ideas.

Es por eso que siempre intento estar un poco fuera de mi zona de confort. Con 25 años de carrera por delante, es muy importante aprovecharse de la experiencia adquirida, pero mucho más aún seguir con el motor en marcha y mejorar.

Para probarme y ver si ya estoy en fase de acartonamiento, me he puesto a programar lo que sería una práctica de la universidad, una implementación de árboles binarios en Golang.  Y ¿Cómo no? La he programado en Go, que es mi juguete actual y por el que estoy apostando fuerte en mi carrera profesional.

Y he de decir que he sufrido. Creo recordar que en mi época de estudiante era más rápido implementando este tipo de cosas. O quizás era menos exigente y sólo aspiraba al aprobado justito.

En próximos articulos me meteré más en explicaros este proyecto y algunos patrones que he aplicado que me parecen muy interesantes por la manera en que se usan en Golang.

 

 

Ofertas de trabajo: ¿De que palo va la empresa?

Durante estos últimos meses he hecho varias entrevistas laborales, en realidad, muchas entrevistas. Y he leído muchísimas más ofertas de trabajo, todas relacionadas con el mundo de la programación php y/o web, en el área de Barcelona, donde vivo. Hay muchas cosas que contar, por ejemplo cuales son los mejores portales, como detectar empresas interesantes, saber lo bueno y lo malo de las carnicas (consultoras les llaman), como evitar perder tu tiempo y el de tu entrevistador, etc…

Pero hoy me voy a centrar más en como detectar el rollo que lleva una empresa, que te vas a encontrar allí y que esperan de ti, basándome exclusivamente en la redacción de la oferta de trabajo. Me he centrado en mi área, que es el php y el desarrollo web en general. Seguro que los javeros tienen otras historias similares o incluso más surrealistas.

Empresas chupiguais con capital guiri que hacen barbacoas

Las detectarás porque siempre escriben las ofertas en inglés. No siempre es así, pero suelen pedir buen nivel de inglés porque el jefe es guiri y está hasta cansado de relacionarse con mediterráneos bajitos que gritan mucho. A menudo hablan de las barbacoas, algo que no cuadra demasiado con las aficiones barcelonesas, tan acostumbrados que estamos a ver cemento por todas partes. Apenas sabemos que hacer ante una hamburguesa rodeada de llamas.

Suelen incluir frases como «No nine to six mentality» que viene a significar que vas a tirar más horas que un reloj o «startup ambient», que es como decir que te pagarán poco, igual te despiden en seis meses, pero te prometen ser CTO en 1 año.

Importante Empresa del Sector … busca = Cárnica

La verdad es que en estos tiempos se esconden poco. A veces cuesta detectarlos porque cambian de nombre cada dos por tres o usan palabrejas que se confunden en google para que no descubras que es un tío con un móvil en una mesa de coworking.

No tienen porque ser malas ofertas, depende un poco de la consultora. Mis últimos dos trabajos los he conseguido así, o sea que pueden ser de ayuda.

Pero hay que tener algunas precauciones con ellos. Por ejemplo, si la oferta es muy genérica, sobretodo a principio de año o en verano, significa que no hay una oferta clara detrás. Sólo están recogiendo perfiles para su base de datos, esperando tener candidatos preparados cuando les surja la necesidad. Salvo que no te importe, sólo te harán perder el tiempo y con suerte te llamarán dentro de 3 meses.

Otra precaución; busca ofertas similares en otras cárnicas. Es común que una empresa pida el mismo perfil a varias consultoras. Una vez me presenté a tres entrevistas para la misma empresa. Tres llamadas telefónicas, tres reuniones, dos exámenes (al tercero le envié a cagar). Si ves la oferta repetida, busca la mejor consultora. Si puede ser elige la cárnica que sólo cobra la selección, incorporándote con nómina en casa del cliente. Los que subcontratan simplemente se llevarán parte de tu sueldo y procurarán retenerte con ellos el mayor tiempo posible. A veces pueden recolocarte si el proyecto se acaba, pero.. ¿A quien le importa? También puedes recolocarte tu mismo y además es poco probable que te aguanten sin hacer nada más de un mes o dos.

Y no te cortes al preguntar el nombre del cliente o las condiciones. No les gusta dar esos datos, pero tu tiempo puede ser más importante.

Si la consultora es sólo un tío sólo con un móvil, malo. Mis dos peores experiencias han sido de esas. Por lo general se trata de un antiguo «recruiter» que dejó una consultora y se ha montado por su cuenta. El sector del recruitment es muy cerrado. Sus antiguos compañeros se la tienen jurada, sus antiguos clientes le conocen y saben que no puede garantizar nada. Es muy probable que tu currículum acabe en la basura y una posible oferta laboral cerrada para siempre.

Inmenso stack tecnológico

Encontrarás una lista interminable de conocimientos necesarios o recomendables para conseguir el puesto.

Sacado de una oferta real en una startup barcelonesa: Big Data, Nagios, Chef, Puppet, Ansible, Apache, Nginx, Ruby, Python,  Git, Solr, Tomcat, JBoss, Passenger, Unicorn, CloudWatch, Zabbix, Redis, Memcached, ElasticSearch, Cassandra, DynamoDB, Docker, VirtualBox, MongoDB, PostgreSQL, MySQL, AWS.»

Consejo: Huir como de la peste. Generalmente denota que no tienen ni puta idea de lo que se llevan entre manos, pero han leído mucho en twitter. A veces viene motivado por una dirección que tiene miedo de sus programadores y lleva al absurdo la idea de no reinventar la rueda (una buena idea, por cierto). Otras veces tienen un gurú tecnológico suelto por la empresa que va picoteando de flor en flor instalando la última tecnología que citan en stackoverflow.

En todo caso y, salvo honrosas excepciones, se trata de empresas que buscan desarrollos muy rápidos contrayendo una fuerte deuda tecnológica que puede hipotecar su futuro. Al depender de un stack tan inmenso de tecnologias, a veces demasiado inmaduras, corren un serio riesgo de no poder reorientar su negocio más adelante, o de quedarse pillados cuando una de esas tecnologías pinche, y si no, que se lo digan a los pringados que confiaron en Parse, la plataforma SaaS de Facebook, que cerró sus puertas hace unos días dejando un montón de desarrollos tirados.

Frameworks pesados y plantillas en browser

Por frameworks pesados me refiero a Symfony2, Laravel o Zend, excelentes decisiones para muchos desarrollos web. Pero la contradicción salta cuando a la vez están pidiendo Angular.js o React.js, que son sistemas de plantillas que generan la vista en el cliente (el navegador) generalmente a partir de datos json que se piden al servidor vía ajax.

Este tipo de proyectos han oído campanas y se han subido al carro, sin saber exactamente donde es la fiesta. Les han dicho que eso de las plantillas en el browser es la hostia, que podrán hacer con el mismo código la web y la app android e iOS, ahorrándose una pasta en desarrolladores.

El problema vendrá después cuando descubran que un symfony tarda 100ms sólo en devolverte un «hola mundo». Cuando le tiran 5 o 6 peticiones por página el servidor se queda tieso, el navegador congelado y todo el mundo grita y corre desnudo por la oficina aterrorizado.

Node.js, Go y Erlang + plantillas en browser=la ruta de los valientes o el cementerio está lleno de cadáveres

Si te va la fiesta, te molan las startups y cambiar de curro cada 6 meses, estás de enhorabuena.

Muchos de estos ya se han pegado la hostia antes con los frameworks pesados y las plantillas en browser. Pero, erre que erre, continúan hacia el precipicio y deciden reemplazar todo o parte de su backend por tecnologías más rápidas como Node, Go o Erlang. Y no es que crea que está mal, cuidado, el problema viene cuando programas un backend entero de un ecommerce en node, por ejemplo. En pocos días el código acaba siendo un código spagheti de niveles infumables, lleno de llamadas callback que nadie sabe entender.

Y todo vino por ahorrarte 4 duros en el programador de la app móvil.

No será extraño ver como en unos años aparecerán frameworks de desarrollo en estos lenguajes, si no están apareciendo ya. Mi consejo es mirarte ese tipo de ofertas laborales con mucha precaución. El tortazo puede doler mucho.

Y no es que esté en contra de estos lenguajes. Node.js es muy interesante para acelerar algunas partes de un proceso, por ejemplo, implementar un servidor de publicidad o responder a llamadas ajax muy ligeras. Go es un lenguaje muy bueno, especialmente en computación paralela y al mismo nivel de rendimiento del C. Puede ser una gran elección para encapsular lógica de negocio que necesite mucha computación. Erlang es un lenguaje muy antiguo (1998 aprox) que ha tenido un fuerte resurgir ante la aparición de Node y Go. Básicamente los programadores en Erlang han levantado la mano gritando que ellos ya hacían lo mismo hace 15 años y nadie les hacia ni p…. caso. Y algo de razón tienen.

Domain Drive Design (DDD), Arquitectura hexagonal y Microservicios

Este tipo de ofertas laborales pueden ser interesantes.

En este blog os hablaremos bastante de estos temas, pero como ahora estamos centrados en ofertas laborales os diré que este tipo de empresas suelen tener unos cuantos cuarentones pasados de vueltas cansados de remover mierda en códigos antiguos inmantenibles, que todavía conservan la esperanza de programarlo bien desde cero y de una puñetera vez.

Y es que, no nos engañemos, pocos proyectos empiezan desde cero usando DDD o arquitecturas hortogonales. Requieren mucha visión de futuro y por lo general las prisas para sacar un producto no permiten «perder» el tiempo en sutilezas teóricas que alargan el desarrollo, a priori.

Por lo general se trata de empresas que tienen mucho código picado en algún framework o esquema antiguo, que podía ser muy bueno en su momento pero que hoy no satisface sus necesidades (Los del node.js y compañía acabarán aquí en 5 años). Tienen un grupo de programadores gruñones diciendo que esto es una mierda y que toca rehacerlo desde hace años. La gente se va, entra personal nuevo que no entiende nada y poco a poco la cosa se va liando. Hasta que un día, alguien en la dirección cansado de ver programadores inmolados a lo bonzo piensa que quizás tenían razón y toque meter algo de pasta para refactorizar.

Y aquí es donde los viejos del lugar deciden que a partir de ahora no se casarán con ninguna tecnología ni framework. Han oído hablar de DDD y piensan que es la solución a sus problemas ya que a nivel teórico permite aislar tu capa de negocio del framework y otros detallitos.O sea, vamos a volver a programar como toda la vida, pero usaremos un framework para que no se note.

El papel lo aguanta todo. Prepárate para picar líneas de código redundantes por un tubo y escribir más documentación que libros tiene Corín Tellado.

Pero posiblemente te lo pases bien.

Fullstack Developer

Un «palabro» nuevo que hace unos años se resumía en LAMP+php+sql+html+css+javascript+photoshop. Suena mejor decir fullstack developer, ¿verdad? 😉

En resumen, que vas a hacer de todo y vas a tirar más horas que un reloj, porque tanto estarás preocupado porque al jefe no le gusta el botoncito de un formulario como en que la base de datos que diseñó el primo de alguien no tiene ni una tabla bien normalizada.

Si además aparecen las siglas SEO+UX es que quieren que lo hagas bonito. Y si citan angular.js o similar, además te va a tocar pringar con la app de móvil.

Los ágiles

Un clásico en estos tiempos, negocio de antiguos gurús seo reconvertidos en scrum masters. No hay mucho que decir, a fin de cuentas la mitad o más de las ofertas de hoy en día incluyen las siglas agile o scrum.

Sólo dos comentarios.

El primero, tu di que si, que lo tuyo es el scrum. ¿A fin de cuentas, porqué contradecir a tu futuro empleador?

Lo segundo, una pequeña reflexión. Poco después de acabar mis estudios apareció una metodología de desarrollo nueva  lamada Proceso Unificado de Desarrollo (PUD) que mucha gente conocía como UML. A mi me preocupaba el tema, a fin de cuentas no conocía de que iba la cosa y los diagramas del UML eran infumables, apenas podías entender los casos de uso y nada más. En mi empresa se gastaron una pasta en formación y herramientas. Hoy el UML está más tieso que Matusalén y lo que se lleva es el Scrum y las metodologías agile. Los egipcios ya hacían pirámides, ¿Que métodología usaban entonces?

El consejo: Tu di que si.

La verdad es que el scrum, como cualquier otra metodología planificación es interesante, útil y siempre es infinitamente mejor que no usar ningún método. La realidad es que siempre que veo equipos prácticando scrum detecto los mismos problemas: Todas las empresas lo están adaptando pero ninguna finaliza, los equipos se autoorganizan a menudo de manera clandestina y la burocracia es mayor de lo deseable.

O sea que, di que si, que ya inventarán algo nuevo.

La Integración Continua, Jenkins y el TDD

Don’t worry, be happy. Viene a ser la versión moderna de tocar el código en el servidor, pero añadiendo unas cuantas capas para que no se note.

No te asusten estas siglas, por lo general se trata de equipos de trabajo bien gestionados. Por lo menos sabes que usan algún sistema de control de versiones, con developers que saben que de vez en cuando la cagan, y por eso programan pensando en las pruebas de su código.

En mi opinión, son empresas recomendables.

Sin embargo, no es oro todo lo que reluce, luego no te quejes si no te avisé. El sistema consiste básicamente en que cualquier funcionalidad debe tener un test automático asociado. Es más, cualquier desarrollo debe hacerse siempre pensando primero el test (Test Drive Design). Una vez subido al control de versiones (buena cosa) un sistema descarga el código, ejecuta los test y si todos está correcto sube a producción. El problema viene de aquellos que creen que puede programarse un test para cualquier cosa, y no siempre es así. Si el equipo no incluye otro tipo de pruebas, puedes acabar en la versión antigua de tocar código en producción.

Conocimientos de UX (Usabilidad)

¡Alarm, Alarm, Alarm!

Lee el resto de requisitos y decide en consecuencia. Muchos no tienen ni idea de lo que significa usabilidad. Para algunos empresaurios significa «hacer cosas bonitas, no como el otro programador que cada botón lo pintaba de un color».

La usabilidad es un área superinteresante que tiene poco que ver con el diseño. Se trata de medir las mejoras que se producen sobre unos indicadores definidos por negocio cuando hay cambios en el interfaz de usuario.Por decirlo así, es más estadística que diseño. Intenta responder preguntas como «¿Cuantos usuarios comprarán si hago el botón más grande o si cambio una call to action?»

Si lo que están pidiendo es auténtica usabilidad, vas a tener suerte. Si lo que piden son botones bonitos, espero que te guste el photoshop.

Otros

Me gustaría ir extendiendo este artículo con otras burradas que se os ocurran. Si tienes alguna buena historia, no te cortes y déjanos un comentario.