CommitConf 2019

La conferencia en sí

Agenda de la Commit Conf 2019:

Charlas a las que atendí

Refactorizar rima con simplificar

¿Por qué el miedo conduce a código inmantenible? Como manager, refactorizar conlleva un riesgo. Tocas algo que funciona, pero se puede romper.

Típica historia de un proyecto fallido: código duplicado, merges enormes, nada de pair programming, conocimiento aislado, no se entiende el código de los demás ni hay esfuerzos por hacerlo,…

Llega un momento en el que cada vez es más atractivo reescribir el proyecto desde cero, lo que hace aún más difícil tener ganas de mejorar el código existente

Círculo vicioso del mal software

El código legacy no es malo para nada, es un repositorio de decisiones tomadas durante muchísimo tiempo. Es la historia viva del proyecto. Esta es la razón fundamental para decir no a la reescritura.

Podríamos ver las prácticas de eXtreme Programming como la solución a estos problemas.

Círculo virtuoso del refactoring

¿Qué razones podemos dar para refactorizar? Dar sólo razones económicas, nada de razones técnicas. De esta forma Negocio nos entenderá mejor:

Collective ownership: el código es de todos, se comparten unas guías de estilo, se fomenta el respeto entre los compañeros del equipo,…

En definitiva, comenta varias prácticas de XP, situando el Refactoring en el centro de todas ellas.

Charla muy bien expuesta, con historias relacionadas con el tema (storytelling), charla muy ensayada seguramente.

DevOps con Docker, Kubernetes y otras herramientas

Se comienza a hablar de DevOps allá por 2009, donde en una conferencia, dos trabajadores de Flickr, un desarrollador y un administrador de sistemas presentaron cómo desplegaban hasta 10 veces al día.

DevOps trata de colaboración, es como un ciclo infinito.

C.A.L.M.S.: cultura, automatización, lean (acortar ciclos de feedback,…), medir (el impacto de los cambios), share (compartir lo aprendido)

Kubernetes hace lo mismo que el mejor de los sysadmin

Habla de muchas herramientas:

NoOps: concepto que defiende que la colaboración debe ser entre Negocio y Desarrollo, porque se presupone que la infraestructura ya debería ser parte de Desarrollo (cloud,…).

Me da la impresión de que este concepto lo intenta vender alguien de cloud.

Cómo mejorar como desarrollador

¿Se necesita carrera universitaria para ser desarrollador? Bueno, no mucho. Se estudian conceptos relacionados, pero sobra mucho de lo aprendido en la universidad. La charla empezó bastante controvertida.

¿Especializado a generalista? Ni una cosa ni la otra, t-shaped

¿Deberías seguir las modas? Está bien conocerlas, pero no merece la pena pasar mucho tiempo con ellas (con todas ellas). Mejor dedicar el tiempo a estudiar las bases.

¿Objetivos individuales o de equipo? Ambos están bien, pero preferiblemente objetivos a nivel de equipo.

Las code review te deberían de encantar

Te sientes mejor cuando los compañeros te dan buen feedback y aprendes con ellos. Y a la inversa, podrás hacer que tus compañeros se sientan mejor si les enseñas y les das buen feedback.

Elige tus batallas, no impongas tu opinión, no discutas demasiado, hay veces que hay que ceder.

Comparte tus ideas, todas ellas tienen valor.

No tengas miedo a preguntar, pero también dedica un poco de tiempo a investigar.

No dejes que tu trabajo te limite, busca tus pequeñas tareas para encontrar motivación, satisfaccón.

Automatiza todo aquello que tengas que hacer 2 veces o más.

Sé minimalista. Cuanto menos elementos tenga tu código, mejor. Nada de complejidades añadidas innecesariamente.

Comentar las tareas grandes con el equipo antes de comenzar a realizarlas. Hay pocas cosas más frustrantes que dedicar tiempo a una tarea que después no sirva para nada.

Charla tipo entrevista, uno hace las preguntas, otro contesta. Un formato muy curioso.

SOLID front-end architecture

¿Necesitamos arquitectura en el front?

¿Las tecnologías front, son más fuertes o más débiles que las back?

TypeScript pone más difícil que JavaScript hacer las cosas mal.

Microfrontends, una nueva tendencia, según Jose Antonio no estamos preparados para ellos todavía. En mi opinión, creo que hay gente muy interesada en este tema y lo lleva bastante avanzado (ver ThoughtWorks Tech Radar).

La gran diferencia entre el front y el back es que el front es lo que ve el cliente.

En los proyectos en general, el front-end se diseña como una cajita enana comparada con el gran mega-diseño del back.

Normalmente, no se pasa mucho tiempo diseñando el front:

Se termina creando dependencias entre componentes, compartiendo estado entre ellos, acoplándose a respuestas del API,…

El desarrollo front-end es como cualquier otro desarrollo software:

Propuesta de arquitecture

Muchas siglas, mucha tecnología involucrada que no aporta gran cosa a la charla. El autor está bastante flipado con el front y con TypeScript en particular.

Live coding DDD

Segunda parte de una serie de charlas tipo elige tu propia aventura.

Primero un poco de contexto, siguiendo una arquitectura hexagonal, proponen la siguiente nomenclatura para los tests:

¿Cómo comunicar dos módulos (hablando en términos de DDD)? Por ejemplo, el módulo de notificaciones quiere mandar un email a todos los usuarios (módulo de usuarios) informándoles sobre los nuevos cursos (módulo de cursos) del último mes.

  1. CQRS (elegido), enviando queries a los otros módulos y enviando comandos a nuestro módulo
  2. Inyectar Repository en nuestro Application Service
  3. Inyectar Application Service

Comienza a testear de fuera hacia dentro, implementando un test de aceptación.

En el Controller, como estoy en infrastructura, me permito acoplarme a la BBDD (implementación del Repo), a Spring, al framework

El Controller manda un DTO (con tipos primitivos, que son fáciles de serializar) al Application Service. Pero no le llama directamente, si no que manda un Comando al Command Bus donde lo recibirá el Command Handler que será donde comienza nuestro caso de uso. El Command Handler es como el Application Service en CQRS.

Aquí mezcla arquitectura hexagonal, DDD, event driven arquitecture,… y me empiezo a perder

Para comunicar con otros módulos mandará queries al Query Bus. Quizá no sean Bounded Context diferentes todavía, pero El Query Bus nos desacopla muchísimo por si en un futuro queremos que sean Bounded Context diferentes.

¿Inyectar el Repo? Mejor que no, porque un módulo (o Bounded Context) conocerá el modelo de datos de otro módulo/BC

¿Inyectar el Application Service? Algo menos malo. Compartirían DTOs, pero aún así sigue conociendo detalles de otro módulo/bc.

¿Y si ahora cambiamos la base de datos, de MySQL a Elasticsearch? Fácil, no? Cambiamos la implementación del Repository, y ya está.

Casi, casi. En las queries a MySQL, se utiliza el patrón Specification (o Criteria), donde el Repository específico utiliza esa Criteria para mapear con Hibernate a MySQL. En la implementación de Elasticsearch, mantendremos los Criteria, pero el mapeo será diferente, dependerá de la nueva implementación.

Ahora ya solo faltaría migrar los datos. Aquí me he perdido: eventos guardados, etiquetas de los elementos de la base de datos en JSON para facilitar las búsquedas (que?), ¿?

Charla con ritmo trepidante, mucho contexto anterior, me falta mucho conocimiento sobre DDD, arquitectura hexagonal, event sourcing,…

Unbiasing teams

¿Cómo tomamos decisiones? ¿Cómo piensan las personas? Conociendo algunos de los sesgos existentes, podremos entender mejor a las personas que forman parte de nuestros equipos y a las decisiones que toman.

Creemos que el mundo es como lo percibimos nosotros, pero existen tantas percepciones diferentes como personas.

Sesgos y estereotipos: no tienen por qué ser malos, nos ayudan a tomar decisiones diarias de forma eficiente, ahorrando carga cognitiva.

Reciprocidad: tendemos a devolver los favores que recibimos.

El sentido común no existe de forma global, depende de la cultura

Creemos que tomamos decisiones razonadas, pero nos influyen mucho factores externos: hambre, sueño, frío/calor,… Por ejemplo, unos jueces condenaban al 100% de los juzgados justo antes de la hora de comer

En una valoración, si pides información antes, te puede afectar, como el ancla en una negociación. Ten en cuenta esto antes de valorar/juzgar a alguien.

Sesgo de utilidad: la opinión de un senior pesa más que la de un junior

Sesgo status quo: aquí se hace siempre así

Entendiendo a los demás

Las personas tienden a justificarse siempre, por muy ridículo que sea (historia del hombre hipnotizado que despierta con paraguas en día soleado)

[Disonancia cognitiva:] nos cuesta dejar algo que no nos gusta si nos ha costado mucho trabajo llegar hasta ahí

Error de atribución: atribuimos los errores de otros a su personalidad (es malo, es vago) mientras que nuestros errores los atribuimos a causas externas (mala suerte, esto falló,…). Una posible solución es asumir que todo el mundo es bueno, que intenta hacer las cosas lo mejor que sabe/puede

Las empresas deberían fomentar la ayuda entre personas, es bueno que la gente se focalice en los demás

Solemos hacer favores a personas a las que hemos hecho favores anteriormente

Cuando alguien te cae mal, buscas justificaciones para representarlo como mala persona

Si quieres que alguien se comporte de alguna forma en concreto, facilítale que se comporte de esa forma, ayúdale, incentíbale (si quieres que alguien coma bien, pon la comida sana en un lugar visible y esconde la comida menos sana)

Cambiando el entorno puedes cambiar el comportamiento de las personas

Comunicación

Tomamos decisiones dependiendo de cómo nos presentan la información. ¿Qué prefieres?

  1. Una operación con 90% de supervivencia
  2. Una operación con 10% de mortalidad

La comunicación entre iguales sólo es posible si no hay castigo. Por eso no te quejas a tu jefe, por miedo a que te despida

Incompetencia aprendida: la gente/alumnos cumple las espectativas (buenas y malas) de su jefe/profesor. Historia de los alumnos y los anagramas

Experimento con nosotros doblando una hoja de papel:

Siempre interpretamos los mensajes, por sencillos y concretos que sean. Cuidado con asumir que la gente entiende exactamente lo que tú quieres transmitir

TDD en el mundo real

TDD es una herramienta de diseño de funcionalidad, no de diseño de arquitectura

¿Qué no es TDD?

Tests de dentro hacia afuera

Así empiezan los tutoriales, así lo muestran, pero en el mundo real es difícil de aplicar. ¿Por qué? Porque tengo dos incógnitas, la entrada y la salida, lo que hace que tenga que hacer más suposiciones de las necesarias:

    ?   --- in --->  SUT   ---- out --->   ?

Tests de fuera hacia adentro

Así tengo menos incertidumbre, porque soy el que comienza el flujo.

    SUT    ---- out --->   ?  --->   ?

Cuando paso a testear la siguiente unidad, más interior, puedo desentenderme de la anterior, su comportamiento ya está totalmente testeado.

Evito el exceso de programación defensiva, porque esas defensas ya las habré implementado en las unidades exteriores.

Ya tenemos todos los tests, tenemos 100% de cobertura. ¿Puede fallar algo? Sí, por supuesto, pero no debería ser relativo al código. Será configuración, inyección de la dependencia equivocada,…

Comienza con temas generales de TDD y luego un live coding sin ritmo. Al final, como conclusión, me quedo con que su forma de trabajar es de afuera hacia adentro.

Charlas que me perdí (pero me gustaría ver)

Ideas

Libros interesantes:

También puede estar muy intersante participar en el Advent of Code 2019

Referencias