Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Pomodoros: organización, productividad, salud, motivación, constancia.

Nota: este es un post no-técnico de opinión/experiencia personal.

Hace un tiempo parece que muchas de las charlas que tengo con colegas y hasta amigos terminan en el mismo lugar motivadas por diferentes factores pero digamos que casi siempre tiene el mismo origen: el día a día.

A modo de disparador voy a enumerar las principales ideas y frases que surgen de estas conversaciones.

  • No llego a terminar nada durante el día.
  • Me cuesta concentrarme con tanta interrupción.
  • Se me hace muy largo el día.
  • Termino la jornada sin ganas de hacer nada.
  • Me duele todo el cuerpo por estar sentado tanto tiempo.

Y claro todo esto esconde detrás diferentes problemáticas, algunas cosas son comunes, porque todos sabemos que en nuestra industria hay muchos cambios, que en la vida actual hay muchas interrupciones y que sufrimos un desgaste mental y físico por el tipo de tarea que hacemos y cómo la hacemos: estamos muchas horas sentados y tenemos que aplicar conocimientos, imaginación y decisiones todo el tiempo.

Pomodoro con mis ajustes

Voy a contar qué hago yo que no es nada nuevo, es una variante de la técnica del pomodoro, pero con el agregado de años de hacerlo e ir detectando qué es mejor para mí:

Básicamente, durante 25’ me focalizo en una tarea y después tomo un descanso de 5’, y cuando digo me concentro y después descanso hago varias cosas para que este tiempo sea de máximo provecho:

  • Apagar notificaciones: de todo tipo, Skype, Whatsapp, No mirar los mails, no mirar Facebook, nada; todas las interrupciones que pueden esperar 25’ se deben evitar.
  • Tener bien claro qué voy a hacer en esos minutos: invertir un poco de tiempo (tal vez un pomodoro) en organizar que voy a hacer durante esos 25’ para que sean provechosos.
  • Concentrarse en una única cosa: Si estamos programando por ejemplo puede que haciendo TDD u otra cosa vayan surgiendo otras, por ejemplo estamos haciendo TDD y nos damos cuenta de un caso de test que no tuvimos en cuenta, entonces lo anotamos de alguna manera: escribimos el nombre del caso, lo anotamos en un archivo de texto, en un papel, lo que sea, pero no nos desenfocamos de lo que estamos haciendo ahora mismo.
  • Tener todas las herramientas / información para lo que tenemos que hacer.
  • Ir por incrementos: si lo que vamos a hacer es complejo, apuntamos a algo que podemos terminar en 25’ una iteración, una primera versión (tal vez código no tan eficiente y refactorizar durante otro pomodoro)
  • No continuar más de 30’: si estamos muy concentrados con algo y nos pasamos de los 25’ lo demos ahí si podemos o intentamos tener una versión lo más rápido posible pero no nos excedemos porque estamos entusiasmados porque todo fluye, esto no hace más que cansarnos para los pomodoros posteriores.
  • Levantarse de la silla durante los 5’ de descanso: levantarse y caminar, desconectarse de lo que estamos haciendo, yo a veces todo un poco el piano o la guitarra, tiene que se un descanso físico y mental.
  • Aprovechar para estirar el cuerpo: esto es un agregado mío a la técnica, pero nos va a hacer muy bien: durante uno o dos minutos hacemos algunos ejercicios para relajar la espalda, estirar las piernas y demás.
  • Nunca, pero nunca, salta un descanso: por motivos físicos y mentales, todos saemos que trabajar de más no es bueno y menos sostenible, esto es lo mismo, tenemos que confiar en este proceso.

Yo no creo en ser tan estrictos con las reglas de casi nada (no entremos en detalles) pero tal vez para vos no funcionen 25’ sino 20’ y está perfecto, después uno irá encontrando su tiempo, lo importante es no excederse de los 30’ según mi experiencia.

Prioridades

Como en todo proceso ágil, es bueno comenzar atacando lo más riesgoso y que más incertidumbre nos cause, por supuesto utilizando prioridades y comenzando por lo más prioritario primero, de esta manera disminuimos el riesgo, la incertidumbre y vamos aprendiendo en el camino.

Pomodoros de diferentes cosas

Es buena idea utilizar pomodoros para organizar o reorganizar el trabajo, al prinicipio o mitad del día, o cuando sea, pero la idea general es la misma: Timebox y foco. Podemos hacer pomodoros de cualquier cosa, siempre intentando explotar sus principios.

Para ir mejorando

Al igual que todo proceso es mejor si es iterativo y lo vamos mejorando con el tiempo, aunque parezca poco si durante una jornada laboral de 8 horas hago 11 o 12 pomodoros considero que fue un día excelente, y van a notar que aplicando la técnica esto puede significar un progreso gigante aunque parezca que perdimos horas de trabajo.

Motivación

En mi caso una vez que fui encontrando la mejor forma para mí de aplicar estos conceptos mejoró mucho la motivación, no voy a descubrir nada si digo que trabajar alcanzando “pequeños triunfos” es mejor que trabajar todo el día para esperar el logro final, como se demuestra en el desafío del malvavisco.

Constancia

En mi caso esto me permite mantener una constancia, porque me siento más contento con la marcha de las cosas, más enfocado y obtengo resultados que me entusiasman en lugar de ver un gran resultado solamente al final de un gran esfuerzo.

No solo en desarrollo de software

Yo he aplicado estos mismos principios para hacer cosas bien diferentes al desarrollo de software, como preparar una charla, estudiar algo nuevo, practicar tocar el bajo y demás.

Dejo algunos links

Nos leemos

Novedades de Visual Studio 2017: Intellisense Filtering

Entre las muchas novedades que nos trae la nueva versión de Visual Studio una que me resultó muy útil es Intellisense filtering, una características que nos permite aplicar filtros sobre los que nos muestra intellisense, es decir, hasta hoy si presionamos Ctrl + Space vemos algo así:

image

Lo clásico un listado con todo lo que tenemos disponible en el contexto actual, por supuesto que la lista puede ser muy larga lo cual dificulta encontrar lo que estamos buscando, más aún si se trata de una API que no conocemos y no tenemos muy claro qué estamos buscando

Intellisense filtering al rescate

Intellisense filtering permite justamente eso, poder usar intellisense y aplicar filtros en el mismo momento

image

Ahí debajo tenemos los filtros, podemos ir con el mouse y tocarlos pero mejor que eso, tenemos teclas de acceso directo para hacerlo

Teclas rápidas

  • Methods (Alt + M)
  • Interface (Alt + I)
  • Classes (Alt + C)
  • Structure (Alt + S)
  • Enums (Alt + E)
  • Delegates (Alt +D)
  • Namespace (Alt + N)
  • Keywords (Alt + K)
  • Snippets (Alt + T)

intellisense filtering

Como se ve se pueden ir tocando las teclas rápidas y agregando o quitando filtros.

De momento no existe la posibilidad de hacer nuestros propios filtros, por ejemplo si quisiéramos mostrar elementos con ciertos atributos hoy no lo podemos hacer.

De todos modos es una característica excelente que seguro le vamos a sacar provecho.

Hasta la próxima, nos leemos.

Typemock o cómo mockear como un campeón.

Todos entendemos el valor de los test unitarios en mayor o menor medida, es decir, poder probar una parte de nuestro código sin intervención de las demás en un “ambiente” aislado y repetible, de modo de poder hacerlo muchas veces y progresivamente, etc. Bien, en ocasiones ocurre que nuestro código depende de componentes que podemos “aislar” porque, por ejemplo tenemos una interfaz, algo así:

public class Negocio
{
    private IServicioExterno servicio;

    public Negocio(IServicioExterno servicio)
    {
        this.servicio = servicio;
    }

    public int HacerAlgo()
    {
        var valores = this.servicio.GetAll();
        return valores++;
    }
}

En este caso sería sencillo desentendernos de la dependencia IServicioExterno creando un mock, con Moq por ejemplo, y probar así:

[TestClass()]
public class NegocioTests
{
    [TestMethod()]
    public void HacerAlgoTest()
    {
        var mock = new Mock();
        var target = new Negocio(mock.Object);

        mock.Setup((servicio) => servicio.GetAll()).Returns(1);

        var result = target.HacerAlgo();

        Assert.AreEqual(2, result);
    }
}

Lo que hacemos es crear un mock y configurarlo para que cuando se llame al servicio GetAll devuelva un 1, esto se puede hacer porque hay una interfaz de por medio, y además tenemos acceso al código de todos los componentes.

¿Qué pasa cuando no tenemos acceso a nuestras dependencias?

No es poco común que nuestro código dependa de un componente de terceros que no tiene una interfaz o que dependamos de un componente del mismo framework de .NET que no podemos controlar y que necesitamos aislar, el clásico ejemplo es el HttpContext en una aplicación web, pero podría ser cualquiera, ahí la cosa se complica.

En estos caso hay quien (y diría que todos lo hemos hecho) genera un wrapper y saca la interfaz afuera para poder cambiar sus dependencias de HttpContext a la interfaz y usar el wrapper contra el context real en la app y una mock en los tests.

Esto es bastante trabajo, y además estamos modificando nuestro código para poder probarlo, lo cual es, al menos, polémico; por otro lado no siempre vamos a poder “inyectar” esas dependencias, habrá casos en los que no podamos simplemente hacer un wrapper porque no tenemos ningún tipo de acceso.

Otro caso aún más polémico es definir mecanismos (inyecciones, interfaces) que realmente no aportan al real funcionamiento ni a la arquitectura solamente para poder, al momento de probar, poner un mock o aislarnos de nuestra base de datos.

Typemock al rescate

Typemock Isolator no es algo nuevo para nada más bien todo lo contrario, es un proyecto bien maduro que tiene varias funcionalidades que nos ayudan a hacer tests, como runners, code coverage, generador de tests automático, etc. En el caso del Isolator en sí, lo que hace es justamente eso: permitir interceptar las llamadas a cualquier objeto de la aplicación, si, cualquier objeto y hacer diferentes cosas:

  • Reemplazarlo por un mock
  • Interceptar y modificar el resultado
  • Interceptar llamadas a métodos estáticos
  • Interceptar llamas a constructores
  • Correrlo contra nuestro entorno de CI

y algunas más, todo sorprendente, y aclaro que no es una herramienta gratuita pero creo que vale la pena, pero no demoremos más, vamos a ver cómo reemplazar una llamada a HttpContext con un mock nuestro

//decimos al Isolator que cualquier llamada a HttpContext.Current retorne un mock recursivamente
Isolate.WhenCalled(() => HttpContext.Current).ReturnRecursiveFake();
//ahora recuperamos el mock del objeto Session 
var fakeSession = HttpContext.Current.Session;
//configuramos el comportamiento del Session para que retorne un 1
Isolate.WhenCalled(() => fakeSession.SessionID).WillReturn("1");
//verificamos el comportamiento
Assert.AreEqual("1", fakeSession.SessionID);

 

Simple no? en este caso le decimos que hago mocks recursivos a partir de HttpContext.Current, después tomamos la sesión (fake) y le asignamos un valor, de ahí en adelante el código que use la sesión va a recibir lo que nosotros configuramos, sorprendente, no?

Conclusiones.

No son pocos los casos en los que agregamos una interaz solamente para poder inyectar un mock durante un test y esto es claramente trabajo de más y arquitectura de más, en este caso y en otros donde no es imposible controlar las dependencias (librería de terceros ya compiladas por ejemplo) Typemock es una excelente opción.

Nos leemos.

Tips de Javascript: Lograr que JSON.stringify se comporte a nuestro gusto

Hace ya bastante tiempo que contamos con JSON.parse() y JSON.stringify() para des-serializar y serializar objetos, lo que hace este último es generar una representación JSON de nuestro objeto, al recorrer todas las propiedades del objeto y sus propiedades anidades también, algo así:

image

Esto está muy bien, pero existen ocasiones en las que no queremos esto, por diferentes motivos: no queremos serializar todo, queremos que tenga otra forma, etc. por supuesto que podemos siempre echar mano de un método propio y no usar JSON.stringify, pero si quien consume nuestro código no sabe de la situación es probable que termine haciéndolo, entonces, ¿podemos modificar este comportamiento?

Modificando el comportamiento de JSON.stringify

Sí, existe una forma estándar de decirle al navegador que en lugar de comportarse como lo hace siempre haga exactamente lo que nosotros queremos cuando se usa JSON.stringify, y es tan simple como escribir nuestro propio método toJSON, así algo así;

image

Y magia, vemos que ahora utilizando la función estándar del navegador obtenemos justo lo que queremos.

Nos leemos.

Novedades de C#7: Funciones locales

Ya hemos visto algunas de las novedaes de C#7 en este espacio y es momento de hablar de las funciones locales.

¿Qué son las funciones locales?

En pocas palabras C#7 nos da la posibilidad de declarar una función dentro de otra…si, dentro de otra, con las ventajas que esto aporta:

  • Visibilidad acotada
  • Acceso a las variables del entorno en que se declara
  • No ensuciamos el código con algo muy específico del contexto que necesitamos

Vamos a ver un ejemplo, imaginemos que tenemos una estructura tipo árbol guardada en una base de datos

image

Simple, cada elemento tiene un padre y así se arma el árbol, del lado de C# tenemos:

class Hoja
{
    public string Nombre { get; set; }
    public int Id { get; set; }
    public IList Hijos { get; set; }
    public Hoja Padre { get; set; }
}

Básicamente tiene el nombre, id, el id del padre y el listado de hijos, lo que queremos hacer es armar un árbol poniendo los hijos, lo natural sería hacer algo recursivo.

void BuscarHijos(Hoja hoja, IEnumerable hojas)
{
    foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
    {
        hoja.Hijos.Add(hijo);
        BuscarHijos(hijo, hojas);
    }
}

public IEnumerable Generar()
{
    var hojas = Hoja.GetAll();
    var lista = new List();

    foreach (var item in hojas.Where(i => i.Padre == null)) // buscamos los nodos raíz
    {
        lista.Add(item);
        BuscarHijos(item, hojas);
    }

    return lista;
}

Entonces, primero buscamos aquellas hojas que no tiene padres (son las raices) y después iteramos esa colección y buscamos las hojas que tienen como padre al nodo raíz actual, usamos una función recursiva para buscar hijos de hijos, esto debería funcionar.

Usando funciones locales.

El mismo código con funciones locales se pude hacer así:

var lista = new List();

foreach (var item in hojas.Where(i=>i.Padre == null))
{
    lista.Add(item);
    BuscarHijos(item);

    void BuscarHijos(Hoja hoja)
    {
        foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
        {
            hoja.Hijos.Add(hijo);
            BuscarHijos(hijo);
        }
    };
}

Como vemos declaramos la función BuscarHijos no solo dentro del método sino dentro del bucle y acotamos bien su impacto, además tenemos visibilidad de la lista de hojas y de la misma función BuscarHijo, super cool

Hay más detalles sobre las funciones locales en este link, y la propuesta original de la funcionalidad acá.

Nos leemos.