Mar 29

He leído “JavaScript, The Definitive Guide”

Hace un mes aproximadamente terminé de leer "JavaScript, The Definitive Guide". Un libro sobre JavaScript y alrededores que me ha encantado. Aparte de JavaScript, trata bastante bien temas como JavaScript en un navegador web, una introducción a node.js y rhino en el lado del servidor, AJAX, jQuery, almacenamiento local en el navegador, Canvas de HTML5, …

Son un montón de páginas, 1100 nada menos, pero aproximadamente la segunda mitad son una guía de referencia de las funciones de JavaScript, por lo que de lectura es aproximadamente la mitad.

Comienza con los principios de programación en JavaScript desde cero, el típica capítulo de introducción al lenguaje que no aporta demasiado a casi nadie, demasiado rápido para el que no sabe nada de programación, pero demasiado trivial para el que sabe programar en otros lenguajes. Aun así, dentro de esta parte, he encontrado una pequeña joya para alguien como yo acostumbrado a otros lenguajes y es todo el tema de cómo se hacen conversiones de tipos automáticas, sobre todo en los condicionales, es decir, cuándo una variable independientemente de su tipo (string, numérico, un objeto,…) se considera que es true o false.

Sin embargo, luego empieza a meterse en profundidad en montones de temas variados de JavaScript y aquí es donde algún programador experto en otro lenguaje pero sin demasiado conocimiento de JavaScript, empieza a disfrutar del libro. Por supuesto, hay temas demasiado farragosos como para que sea agradable leerlos, pero hay otros que me han parecido geniales, tanto por lo que supone aprender cosas que no sabes, como por la forma de exponerlas.

Entre los primeros, los farragosos, está la parte de orientación a objetos en JavaScript, clases, herencias, polimorfismo a base de tipado tipo pato, También la parte de eventos en los navegadores web es pesadita, más que nada porque cada navegador es de su padre y de su madre y no hay acuerdo en los eventos que se producen, cómo se llaman y cuándo se producen. El libro no puede hacer mucho más que dar una lista con una breve descricpción de cada uno de ellos.

Sin embargo, entre las partes geniales, me ha encantado la forma de explicar las expresiones regulares, tanto, que he hecho mi propio tutorial de expresiones regulares en JavaScript siguiendo esa forma de explicación, por supuesto, donde esté el libro que se quite cualquier tontería que haya podido hacer yo. También me ha encantado la forma de explicar jQuery, todos sus apartados, desde los selectores para buscar y modificar elementos de nuestro HTML, como la parte de AJAX, efectos especiales como fadeIn() y fadeOut(), …

En fin, totalmente recomendado para aquel que ya ha empezado a programar cosas en JavaScript pero necesita profundizar y comprender más el tema.

Mar 22

Móviles, “the hard way”

Esta mañana, como todas las mañanas de día laborable, estaba desayunando en mi cafetería habitual antes de ir a trabajar. La camarera estaba hablando con uno de los clientes y comentaban el precio de un móvil que libre costaba unos 300€, pero si hacías contrato costaba unos 80€. Por supuesto, sería un móvil de estos güay que ahora, imagino que con Android o similar.

Mi móvil es un "patatófono", el de la foto, con java JME, con teclas y todo, de tarjeta prepago porque soy muy rácano y encima lo uso como hucha, ya que cada 6 meses le meto dinero para que no se caduque la tarjeta y como pasa el 99% del tiempo apagado, tampoco lo gasto.

Sin embargo, la conversación de la camarera me ha hecho pensar que todos estamos "pillados" por los móviles de última generación. Ella con su cliente de la forma habitual, pendiente de los "wasaps" mientras pone cafés, y yo, raro de mí, de la forma "dura". Justo mientras ella hablaba con el cliente, yo estaba desayunando y leyendo "Programming Android: Java Programming for the new generation of Mobile Devices".

Aprovecho para comentar que el libro no me está gustando demasiado. Voy aproximadamente por la página 150 de sus 550 y todavía está explicándome que eclipse tiene autocompletar. Hasta ahora va explicando las cosas metiéndose en detalles sueltos muy profundos, pero explicándolos por encima y sin dar un "esquema general". Por ejemplo, primero explica java en un capítulo, pero evidentemente muy por encima. Luego cuenta el SDK de Android con todas sus herramientas en otro capítulo, describe un montón de herramientas que vienen con el SDK, pero metiéndose en detalles sin explicarlos claramente. Luego se mete con detalles que considera importantes de la programación Android, como liarse a explicar programación concurrente, tema un poco "farragoso" para empezar por él, y nuevamente se mete en detalles sin explicarlos claramente.

Sigo leyendo, enganchado como estoy al "hard way" de los móviles.

Oct 25

He leído “OpenLayers 2.10 Beginner’s Guide”

http://blog.sonxurxo.com/wp-content/uploads/2011/03/openlayers-beginners-guide.pngAcabo de leer OpenLayers 2.10 Beginner’s Guide 

OpenLayers es una librería javascript que nos permite hacer aplicaciones con mapas en nuestra página web. Los mapas pueden ser los de Google Maps, Bing, OpenStreetMap o servidor por cualquier servidor que cumpla los estándares OGC, como Geoserver. OpenLayers "traga" además otro montón de formatos para dibujar mapas directamente de ficheros.

El libro es muy básico, empieza desde el principio, tan desde el principio que incluso nos explica lo básico de javascript y qué son las clases, la herencia, los métodos y atributos. Por supuesto, no se entretiene demasiado en ello, una simple explicación para no pillarse los dedos según va avanzando en OpenLayers.

Si, como yo, has empezado con OpenLayers a base de ensayo y error, copy-paste de código en google y ya tienes algo de experiencia, este libro es muy básico, pero siempre acalara algún concepto que puedes no haber "pillado" en tus pruebas, ensayos, errores, copies y pastes.

Es ideal sin embargo para leer antes de empezar con OpenLayers, el libro va despacio, no es muy complejo lo que explica y va asentando bases antes de seguir. Cada apartado resulta un poco repetitivo porque primero te explica cómo funciona, luego te lo vuelve a explicar mientras te dice cómo codificarlo y finalmente te lo vuelve a explicar añadiendo un título "¿Qué acaba de pasar?" después de que hayas ejecutado el ejemplo que acabas de codificar. Lo dicho, ideal para quien no tiene idea del tema y le gusta asentar bien las cosas.

 

Sep 20

He leído “Test Driven: TDD and Acceptance TDD for Java Developers”

tdd acceptance testBueno, realmente exagero un poco cuando digo "he leído…", me he dejado sin leer los últimos capítulos.

La parte central del libro me ha encantado, pero la primera parte y la última me han resultado muy pesadas e inútiles, hasta el punto de dejar de leerlo en esa última parte.

Los primeros capítulos nos cuenta principalmente las ventajas de TDD, no se extiende mucho en qué es o cómo se hace TDD, sino que se extiende mucho (muchísimos) en sus ventajas. Estas ventajas son más o menos conocidas por todos (código con menos fallos, confianza en que no estropeamos nada a la hora de hacer refactoring por lo que nos cuesta menos hacerlo, etc, etc). Por ello, varios capítulos dedicados a las ventajas me parece excesivo e incluso repetitivo, ya que una y otra vez comenta las mismas ventajas.

Afortunadamente el grueso de capítulos centrales me ha parecido una maravilla. No por TDD en sí mismo, sino porque se dedica para cada tipo de proyecto diffícilmente testeable (base de datos, jsp, swing, etc) a mostrarnos los distintos frameworks con los que podemos trabajar (jdbc, hibernate, spring, jsf, tapestry, wicket, …) como las librerías útiles para hacer test automáticos en esos frameworks (mockito, clases de spring que son mock objects de interfaces java complejas, jspunit, fit, etc, etc). Lo mejor de todo esto es que no da por supuesto que conocemos cada framework o librería, sino que nos da un resumen de cada uno de ellos, qué es, para qué sirve y cómo se usa. Así que esta parte, más que para hacer test automáticos, sirve realmente para conocer de qué van todas esas siglas que oímos de continuo y a veces no sabemos qué son (jsf, spring mvc, tapestry, jsf, wicket …) y es una primera guía para saber por dónde empezar a usarlas.

Dentro de este grupo de capítulos nos habla de los test de aceptación, que son test automáticos de más alto nivel donde idealmente se considera el sistema como caja negra y se testea desde fuera automáticamente. Idealmente estos test deben estar escritos por el cliente más que por los desarrolladores, puesto que el cliente es el que sabe lo que quiere y si el test es o no suficiente. Así que, aparte de discutir en qué casos se puede/debe testear desde fuera el sistema como caja negra, o cuando se puede/debe testear justo por debajo de la interfaz de usuario, nos introduce en herramientas como fit o fitnesse.

En la última parte, la que he dejado de leer, nos muestra los problemas que podemos tener con nuestros compañeros de trabajo si intentamos convencerlos de que usen TDD, y cómo identificar esos problemas y cómo abordarlos. Pero para mí, programador principalmente, lo de las relaciones humanas no es un libro que me entretenga. Y para mí, cabeza cuadriculada, semejante texto me parece demasiado "etéreo" y evidente. Oír por enésima vez las ya consabidas frases estilo "para que tus compañeros hagan TDD, dales ejemplo haciéndolo tú" o "si te dicen que sí sin entusiasmo igual te están diciendo que no", no me parece que ayuden demasiado a pelearte con los problemas día a día. Este tipo de problemas son problemas que puedes resolver si tu forma de ser es la adecuada para ello, y los resolverás o no independientemente de que hayas leído este libro. Hay quien de forma innata es un lider y que yo sepa, no existe quien de forma innata es un anti-lider y se convierte en lider con un cursillo.

Hablando de cursillos, me ha llamado la atención (creo que tiene toda la razón), este post sobre el peligro de las certificaciones, tan de moda hoy en día http://www.javiergarzas.com/2012/09/problemas-testing.html

Y volviendo al libro otra vez, una frase traducida más o menos libremente que me ha llamado la atención "Los buenos programadores sufren un tipo especial del síndrome de déficit de atención, consistente en poner todo su empeño en usar una herramienta nueva, para abandonarla pocos meses después  y poner nuevamente todo su empeño en otra herramienta más nueva". Real como la vida misma.

Jul 07

Triangulación con TDD

Test Driven Practical TDD and Acceptance TDD for Java DevelopersEstoy leyendo ahora en mis ratos perdidos de tren al trabajo el libro Test Driven: TDD and Acceptance TDD for Java Developers. Los dos primeros capítulos me han resultado muy pesados porque no paran de repetir una y otra vez las ventajas de TDD de mil formas distintas, ventajas por otra parte ya bastante conocidas. Pero acabo de entrar en la parte donde se va desarrollando código con TDD y me está pareciendo interesante.

Una de las cosas que me ha llamado la atención es lo de la "triangulación" con TDD. Ya había leído de ella sin llegar a entenderla realmente, simplemente porque los ejemplos que había leído de triangulación eran muy tontos. Por ejemplo, si tienes que hacer un test de una clase que suma, el primer test podría ser el típico

assertEquals(4, sumador.suma(2,2));

Explicando la triangulación te dicen que pongas directamente que ese método suma(2,2) devuelve a piñón fijo 4 y luego, triangulando, haces otro ejempo de suma, por ejemplo, suma (2,5) y así llegas a la implementación correcta return sum1+sum2. Como se puede ver, algo un poco "estúpido".

Este libro menciona la triangulación varias veces, pero en un párrafo deja muy claro qué es exactamente o, al menos, así me lo ha parecido a mí. El ejemplo que comenta es que queremos tratar varias tipos de tarjetas de crédito (visa, master card, dinners club, etc, etc). El problema es que cada tarjeta tiene sus particularidades y que podemos no tener muy claro cómo hacer el código para tratar todas esas particularidades, qué partes van a ser comunes y ponernos a pensar a priori todo ese código puede ser tedioso.

Así que la solución es la famosa triangulación. Cogemos una de las tarjetas y empezamos el TDD con ella, los test, el código, específico para esa tarjeta, sin preocuparnos de las otras y finalmente el refactoring. Luego cogemos la segunda, hacemos nuevos test para esa y modificamos el código para que funcione para las dos. En la parte importante de refactoring es donde realmente arreglamos ese código para que las partes comunes y no comunes queden bien diseñadas para esas dos tarjetas. Luego tercera tarjeta, más test, más tocar código y lo más importante, nuevamente refactoring para que el diseño sea lo más claro y mejor posible para tres tarjetas.

De esta forma, deberíamos llegar a una de los mejores diseños posibles para tratar los tipos de tarjeta que debemos tratar.

Así que cuando hacemos TDD, más que triangular siempre a piñón fijo, incluso para suma(2,2) haciendo que devuelva 4 a piñón fijo y obligarnos a hacer otro test suma(2,5), debemos aplicar triangulación cuando tenemos varios casos similares pero con peculiaridades cada uno de ellos y no tenemos muy claro cómo hacer un código elegante o el mejor diseño para tratar esas particularidades a priori.

 

Apr 11

He leído “Scrum y XP desde las trincheras”

Aprovechando el eBook que me han traído los reyes estoy leyendo mucho últimamente, en el tren y en las cafeterías (sí, soy el friky ese que se sienta solo en una esquina y esconde las narices en el libro, aunque no tengo muy claro si esa expresión aplica a un eBook). Ahora le ha tocado el turno a "Scrum y XP desde las trincheras", de Henrik Kniber.

El libro no cuenta Scrum, por lo que no es el adecuado si quieres aprender qué es Scrum. De XP habla más bien poco o nada (creo que menciona la programación en parejas en un par de ocasiones, poco más). Entonces, ¿de qué va el libro?

El autor trabaja con grupos de desarrolladores que aplican Scrum y como la teoría nunca es tan bonita como la pintan, aplicar Scrum tiene un montón de problemas o cosas que no están muy claras cómo resolver. El autor nos va contando los problemas que ellos han encontrado, soluciones que han probado, soluciones que han adoptado y qué problemas todavía no saben resolver. Es un libro adecuado para aquellos equipos que saben qué es Scrum y lo están aplicando desde hace poco y se van encontrando con los problemas típicos de aplicar Scrum. Este libro le ofrece un abanico de soluciones posibles y cuáles le han funcionado al autor y cuales no.

Algunos problemas típicos:

¿Qué hacer cuando alguien del equipo se queda sin tarea dentro del Sprint?. Entre las soluciones del autor está el dejarle que él mismo elija cualquier cosa que pueda hacer para ayudar al equipo (test, pruebas, documentación, scripts que automaticen tareas, lo que sea). Y si sigue sin encontrar nada para hacer, entonces convertirlo en "recadero" de los miembros del equipo, una forma de ayudar es traerles café, por ejemplo.

¿Qué hacer cuando el código o lo que sea necesita tiempo para ser arreglado y no para producir historias válidas de  un Sprint?. El autor propone varias cosas, pero parece que opta por bajar el factor de rendimiento del equipo lo suficiente como para que puedan abordar estas tareas de mejora, es decir, aceptan menos historias en el Sprint.

¿Qué hacer si el proyecto es grande y necesita muchos desarrolladores?. El autor dice haber probado con un equipo de Scrum grande y con varios más pequeños. Al final la solución buena según él es hacer equipos pequeños (de entre 3 y 10 desarrolladores).

Y si hay varios equipos Scrum en el mismo proyecto, ¿cada uno a su bola? ¿Sprint sincronizados? ¿Un sólo dueño de producto o uno por equipo?. Entre las soluciones del autor, parece que opta por un sólo dueño de producto, Sprint sincronizados de forma que la demos sean el mismo día, la planificación también pero solo par repartir las historias entre los equipos, luego cada equipo hace su planning poker. Las reuniones diarias deben hacerse a diferentes horas, de forma que el jefe de producto pueda acudir a todas reuniones de todos los equipos si quiere, etc, etc. Otra ventaja de esto es que al terminar cada Sprint se pueden intercambiar miembros entre los equipos, partir un equipo más grande en otros más pequeños o juntar dos equipos en uno.

¿Y qué hacemos con los que llegan tarde a la reunión diaria?. Elegir una hora buena para todos y si los tardones son habituales, lo típico de echar una moneda a un fondo común o traer "bollitos" para todos.

¿Y si el equipo está distribuido geográficamente?. Messenger abierto todo el día, web cams, etc, etc y todo lo posible para facilitar la comunicación. Habla incluso de poner web cams permanentes, de forma que todos puedan verse a todos en cualquier momento.

En fin, lo dicho, todo un abanico de problemas y posibles soluciones. El libro es ameno de leer y no se hace en absoluto pesado.

 

Mar 28

He leído “Getting things done”, de David Allen

Gettings things done

He leído "Getting things done" de David Allen, el famoso método GTD para organizarse.

La lectura me  ha resultado un tanto extraña. Los primeros capítulos me han parecido estupendos. Nos cuenta en plan teórico cuales son los problemas que tenemos para organizarnos y trabajar con eficacia y nos cuenta, también en plan teórico, cual es la forma que propone para remediarlo. Podemos estar más o menos de acuerdo con lo que cuenta, pero en mi caso sí es cierto que los problemas que menciona son los problemas que me impiden muchas veces hacer las cosas. En otros casos no, soy vago por naturaleza y si el trabajo no me resulta entretenido, tiendo a no hacerlo y eso no lo menciona ;-)

La segunda parte me ha parecido más aburrida. Entra ya en el detalle práctico de cómo aplicar su método, pero para mi gusto se extiende demasiado, contando/reafirmando una y otra vez los conceptos que explicó en los primeros capítulos sin aportar realmente nada nuevo, al menos, a nivel conceptual. Por ejemplo, dice que para aplicar su método, debemos aplicarlo a todas las facetas de nuestra vida (trabajo, casa, aficiones, recados, etc) y por ello, para empezar a aplicar su método …. ¡¡ debemos emplear entre una y dos semanas a organizarlo !!. Claro, lo primero es hacer una lista de todo lo que nos preocupa, aunque sea mínimamente, así que empieza por meter en esa lista desde los proyectos de trabajo …. hasta el cuadro que tenemos colgado en el pasillo de casa y que no nos gusta. Y luego hay que coger todas esas cosas, una por una, para ver qué hacemos con ella. Efectivamente, no me extraña que necesitemos una o dos semanas.

Bueno, ahí va mi resumen del libro. No voy a centrarme en las consabidas listas de acciones, acciones siguientes, contextos y lo que encontramos en cualquier resumen por ahí. Iré más que nada a lo que me ha llamado la atención, el "fondo" del asunto.

El problema principal es que habitualmente tenemos los problemas en la cabeza y son muy variados, desde cosas de trabajo realmente estresantes hasta pequeños detalles de la vida cotidiana como "debería revisar el coche".  Tener todo esto en la cabeza hace que no nos acordemos de todo en el momento adecuado y que cuando estamos haciendo algo estemos preocupados pensando en otras cosas pendientes, por lo que no somos todo lo eficientes que deberíamos.

La solución, apuntar todo esto, absolutamente todo lo que tengamos en la cabeza (problemas, cosas que tenemos que hacer, ideas, etc) en una lista. En realidad el autor habla de una bandeja de entrada en la que podamos poner físicamente cosas, notas, papeles, etc. Debemos tener además esa lista más o menos siempre a mano de forma que cuando se nos ocurra algo, podamos apuntarlo inmediatamente. Debemos apuntar absolutamente todo, de forma que confiemos en que esa lista tiene todo y así nuestra mente pueda "descansar" y no pensarlo.

El segundo gran problema es que estas listas suelen ser listas de problemas o cosas que no están totalmente claras, así que nuestro trabajo consiste en revisar esa lista periódicamente y decidir, una por una, que vamos a hacer con cada una de esas cosas. El objetivo es vaciar esa lista de cosas e ir creando otra lista con acciones concretas a hacer. El proceso y las reglas son las siguientes

  • Coger los item de la lista uno por uno, en orden y sacarlo de la lista, no se puede volver a dejar ahí.
  • Decidir si ese item es simplemente información que nos interesa o puede interesar. Tenemos entonces que tener un archivo donde podamos guardar información.
  • Decidir si ese item requiere que hagamos algo. Hay que decidir cosas concretas y exactas para hacer. Por ejemplo, "debería revisar el coche" debe convertirse en "llamar al taller patatín para pedir hora/precio". Si extraer la lista de cosas a hacer requiere mucho tiempo o pensarlo en profundidad, la siguiente tarea a hacer es "sacar lista de acciones a hacer con esto".
  • Si lo que hay que hacer se hace en menos de dos minutos, hacerlo directamnte. Si no, ponerlo en una lista de cosas concretas a hacer. Lo de dos minutos es el tiempo estimado que te puede llevar archivar algo que tienes que hacer para procesarlo luego. Si tardamos más en archivarlo y recuperarlo luego, mejor hacerlo ahora.

Y ya está, cuando hagamos la revisión de la lista de cosas que nos preocupan, debe quedar vacía y en su lugar tendremos una lista de cosas concretas para hacer. La lista de cosas que nos preocupan volverá a ir teniendo más cosas según nos vayan llegando o se nos ocurran. Las apuntamos hasta la siguiente revisión que haremos con periodicidad.

Finalmente, hay un tercer punto muy importante y es el que da lugar a lo de siguiente acción, algún día/tal vez, contexto, etc. El punto importante es que para usar realmente este sistema debemos hacerlo fiable y cómodo. Ello implica que debemos organizarlo de forma que tengamos seguridad de que está todo y que vamos a encontrarlo cuando lo necesitamos. Y de ahí sale todo lo demás.

  • Debemos tener un calendario con las citas o cosas que hay que hacer en fechas fijas. Aquí insiste mucho el autor en que sólo debe apuntarse aquello que sólo se pueda hacer ese día (una cita con el dentista, una reunión ya fijada, etc). Nunca debemos poner el día que una tarea tiene que estar acabada o la lista de tareas que queremos hacer ese día.
  • Las acciones debe estar claramente partidas en acciones que podemos hacer en cualquier momento y acciones que no podemos hacer porque estamos a la espera de algo. Esto nos permite, cuando tenemos tiempo para trabajar, revisar una lista más reducida de cosas que realmente podemos hacer en ese momento.
  • Las acciones tienen que estar clasificadas por un contexto en que podemos llevarlas a cabo. Acciones que se hacen con teléfono, que se hacen teniendo internet, que se hacen teniendo ordenador, que se hacen en casa, que se hacen cuando estamos de compras o de recados, etc. De esta forma, cuando tenemos un rato para trabajar, podemos mirar la lista concreta de cosas que podemos hacer con los medios disponibles.

Todo el sistema (cosas que nos preocupan, acciones, contextos, contenido de las listas, acciones en espera, etc) debemos revisarlos periódicamente para reorganizarlo y asegurarnos que todo el sistema está completo y actualizado. Debemos hacerlo con la frecuencia necesaria como para que confiemos en su estado.

Y aunque hay más cosas en el libro, creo que esto es lo realmente importante: Apuntar todo, decidir acciones concretas y tenerlas perfectamente organizadas para en cada momento y circunstancia, saber qué podemos hacer y asegurarnos que no se nos olvida nada.

Mar 14

Clean Code

clean codeMe acabo de casi terminar "Clean Code", de Robert C. Martin. Posiblemente lo he leído muy tarde, puesto que casi todo lo que se cuenta ya me sonaba de haberlo leído en otros libros o resúmenes, por lo que no me ha aportado nada especialmente nuevo.

Trata principalmente de cómo hacer un código legible para otros programadores, de forma que no necesiten gastar mucho tiempo navegando por él para entenderlo y puedan abordar fácilmente las posibles modificaciones o mejoras que tengan que implementar.

En los primeros capítulos nos cuenta las reglas más o menos conocidas por todas: nombres largos de clases, métodos y variables, lo suficientemente descriptivos, tratar de que no sean necesarios los comentarios por el código lo suficientemente claro y eliminarlos, evitar listas interminables de parámetros en los métodos prefiriendo realizar más métodos con nombres más descriptrivos pero con menos parámetros, etc, etc. Una regla si me ha llamado especialmente la atención y es la de tener las clases a distintos niveles de profundidad en la lógica del programa, es decir, debe haber clases de alto nivel con vocabulario muy cercano al usuario y clases de más bajo nivel con vocabulario muy cercano a los programadores pero, lo más importante, es no mezclar ambos vocabularios en una misma clase.

La segunda parte del libro es muy farragosa. Pone código real de ejemplo sacado, por ejemplo, de Fitnesse, JUnit, … y se dedica a mostarnos, paso a paso y con detalle como se puede ir mejorando ese código a base de refactorizaciones pequeñas para dejarlo más entendible. Lo realmente importante de esta parte no son los pasos que se van dando en sí, aunque siempre se aprende algo de alguno, sino el hecho de que el código se deba refactorizar no sólo para evitar duplicidades en él o reorganizarlo de otra manera mejor, sino símplemente por el hecho de hacerlo más entendible. Como el autor dice, "el programador que da su código por finalizado cuando funciona no es  un buen programador. El buen programador dedica tiempo a arreglar su código para que sea entendible por otros". Y por entendible se entiende que otro programador pueda entender qué hace el código sin tener que andar entrando en todas y cada unade sus clases y métodos.

En cuanto a la tercera parte… me la he saltado. Tras el cansancio de la segunda y ver que empezaba a meterse con problemática concreta de determinados códigos (Threads en concreto), me dio la pereza y pasé a otro libro.

Sep 02

¿Enseñanza gratuíta? No hay tutía

Nos salimos en este post de lo que es programación para comentar una cosa que me ha llamado la atención desde hace mucho, la expresión "no hay tutía". Sí, "tutía" se escribe todo junto y no tiene nada que ver con "tu tía", la hermana de tu padre o madre.

atutía (también tutía) era una especie de ungüento medicinal hecho con óxido de zinc y otras sales minerales que con el tiempo empezó a considerarse como un remedio universal para cualquier tipo de enfermedad. La expresión "no hay tutía" se usa en la actualidad para indicar que algo no tiene remedio o solución.

http://es.wikipedia.org/wiki/Atut%C3%ADa

Y aprovecho la salida de tema de este post para comentar algo que tampoco tiene nada que ver ni siquiera con lo que acabo de escribir : ¡¡ 600 € en libros de texto !! para mis dos hijas (material escolar y libro de biología y geología, que no quedaba, excluidos). No me extraña, cada asignatura tiene dos libros, el de teoría y el de problemas. Cada libro vale unos 30€ de media,  aunque no sea más que un "cuadernillo" de unas 100 hojas (tapas plastificadas, papel satinado, a todo color, etc, etc). Así que suma ¿7 asignaturas? incluida "educación física" que también tiene libro, a dos libros por asignatura y unos 30 € por libro … y tienes lo de una de las niñas, falta la otra.

Menos mal que la enseñanza es gratuita.

Jun 23

Test Driven Development by example, de Kent Beck.

 

Aprovechando mi puente de cuatro días (fiestas locales de la ciudad en la que trabajo), me he leído "Test Driven Development by example", de Kent Beck. El libro se lee rápido, ya que hay poco texto en cada hoja, mucho código de ejemplo, mucha hoja en blanco para que pongas tus anotaciones y, sobre todo, porque al estar en inglés, me he saltado alegremente todo lo que no he entendido ;-)

De todos son conocidos los tres famosos pasos que hay que seguir con TDD

  1. Escribir un test automático de prueba y ejecutarlo para ver que falla.
  2. Hacer el código mínimo necesario para que el test pase.
  3. refactorizar el código.

Sin embargo, es necesaria la lectura de un libro como este (o aprender de alguien con experiencia) para poder entender qué significan exactamente estos pasos y cómo seguirlos de forma eficiente. Paso a continuación a detallar algunas de las conclusiones prácticas a las que te lleva la lectura del libro.

¿Cuánto debemos avanzar cada vez?

Siguiendo los tres pasos anteriores, podemos irnos a dos extremos. Por un lado, podemos hacer un test tonto, que nos lleve un minuto hacerlo. Luego podemos hacer el código para que pase ese test, que nos lleva otros dos minutos, y luego el refactor, en otros dos minutos. Al final del día podemos haber escrito doscientos tests y docientos trozitos de código y apenas haber avanzado en nuestro proyecto. El otro extremo es pasarnos dos días haciendo un test, una semana para el código de ese test y otra semana para hacer el refactor.

Según el libro, ni lo uno ni lo otro, hay que llegar al punto justo. ¿Y cual es ese punto?. Somos nosotros los que debemos decidirlo en función de nuestras "sensaciones" al ir programando. Los test y el código que hagamos no nos deben resultar demasiado triviales de forma que nos de la sensación de estar perdiendo el tiempo. Sin embargo, si deben ser del tamaño justo para que no nos cueste demasiado pensar el código que tenemos que hacer. Debemos ser capaces de hacer con cierta facilidad el código necesario para el test, sin que nos lleve más de, digamos, media hora conseguir que el test pase.

Si el código que hacemos para cada test nos resulta demasiado trivial, podemos hacer test un poco más grandes. Si el código para el test que estamos haciendo nos empieza a dar que pensar, no estamos muy seguros de cómo hacerlo o si va a funcionar a la primera, debemos hacer test más pequeños. Por ejemplo, si hacemos un test para un método suma, podemos implementar fácilmente el método. Si hacemos un test para un método recursivo de factorial, los más experimentados o con mejor cabeza para la programación pueden hacerlo directamente, pero los más novatos quizás necesiten hacer primero un test para el caso trivial e implementarlo, luego un test para otro número e implementarlo, etc.

De alguna forma, el libro da a entender que tenemos que tender más al ensayo y error con los test que pasarnos ratos largos pensando cómo implementar algo. Una buena medida de que debemos empezar a hacer test más pequeños y menos código en cada paso es cuando los test empiezan a sorprendernos con fallos inesperados, es decir, cuando ya no estamos realmente controlando la situación.

Centrarse en un test cada vez y hacer sólo lo necesario para este test

Este es quizás uno de los puntos que más fácilmente nos podemos saltar. Si hacemos un test y nos ponemos a hacer un código, es muy fácil que nos salgan situaciones o código auxiliar que necesitemos y nos pongamos a hacerlo en condiciones.

Por ejemplo, imagina que para pasar un test que requiere buscar un Alumno en una lista, vemos que necesitamos implementar el método equals() en la clase Alumno, que ese método equals() requiere un código algo rebuscado y además deberíamos implementar el método hashCode() que nos aconseja java siempre que implementemos el equals(). Es muy fácil que nos desviemos de nuestro test para hacer ese equals() y ese hashCode() lo más completos posibles y nos olvidemos temporalmente del test que nos ocupa. O quizás, haciendo el código usemos un método ya hecho y descubramos que ese método necesita un arreglo porque hay un caso que no contempla o debería hacer algo más. Es fácil que ahora nos pongamos a arreglar ese método.

Según el libro, no debemos hacer eso. Debemos implementar únicamente un equals() y/o hashCode() mínimo que nos permita pasar el test lo antes posible, incluso aunque devuelva directamente true o false y un hashCode cero, si con eso basta para que pase el test. Una vez que pasa nuestro test, podemos dar la siguiente iteración y hacer un test para el método equals() y entonces hacer una implementación correcta de equals().

Y la mejor forma de hacer esto y que no se nos olvide después y que nos sintamos cómodos haciendo esas "chapuzas" temporales, es tener un papel al lado del teclado en el que apuntemos los test que creemos que debemos  hacer más adelante. Si tenemos que hacer un equals() en condiciones, apuntamos en el papel que tenemos que hacer un test de equals() de la clase Alumno, escribimos ahora un equals() con la implementación mínima necesaria para que funcione el test en el que estamos trabajando, y nos olvidamos del equals() hasta que le toque el turno. Si tenemos que arreglar aquel método que hemos descubierto, pues apuntamos hacer un test para ese método y no lo tocamos ahora, nos centramos en el test que estamos actualmente trabajando.

Dejar que TDD nos vaya llevando al diseño más simple

Según TDD, debemos hacer en cada momento el código más simple posible que haga pasar el test. En el refactor, según el libro, debemos sobre todo trata de eliminar repeticiones (DRY, Dont repeat yourself o "no te repitas", para los amigos) y es precisamente en este paso de refactor, donde debemos "complicar" nuestro diseño sólo lo justo para evitar esas repeticiones. Veamos esto con un ejemplo concreto.

Imagínate que uno de nuestros test dice que al jefe le podemos fijar el sueldo. Hacemos un test que a la clase Jefe le pone un setSueldo() y comprueba que getSueldo() devuelve el sueldo que hemos pasado. (sí, ya sé que es muy tonto y que este tipo de cosas ni siquiera merecen la pena ser testeadas). Bueno, hacemos nuestra clase Jefe y ese par de métodos tontos y el test pasa.

Ahora, el siguiente test nos dice que podemos hacer lo mismo con un currito. Hacemos el test, hacemos la clase Currito y le ponemos los dos métodos de marras. Los test pasan, pero ahora toca refactorizar. ¿Código repetido?. Sí, las dos clases enteras, lo único que cambia es el nombre. Tal cual tenemos ahora, deberíamos hacer una clase Empleado con todo el código de setSueldo() y getSueldo() y BORRAR las clases Jefe y Currito. Sí, borrar, no hacer herencia, ni interface común ni nada parecido. Ahora mismo no hay nada que distinga a Jefe de Currito y el diseño más simple es tener una única clase con el código común (todo el código) para ambos tipos de personajes. No debemos dejarnos llevar en ningún momento por nuestro entusiasmo ni nuestros bastos conocimientos de OO para mantener la clase Jefe y Currito y hacerles una clase padre Empleado. De momento, simplemente no es necesario y por tanto, no lo hacemos.

Supón ahora que un test nos pide que escribamos en pantalla el tipo de personaje que es. Si es jefe o currito. Pues bien, la solución más simple no es volver a hacer las clases Jefe y Currito. La OO nos lo pide a gritos, pero no es la solución más simple para los tres test que tenemos. La solución más simple es hacer un enumerado JEFE, CURRITO y ponerle un atributo a la clase Empleado, que puede rellenarse en el mismo constructor, con el método getTipoEmpleado() correspondiente.

Ahora, otro test hace que alguna cosa, por ejemplo, comprobar si el Empleado tiene derecho a coche de empresa, y cómo no, sólo si es jefe tiene derecho a ello. Pues bien, mientras sólo este este test, la solución más simple es poner un if comprobando en el atributo enumerado si es jefe. El método tieneCocheEmpresa() de empleado simplemente devuelve el restultado del if.

Y finalmente, piensa en otro test que también da un privilegio al jefe, como comprobar si Empleado tiene derecho a un sillón cómodo y nuevamente sólo si es jefe tiene ese derecho. La solución más simple que podemos dar en este momento es añadir otro método tieneSillonComodo() otro if del atributo … pero cuando llega el momento de refactor vemos que hay código repetido. Ese if está en dos sitios distintos. Ahora, y sólo ahora, es el momento donde TDD nos aconseja que empezemos a pensar en la existencia de dos clases separadas, la de Jefe y la de Currito, cuando empezamos a ver que el "si es jefe" empieza a repetirse en varios sitios. Y sólo si las nuevas clases Jefe y Currito tienen código repetido, debemos mantener la clase Empleado y  heredar de ella. Si dejara de existir ese código común, simplemente eliminamos Empleado y no hacemos herencia. O quizás, en este caso concreto, sea más fácil mantener una tabla de booleanos/privilegio dentro de la clase Empleado.

De hecho, uno de los ejemplos del libro es precisamente algo parecido a esto. Comienza haciendo dos clases (Dolar y Franco) y acaba descartándolas para hacer una única clase (Dinero) que tiene un atributo que indica el tipo de moneda.

Descansos frecuentes

Y el consejo que más me ha gustado del libro: Tener siempre una botella de agua a mano, de esta forma, la fisiología te obligará a tomarte descansos frecuentes … para ir al baño.