Con la vista en 2018, se aceptan sugerencias

Un año más es tiempo de echar la vista atrás, repasar qué ha sido del blog en 2017, revisar retos y plantear nuevos para 2018.

Este año que acaba de terminar ha resultado más exigente de lo esperado para mí, tanto profesional como personalmente, una de las más claras consecuencias de ello ha sido que he descuidado el blog en ese período.

Por otra parte, a principios del pasado año cometí el que creo que es un error (voy iterando de un lado a otro del espectro) de poner objetivos ambiguos, con lo cual 365 días después no tengo del todo claro que estén cumplidos o no.

Dichos objetivos eran:

  • Seguir leyendo, estudiando y compartir las notas de lo leído.
  • Seguir corriendo y moviéndome, este trabajo nos hace sedentarios.
  • Seguir aprendiendo abstracciones, y hablar de ellas en el blog.
  • Mejorar la fluidez con herramientas de UNIX, comandos, pipes, python para scripts, etc.
  • Contribuir de vuelta a la comunidad vía charlas o artículos.

En general he leído algo (22 libros, algunos de ellos re-leidos) pero poca literatura técnica, he acudido a menos carreras que el pasado año aunque las marcas han mejorado un poco, no he podido sacar tiempo para sentarme a estudiar abstracciones y/o herramientas, más allá del uso diario.

Por otra parte, este año mi presencia en la comunidad se ha reducido a participar en un tres o cuatro eventos como ponente y moderar algunas discusiones como parte de open spaces. En el blog, me he centrado un poco más en productividad personal, y algo de desarrollo full stack.

Para 2018 quisiera volver a poner objetivos “a la antigua”. es decir, específicos, medibles, alcanzables (al menos en teoría), relevantes y limitados en el tiempo (SMART), así que aquí está mi lista:

  • Prepararme y presentarme al examen de certificación AWS Solutions Architect.
  • Crear un proyecto personal en un nuevo lenguaje.
  • Leer, al menos, 6 libros técnicos NUEVOS.
  • Hacer un MOOC con Coursera o EdX.
  • Publicar un artículo al mes.

Salvo el primer objetivo, los demás siguen siendo algo ambiguos, pero, como bien describe el título, se aceptan sugerencias.

Feliz año nuevo, querido lector.

Otros tipos de inyección de dependencias

No es la primera vez que hablo en este blog sobre inyección de dependencias, el patrón que nos permite pasar todas las dependencias que una clase necesita en el constructor en vez de como argumentos en métodos o utilizar clases estáticas.

En el caso de Java, donde últimamente paso la mayoría de mi tiempo, contamos con Spring y Guice como las maneras más conocidas de inyectar dependencias, veamos un ejemplo de Spring.

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ClassWithDependencies {
    private final DependentClass dependentInstance;

    public void doSomethingWithDependency(){
        dependentInstance.doSomething();
    }
}

@Component
public class DependentClass {
    public void doSomething(){
        System.out.println("Doing something")
    }
}

En este ejemplo, con las anotaciones @Component de Spring y @RequiredArgsConstructor de Lombok (un pre-procesador que nos permite agregar setters, getters y constructores a Java) podemos definir ClassWithDependencies como una clase que recibe DependentClass como parámetro del constructor, y luego operar sobre ella.

En artículos anteriores hemos hablado de otros sistemas como el de ASP.net vNext o incluso crear el nuestro propio. Creando un motor de inyección de dependencias con C#

Es importante destacar que en este ejemplo concreto, la inyección construye una nueva instancia de la clase cada vez que se inyecta, siendo la más sencilla de las opciones de inyección.

Una instancia por ejecución (Singleton)

Sin embargo, podemos personalizar aún más el tipo de inyección que hacemos. Volviendo a nuestro ejemplo anterior, supongamos que DependentClass contiene información de la máquina (memoria, procesador, etc) en la que se ejecuta, y por tanto no cambiará a lo largo de la vida de nuestra aplicación.

En este caso, una nueva instancia de cada clase sería innecesario o incluso costoso, dependiendo del tipo de inyección, para lo cual, en la definición del componente, especificamos qué tipo de inyección queremos

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ClassWithDependencies {
    private final MachineContext machineContext;

    public void doSomethingWithDependency(){
        machineContext.getProcessor();
    }
}

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class MachineContext {
    public String getProcessor() {
        return "Intel";
    }
}

Comparemos esto con definir un patrón singleton de manera manual:

public class ClassWithDependencies {
    private final MachineContext dependentInstance;

    public void doSomethingWithDependency(){
        MachineContext.getInstance().getProcessor();
    }
}

public class MachineContext {
    private static MachineContext instance;

    public String getProcessor() {
        return "Intel";
    }

    private MachineContext() {
    }

    public static MachineContext getInstance(){
        if(instance == null){
            instance = new MachineContext();
        }
        return instance;
    }
}

La principal diferencia de usar Singleton en inyección respecto al singleton estándar que podemos ver en el ejemplo anterior es con inyección de dependencias tenemos las ventajas de singleton y mantenemos la capacidad de probar nuestro sistema, ya que en una prueba de ClassWithDependencies podríamos simular o utilizar un mock de MachineContext (por ejemplo si queremos probar cómo se comporta nuestra aplicación en distintos contextos).

Una instancia por petición (Request)

Una variante de Singleton especialmente para web, ocurre cuando el contexto depende de la petición o la sesión. Para este ejemplo, tenemos una función que se dedica a llevar un registro de las excepciones, y queremos, para cada excepción, registrar además el Id del usuario al que le ocurrió la excepción.

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class GlobalExceptionHandler {
    private final Request request;

    public void handleException(Exception ex){
        logger.error(request.getUserId(), ex.getStacktrace())
        machineContext.getProcessor();
    }
}

@Component
@Getter
@Setter
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class Request {
    private String userId;
}

Este formato nos permite rellenar la clase Request en la capa del controlador de de nuestra aplicación, y en la otra directamente preguntar por el estado, sin necesidad de tener que pasar el objeto request a lo largo de toda la cadena de llamadas hasta la captura de esta excepción.

Con ello, evitamos que nuestras clases tengan una referencia al objeto únicamente por tener que pasarlo a la siguiente capa, se simplifica el número de parámetros que manejamos y podemos referirnos al contexto siempre que lo necesitemos.

Conclusiones

En este artículo hemos repasado inyección de dependencias de manera tradicional y además hemos visto las ventajas de utilizar construcciones como Singleton y Request.

Y tú, usas estas construcciones cuando desarrollas aplicaciones?

En Pamplona Software Craftsmanship 2017

Este fin de semana he tenido la oportunidad de participar en un evento diferente orientado a profesionales de la industria del software en la ciudad de Pamplona, en Navarra, en el que se combinaban dos aproximaciones:

  • Por una parte, una conferencia tradicional, en la que los ponentes y las sesiones se conocen de antemano.
  • Por otra, un open space, en el que las sesiones se proponen, presentan y votan por parte de los asistentes.

Durante dos días, más de una centena de desarrolladores, ingenieros de software, programadores, agilitas, craftsmen, o profesionales de la industria, independientemente de la etiqueta que tengamos en nuestro lugar de trabajo o en nuestro CV, hemos debatido sobre la profesión, lo que nos motiva a hacer lo que hacemos, los problemas a los que nos enfrentamos y las soluciones a las que hemos llegado.

Con unas 40 sesiones entre open space y ponencias, la temática era muy variada, y pude tomar bastantes notas, entre otras cosas, sobre:

  • Cómo con TDD podemos aprender a trabajar con un lenguaje como Elixir.
  • Cuales son las responsabilidades del arquitecto del software, como todos somos arquitectos en cierta manera y cómo conectar con los responsables de negocio en nuestra empresa o nuestros clientes.
  • Cómo algunos han conseguido llevar soluciones de entrega continua a sectores como la fabricación de vehículos.
  • En qué aspectos de la experiencia de usuario deberíamos fijarnos, como mínimo, a la hora de desarrollar sistemas de información en general e interfaces de usuario en particular.
  • Cómo aprender a enseñar, de qué maneras podemos ayudar, especialmente a los que están empezando, a que entiendan y usen buenas prácticas desde el principio.
  • Por qué perdemos la motivación por la comunidad o por mejorar como profesionales, y cómo podemos recuperarla.
  • Cómo nos organizamos, tanto profesionalmente en el caso de ser freelance como personalmente.
  • Qué libros, charlas o eventos, han influido en nuestra manera de trabajar, nos han enseñado nuevas maneras de ver problemas o nos han inspirado.

Tuve además, la oportunidad de facilitar dos debates, algo que supuso otra experiencia nueva para mí por la cantidad de conversaciones que surgen, cómo se ramifican los temas y la necesidad de ser capaces de reconducir la conversación cuando se aleja demasiado del objetivo del debate.

El formato del evento y los tiempos, con descansos entre todas las sesiones, permitían un amplio margen para conversaciones informales, y eso invitaba a acercarte e iniciar una conversación con gente con quien tal vez no habrías interactuado en una conferencia “tradicional”, ya sea por la cantidad de asistentes como por esa separación entre “ponente” y “asistente”.

De manera paralela, como no solamente de software vive el craftsman, el segundo día por la mañana el tiempo me dio un respiro, me puse mis zapatillas y salí a correr un par de millas alrededor de la ciudad, algo que estoy intentando convertir en una tradición cuando voy a un evento.

Para mí fue toda una experiencia, el viernes comenzó en una sala donde, salvo excepciones, estaba rodeado de desconocidos, y vuelvo el domingo sintiéndome parte de otra comunidad, con muchísima gente que se enfrenta a un montón de problemas interesantes y con quien he compartido experiencias con una cerveza, un café, una copa de vino y algo de comer.

Desde mi humilde blog, no quería perder la oportunidad de agradecer:

  • A la organización por el impagable trabajo que han hecho a lo largo de todos estos meses desde que se convoca hasta que sucede.
  • A todos con los que compartí experiencias, de los que aprendí trucos, y que escucharon mis batallitas,
  • Finalmente a mi familia, por entender la importancia de participar en estos eventos.

Nos vemos en la siguiente!

Materiales de la charla sobre desarrollo Full Stack

El pasado 17 de marzo estuve con los chicos del DotNetClub de la UAM hablando sobre desarrollo Full Stack en la Escuela Politécnica Superior.

Desde un punto de vista personal (y sesgado) discutimos la definición de stack, la importancia de conocer las diferentes partes del mismo, los diferentes modos de ver stacks, las piezas móviles con las que nos podemos encontrar, así como diferentes arquitecturas, utilizando comida italiana como ejemplo, raviolli, lasagna, risotto, pizza, panetone…

Las slides de la charla las tienes disponibles en SlideShare y a continuación.

Gracias por asistir!

Tareas, Kanban, GTD y otras hierbas

Cada día, una, dos, diez, o centenares de tareas esperan acción por nuestra parte, tanto en nuestra vida personal como en la profesional.  Mantenerlas al día o completamente fuera de control nos puede alegrar o estropear el día.

En este artículo veremos algunas maneras de organizar las diferentes tareas que surgen a lo largo de nuestra jornada, así como aquellas que planificamos para corto, medio y largo plazo.

Listas de tareas

En este apartado cubrimos desde la lista de la compra hasta un plan de carrera. Es la variante más versátil, y podemos utilizar papel y bolígrafo en su versión más simple. Si compartimos tareas con más personas puede ser más útil recurrir a una pizarra. Por otro lado, si nuestras tareas nos llegan vía e-mail, podemos emplear nuestro cliente de correo favorito para gestionarlas, siempre que no olvidemos dar alguna respuesta al emisor.

En el terreno de las apps, tenemos Apple tasks y Gmail tasks, para iOS y Android, servicios como Remember The Milk, Wunderlist o Todoist, así como alternativas más “frikis” como Todo.txt, basado en ficheros de texto.

Sin embargo, siempre se nos acumulan demasiadas tareas, y alrededor del 60% de lo que escribimos en esas listas nunca se completa, por no decir aquello que no llegamos ni a empezar.

Como alternativa, podemos emplear una “lista de hechos”, donde escribimos aquello que hemos completado en vez de lo que pensamos hacer. iDoneThis es un servicio muy interesante para este escenario.

Agregando prioridades

Una vez que tenemos nuestra lista, el siguiente paso es decidir qué hacer primero. Una de las maneras en las que podemos priorizar nuestras tareas es mediante la matriz de Eisenhower, que divide las tareas en cuatro cuadrantes:

  • Urgente e importante: caída del servidor de producción…
  • Urgente y no importante: pasar la ITV del coche, renovar DNI…
  • No urgente pero importante: una certificación, un viaje, cambiar de trabajo…
  • Ni urgente ni importante: terminar el Halo 4…

Imagen 1.png

Al usar esta matriz, podemos priorizar aquello urgente e importante; dedicar todo el tiempo planificado a aquello que es importante, aunque no urgente; y en la medida de lo posible, delegar o retrasar aquello que, pese a ser urgente, no es importante.

imagen-2

Fuente de la imagen: http://mathewreuther.com/blog/2013/12/30/looking-ahead-to-2014/the-oatmeal-running-agony-nope/

Por último, lo que no encaja en ninguno de los tres cuadrantes debería ser descartado, siempre que haya trabajo pendiente en los otros cuadrantes.

Otra manera de priorizar es la propuesta por el método GTD®, de acuerdo con los siguientes valores:

  1. Contexto: esperando en el metro o sentado en nuestro escritorio, por ejemplo.
  2. Tiempo disponible: cinco minutos antes de una reunión o toda la mañana por delante, por ejemplo.
  3. Energía disponible: ¿Hemos dormido mal? ¿Venimos de salir a correr? No siempre tenemos la misma energía.
  4. Prioridad: finalmente, vemos qué es más importante para nosotros de acuerdo con nuestra preferencia.

Kanban

El contexto que acabamos de ver nos ayuda, pero ¿qué pasa con tareas que tienen más de un estado, o tareas que están en proceso o bloqueadas?

Para mantener estas tareas bajo control podemos recurrir a sistemas como Kanban, que se basa en agruparlas por estados, consiguiendo con ello visualizar todo el trabajo disponible y minimizar aquello que está en progreso, así como poder revisar aquello que hemos terminado.

La principal razón para limitar el trabajo en progreso la podemos ver en el contexto de una carretera: cuando está al límite de su capacidad es inútil, porque es un colapso de coches, mientras que si está vacía también lo es. En este escenario lo que se usa es un punto medio de capacidad que maximice el número de coches que entran y salen de la carretera. Al 100% de su capacidad es un parking, al 0% de su capacidad es un desierto, pero al 60% de su capacidad el tráfico fluye con normalidad.

Cuando trabajamos con tareas, es más importante el tráfico de las mismas que estar operando al máximo de nuestra capacidad; siendo el tráfico lo rápido que una tarea pasa por todos los pasos.

Además, tener muchas tareas “en progreso” puede provocar que haya algunas que no terminemos nunca y se mantengan en ese estado intermedio, volviendo al primer plano de nuestra mente cuando menos lo imaginamos.

Un tablero de Kanban se divide, en su forma más simple, en tres partes:

  • TODO
  • WIP
  • DONE

La sencillez del sistema hace que podamos agregar estados adicionales con total facilidad.

Como herramientas, podemos recurrir a la clásica pizarra blanca + Post-it, o usar aplicaciones como Excel (son filas y columnas, al fin y al cabo) o podemos usar tableros de Kanban de Github, GitLab, TeamServices y Jira, o aplicaciones específicas como Leankit y Kanbanflow, aunque personalmente me decanto por Trello.

Finalmente, el mayor valor de Kanban es su capacidad para trabajar con volúmenes pequeños de información. Demasiadas notas en el tablero pueden provocar que el bosque no nos deje ver los árboles.

GTD

El método GTD, popularizado por David Allen a principios de la pasada década, es uno de los más complejos e interesantes sistemas de almacenamiento y gestión de información.

Se han escrito innumerables libros y artículos sobre GTD, pero las bases son relativamente simples:

  • Capturamos la información en un buzón de entrada.
  • En otro momento clarificamos esta información y decidimos si es accionable o no, asignándola a su lista o archivo correspondiente.
  • Organizamos las listas en tareas, proyectos y contextos en función de la complejidad y los requisitos.
  • Reflexionamos sobre las tareas pendientes, re-priorizando o descartando aquellas que hayan cambiado de estado.

Este sistema se aplica de manera bastante eficiente también a elementos físicos, pudiendo utilizar papel y lápiz, notas de papel almacenadas en carpetas, o herramientas de software entre las que figuran Omnifocus, Things o, como he mencionado antes, Trello.

El principal valor de GTD es la esencia de “mente como el agua”, es decir, vaciar nuestra mente en el sistema y tenerlo todo organizado fuera de nuestro cerebro, para podernos dedicar a crear, en vez de a recordar. Un pasaje de su libro comentaba que era habitual para muchos tener listas con cientos de elementos, algo impensable en un modelo Kanban.

Midiendo resultados

Una parte importante de nuestras tareas es hacer retrospectiva, ver si hemos podido completar lo que nos hemos propuesto o saber qué nos lo ha impedido.

Una manera es utilizar programas que nos ayuden a ver a qué dedicamos nuestro tiempo, como son RescueTime y Qbserve, que vigilan nuestro ordenador para darnos informes detallados de uso y ver cuánto tiempo realmente pasamos trabajando y cuanto se nos va contestando e-mails.

Por otra parte, para tener un control más estricto sobre cuánto tiempo tardamos en completar una tarea, podemos utilizar contadores como Toggl, que está disponible para web, escritorio y móviles.

Además, podemos utilizar técnicas como Pomodoro, en el que dedicamos intervalos de 25 minutos de trabajo y 5 de descanso. Es particularmente útil si no estamos demasiado interesados en la tarea en cuestión: “al menos le dedico 25 minutos y me la quito de encima”.

Finalmente, métodos como Bullet journal defienden volver al papel para realizar esta retrospectiva, tomar nota de lo que ha pasado, incluso de aquello no planificado o de aquello que se nos ha quedado pendiente, ya que estudios han demostrado que recordamos mejor aquello que escribimos a mano.

Conclusiones

Las listas nos acompañan, las usemos conscientemente o no. Podemos crearlas, priorizarlas, agregar contexto, ampliarlas o reducirlas, podarlas y curar el contenido de las mismas, tachar elementos, medir el tiempo y el esfuerzo y, finalmente, reflexionar sobre ellas. Hay muchísimos más métodos, reglas y teorías para gestionar listas. Este artículo es solamente un resumen de lo que he ido probando con el tiempo.

Y tú, querido lector, ¿qué sistema usas o has usado?

Libro: Personal Kanban

Llevo ya unos años leyendo y aprendiendo todo lo que puedo sobre sistemas de productividad, metodologías, gestión de tareas, y sobre todo, cómo poder aplicar esos conceptos no a la gestión de equipos, sino a la gestión individual de este pequeño caos diario llamado vida.

El último libro que he agregado a mi colección, es Personal Kanban, de Jim Benson y Tonianne DeMaria Barry. Este libro contiene una implementación del método Kanban haciendo énfasis en la persona y no en el equipo.

Leer más “Libro: Personal Kanban”