Archive for the '12081' Category

TDD y Diseño de Implementación (2)

Sunday, August 11th, 2013

Post Anterior

Vuelvo a uno de mis temas preferidos: Test-Driven Development, TDD. Veamos hoy cómo TDD promueve lo simple y el desarrollo evolutivo de nuestro software de producción, y voy referencias ejemplos propios en JavaScript/Node.js y en C#.

Recordemos el ciclo:

– Escribir el test

– Correrlo en rojo

– Escribir el mínimo código para pasar a verde

– Refactorizar

– Y así repetir con otro test

Hay quienes escriben varios tests. Yo prefiero ir poniendo un test a la vez. Cuando trabajo en un proyecto de código abierto, dejo en mi cuenta de GitHub los commits POR TEST, así pueden ver que cumplo con “put the money where your mouth is”. Como ejemplo temprano, pueden ver lo que estoy implementando en:

https://github.com/ajlopez/SharpMongo
https://github.com/ajlopez/SharpMongo/commits/master

una especie de MongoDB en memoria en C#. O pueden seguir los videos de TDD Rocks!:

http://msmvps.com/blogs/lopez/archive/2013/07/27/tdd-rocks-4-sharpbase-in-c.aspx

sobre un proyecto de ejemplo:

https://github.com/ajlopez/SharpBase
https://github.com/ajlopez/SharpBase/commits/master

Al escribir el mínimo test que pase a verde, pasan dos cosas:

– A veces, hacemos “cheating”. Cuando un método nuevo tiene que retornar null, simplemente ponemos return null en la primera implementación.

– Eso nos obliga a poner más tests, para obligarnos a que el método realmente se enfrente a otras situaciones y tengamos que comenzar a codificar lo que queremos.

– En algún momento, ponemos un algoritmo más cobertor de los casos de uso (los tests son ejemplos de cómo consumir lo que estamos armando, si quieren verlo así).

Pero no hago gran diseño de antemano. Pienso algunas cosas, por ejemplo, estoy escribiendo un intérprete Prolog en JavaScript/Node.js:

https://github.com/ajlopez/SimpleProlog

y entonces pienso: “necesito manejar átomos, variables, estructuras, tener una base de hechos, resolver variables con unificación… “. Pero si ven los tests, ellos son los que me guían a ir implementando nuevas características, y práctimente cada línea de código de producción puede ser traceada (su nacimiento) hasta la aparición de un test que me obligó a codificarla (si tienen paciencia pueden seguir la evolución de binding.current() y binding.reset() cómo fue cambiando según se presentaron casos de uso más complicados).

Por supuesto, Uds. pueden pensar el diseño más profundamente. Yo hasta ahora, en mis proyectos personales y en privados de una sola persona (yo 😉 no he tenido que hacerlo. Puedo pensar un poco el diseño en el desayuno, y luego, el resto del día dedicarme a implementar lo nuevo que quiero que tenga el proyecto. Pero si piensan el diseño en detalle: por favor, que eso no influya en el código que escriban hoy. Lo único que tiene que influir son los test de HOY, no lo que tengan en la cabeza para mañana.

Todo este flujo de trabajo nos lleva a que nuestro software sea lo más simple posible, dado los casos de uso. Trato de no agregar código que no venga impuesto por un caso de uso del software. Si alguien dice: “Ah! Pero si tal parámetro llega en nulo, hay que controlarlo y dar tal excepción”. Entonces voy, ESCRIBO EL TEST pasando el parámetro en nulo, da rojo, y luego voy y escribo el código de control del parámetro.

Alguien podría preguntar: ¿pero si te equivocás en el diseño? o ¿si viene un requerimiento que cambia la manera de hacer las cosas internamente? Bueno, TDD me da el coraje de hacer refactorizaciones quirúrgicas (así las llamo yo). Pero cuando estoy implementando el requerimiento 4, no estoy pensando “Ah! necesito tal estructura porque la voy a necesitar en el requerimiento 10”. PARA NADA. Cuando llegue a ese requerimiento, recién ahí voy a poner eso.

Por ejemplo, en el MongoDB en memoria con C# o con JavaScript, que estoy escribiendo, ES CLARO que lo que en MongoDB real es:

db.customers.find()

devuelve un cursor, bien “affiatado” a poder recorrer una colección que puede ir cambiando, que me devuelve sólo los primeros documentos y que al ir avanzando él solito se ocupa de ir recuperando lo que sigue. ¿Tengo que pensar todo eso ahora e implementarlo?

NO. De nuevo: NO. Ahora, en la implementación de JavaScript al día de hoy, sólo tengo que devuelve un arreglo. Y en la de C#, tengo que devuelve un IEnumerable de documentos, que es más como el cursor de MongoDB, pero es frágil a que otro thread vaya modificando la lista original. ¿Codifico algo ahora? NO ¿Lo tengo en el radar? Si, cuando llegue el requerimiento, escribiré los tests y haré una mejor implementación interna.

A ver, repitan conmigo la tercera ley aj de software:

No cruzar el puente antes de llegar al puente

TDD me permite cumplir fácil con eso. El cambio que implica implementar ese requerimiento: “find no me da todo de golpe, me lo da a medida que lo voy pidiendo, soporta concurrencia de actualizaciones, etc….” puede ser grande o mediano, pero TDD me da el CORAJE para ir implementándolo. Tal vez no todo de golpe. Recuerdo a Kent Beck:

Make it works, make it right, make it fast

Esta semana pasada me tocó uno de esos refactor quirúrgicos. Pues bien, el martes tenía “make it works” por la mitad, pero algunos casos de uso andaban. El miércoles tenía “make it right”, todos los casos de uso de lo nuevo andando, pero con una implementación no muy bueno. El jueves pasó a “make it right”: refactor interno para que la implementación quedara en mejor forma. Y todo eso dedicándole menos de 3 horas cada día.

En otros casos de refactorización adopto “baby steps”: ir cambiando la implementación de a poco. En vez de pasar todo a base de datos, paso una sola entidad. En vez de pasar a persistencia con base de datos, paso a una simple NoSQL, para ir avanzando sin tener un esquema duro.

Todo eso contribuye para que el sistema vaya creciendo orgánicamente, como un organismo: de a poco, y no de a saltos.

Más arriba puse como ejemplo proyectos privados con un equipo de uno: yo mismo. Lo que me cuesta convencer a un equipo de 3 a 5 personas de seguir lo de arriba. Hay que tener disciplina para aplicar TDD a todo código que escribamos. Si no se hace así, van a ver que entonces TDD a medias tiene problemas. El problema es el refactor, y el refactor quirúrgico: lo que no hicieron con TDD les va doler cambiarlo. Van a tener mucho re-trabajo. Si tienen que seguir las recomendaciones de arriba, van a tener que implementar TDD en la mayoría del código.

Una última cosa: TDD no es escribir test unitarios. A mí, a esta altura, no me importa sin son test unitarios, federales, o de color azul como un pitufo. Lo importante es escribir el software de a poco, viendo el test nuevo como un ejemplo de uso, como un desafío de un video juego que tenemos que resolver, pasando de rojo a verde. En futuro post comentaré qué es un test unitario, sobre lo que creo que hay confusión.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Introducción a TDD con Visual Studio

Wednesday, March 27th, 2013

Gracias a la gente del MUG Argentina (http://www.mug.org.ar), dí una charla de dos horas sobre cómo es TDD, con un ejemplo en Visual Studio.

Desarrollamos algunos tests, cumpliendo con el ciclo rojo, verde, refactor, sobre una Factura con Productos y Cantidades. Pueden ver el código en:

https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas

Los commits, con la evolución paso a paso, están en

https://github.com/ajlopez/TddOnTheRocks/commits/master

Mencioné algunos posts en la charla. Son mis posts sobre TDD, pero destaqué:

Escribiendo un intérprete en .NET (Parte 10) donde van a ver un caso distinto y más extenso

TDD y Diseño de Implementación (1) donde voy a escribir sobre cómo queda simple el diseño de implementación usando TDD y la cabeza

TDD como Compilador para ver cómo TDD es el compilador de estos años: nos avisa cuando algo está mal, mucho mejor que los compiladores de lenguajes tipados

TDD y Base de Datos sobre alternativas de qué hacer cuando tenemos bases de datos en nuestros tests

TDD y Baby Steps sobre ¿cómo comerse un elefante? Pedacito a pedacito

TDD y el juego del Go sobre “el sistema está en buena forma” a cada momento, listo para abrazar el cambio y los próximos casos de uso.

TDD, Test Unitarios y Mocks sobre usar mocks solamente cuando es necesario.

TDD y Casos de Uso sobre cómo ir acompañando la implementación de casos de uso con TDD. Lean el post de “Uncle Bob” No DB

Escribiendo una Aplicación usando TDD (parte 5)  sobre algunos pasos que se pueden dar con ASP.NET MVC

Para los que quieran ver cómo desarrollo partiendo de los controllers, en vez que desde el dominio de negocio, ver

Desarrollando una aplicación con TDD desde 0

donde por temas de tiempo, me salteé la evolución guiada por casos de uso. Pero ahí se ve cómo van surgiendo patrones, arquitectura, reparto de responsabilidades, pero PRIMERO LOS TESTS!

Para practicar, coleccioné algunos enlaces en:

http://delicious.com/ajlopez/tdd+codekata

Para aprender más:

https://delicious.com/ajlopez/tdd+tutorial

Para ejemplos en video:

https://delicious.com/ajlopez/tdd+video

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Entrevista y Podcast

Saturday, March 23rd, 2013

Hoy paso a comentar dos entregables que se publicaron: una entrevista, y una charla como podcast.

El año pasado, el bueno de @santiagobasulto (desarrollador de software, emprendedor, programador Python, colaborador en proyectos de código abierto) tuvo la paciencia de hacerme una entrevista en persona, acá en Buenos Aires, tomándose el trabajo de viajar desde su La Plata en un día atareado. Estuvimos charlando como dos horas (en un bar histórico de la ciudad, donde se filmó la escena del billete y el mozo, de la película “Nueve Reinas”, les dejo como trabajo para el hogar averiguar cuál es). Justamente, ese bar tiene también algo que ver con la entrevista, porque he pasado por él varias veces en las décadas que llevo de programar.

Santiago la pasó en limpio, la pueden leer en:

http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html

Algo más de contexto, lo escribí hace algo más de cuatro años:

http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx

Visiten el blog de Santiago:

http://charliedontcode.com/

Muy buena la escena de cine de donde toma el nombre (ya me imagino a @santiagobasulto cruzándose con Robert Duvall, acá en Buenos Aires, supongo que en otro bar histórico, La Biela ;-).

Y también tuve una charla, esta vez a distancia, con los buenos @roundcrisis @dvilchez, publicada hoy como podcast:

http://www.32minutos.net/?p=106

Ah! Pusieron una foto mía, debe ser la “clásica” 😉 (no me saco muchas fotos). Tratamos temas de desarrollo de software, algo de desarrollo ágil, insistí bastante sobre el tema TDD, también sobre generación de código como sistema experto, y “ver la luz”. Y hasta apareció algo de Anglish ;-).

Vean que han producido varios podcast en:

http://www.32minutos.net/

como el de Programación Funcional con el bueno de @martinsalias, o el de Node.js con @woloski, @jfroma y @theprogrammer. Hace unas semanas grabamos otro podcast, esta vez con Martin, para 32 minutos, y se conversó bastante sobre agilidad. Veremos si queda publicado en estos días. Estén atentos.

Les agradezco a los tres haberme permitido conversar y expresar algunas ideas, que pueden servir o no.

Pero lo bueno que están haciendo, es dejar entregables consumibles. Eso es importante. Internet (y la Web en particular) está permitiendo la generación de contenido y compartirlo con todos los interesados, de una forma accesible. Pienso que es una revolución tan grande como la de Gutenberg, y los primeros libros de Manuccio.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Remember the Links

Thursday, March 21st, 2013

Cuando investigo un tema, voy anotando qué recursos he utilizado, ya sea libros, notas, enlaces, etc. Es algo que he tomado como hábito, luego de adaptar una recomendación de Clifford Stoll en su libro The Cuckoo’s Egg: llevar una libreta (notebook) con lo que se hace (algo que Stoll recibió del premio nobel Alvarez). Cuando es algo que está público en Internet, desde hace años uso mi cuenta de Delicious para ir anotando esa información:

https://delicious.com/ajlopez

Y sí, también mantengo libretas (de papel) con notas, ideas y lo que fui haciendo para resolver algo.

Cada tanto voy publicado en mi blog en inglés (o en Anglish) lo que me pareció interesante compartir. Siempre pueden entrar en:

http://ajlopez.wordpress.com/category/links

Los temas que más me han importado en estos años:

Test-Driven Development
Artificial Intelligence
Node.js
CQRS
Distributed Computing
Bioinformatics
Smalltalk
Python
COBOL
Game Development
Genetic Algorithms
Socket.IO
Express
MongoDB

y mil temas más.

Aprovecho este post de recuerdo, para agregar otros posts con links de temas que no son de desarrollo de software, pero que pueden interesar:

Teoría de Categorías
Gauss
Fermat
Topología
Teoría de Números
Teoría de Grupos
Geometría
Astronomía
Historia de las Matemáticas
Matemáticas
Cálculo
Teoría de Cuerdas
Richard Feynman

y de nuevo, mil temas más.

Tantos temas interesantes, una sola vida Smile

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Charla de TDD con Visual Studio en Buenos Aires

Saturday, March 16th, 2013

Gracias al MUG Argentina podré dar en unos días una gratuita charla sobre TDD con Visual Studio:

Introducción a TDD con Visual Studio

Martes 26 de Marzo

Lugar: Auditorio del MUG, Rivadavia 1479 1er Piso, Buenos Aires.

Horario: 18:30 a 20:30 hs.

Describiremos brevemente lo que es y no es Test-Driven Development, pasando luego a escribir código.
Armaremos un dominio simple, usando TDD, y el ciclo de: test, rojo,  verde, refactor. Veremos como entonces va “creciendo” nuestro código de manera orgánica, consiguiendo un diseño adecuado a lo que se necesita.

Los tests nos guían en la construcción del software, siendo más que tests, especificaciones, ejemplos de uso esperado del software en construcción y hasta conseguimos ser más productivos y con código mantenible, evitando la sobre-ingeniería, y arquitecturas complicadas.

Es gratuito, pero hay que registrase aquí.

Ya saben que TDD es uno de mis temas favoritos. Pero ¿por qué? Porque es la disciplina de programación que pone en marco y contexto todas las demás. Si saben SOLID, patrones y “tutti li fiocci” pero no hacen TDD, será hacer lo bueno, pero no lo correcto. Será como alinear las sillas en la cubierta del Titanic 😉

No quiero aburrirlos más, ya escribí bastante en mis posts sobre TDD. Y cada día publico código que sigue TDD en mi cuenta de GitHub.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

TDD como Compilador

Wednesday, February 20th, 2013

Veamos hoy un tema que pone en perspectiva ¿para qué sirve TDD? O por lo menos, trata de responder en gran parte esa pregunta.

Todos conocemos lo que es programar en Java o en .NET. Escribimos el programa, posiblemente usando una IDE (Eclipse, Visual Studio.NET), y llegado el momento, compilamos. Los lenguajes .NET (VB.NET, C#, otros) y Java, son lenguajes tipados. El compilador nos dice cuándo nos equivocamos, ANTES de ejecutar nuestro programa. Por ejemplo, nos dice que nos equivocamos en el nombre de un método, o que escribimos mal el nombre de una clase, o que está mal el tipo del parámetro que tenemos que pasar a una función.

Eso ha sido útil por décadas. Y entonces, es fácil confundir esa solución (detectar en compilación errores), con el problema inicial (que nuestra aplicación funcione como esperamos).

Cuando pasamos a lenguajes dinámicos, como Ruby o Python o JavaScript, algunos se resienten: hey! No tenemos compilador! No podemos asegurarnos que lo que escribimos esté bien. Sólo nos damos cuenta si lo ejecutamos. Esto parece inclinar la balanza de nuestras preferencias a los lenguajes tipados con compilación.

Pero no es así. Todos los compiladores del mundo NO PUEDEN ASEGURARNOS que lo que escribimos esté bien. No pueden asegurarnos, al compilar, QUE NUESTRO SOFTWARE HAGA LO QUE ESPERAMOS QUE HAGA.

Veamos un ejemplo en concreto. Si tenemos un método llamado “incrementar” que recibe un entero, un compilador de Java o de .NET nos va a avisar sin lo llamamos con un nombre incorrecto, o si le estamos pasando un valor real o texto en lugar de un entero. Y eso es útil. PERO NO NOS AVISA NADA sobre si el método “incrementar” cumple con lo que esperamos de él. Bien podríamos tener en ese método código que en vez de incrementar una variable interna se dedica a formatear el disco C: o a borrar todo lo que tengamos en /usr/bin. EL COMPILADOR NO NOS SIRVE para afirmar que el método hace lo que esperamos que haga.

En cambio, TDD, al escribir los tests de lo que esperamos de nuestro método “incrementar” NOS AVISA cuándo las expectativas que tenemos no se cumplen. Entonces, no hay mucha diferencia entre escribir Ruby sin compilar y sin TDD y escribir C# sin compilar y sin TDD: de las dos formas, no sabemos si lo que escribimos HACE LO QUE ESPERAMOS QUE HAGA.

Es por todo eso que veo a TDD como la próxima generación de compiladores: es lo que nos asegura que lo que escribimos esté bien, NO EN SINTAXIS, sino en lo que podemos nombrar como SEMANTICA: lo que escribimos cumple con la conducta esperada.

Accesorio: por eso no tomo tanto en cuenta a los que critican a Ruby, Python o JavaScript por no ser tipados y no poder detectar errores en “compilación”. Si escribimos siguiendo TDD, no importa tanto el lenguaje que usemos: cada línea de código que agregamos está respaldada por un test, y cada test es una condición que cumplir. Cuando TDD nos avise que un test está en rojo, es como cuando el compilador nos avisa “el método inkrementar no existe”. Es más: yo diría que nos das avisos más importantes que lo que nos da cualquier compilador.

Escribir código de producción sin TDD, es como escribir un programa ejecutable, usando un editor hexadecimal sobre el archivo compilado: nada nos asegura que lo que estamos haciendo esté bien. Si quieren escribir código de producción sin TDD, bien, tengo unos folletos para jugar ruleta rusa, si les interesa 😉

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

TDD y Base de Datos

Monday, February 18th, 2013

Ya he escrito bastante en mis anteriores posts, sobre cuánto uso modelos en memoria al desarrollar un sistema. Pero ¿qué pasa cuando tenemos una base de datos? Ya sea porque llegamos al punto de necesitar usarla, o porque la base de datos ya está desde el principio del desarrollo.

Lo que he encontrado que me ha servido en esos casos es tener los tests de TDD como siempre, pero el modelo con persistencia en una base de datos local, del desarrollador. En el repositorio común al equipo debería estar claros los pasos para instalar esa base de datos (por ejemplo, un script de creación e inserción de datos iniciales). Puede que esa misma base de datos la usemos localmente para hacer pruebas manuales y demostraciones. Pero la cuestión es que los tests de TDD debería poder ejecutarse en cualquier momento, una vez o varias veces, sin verse afectado por la base de datos. Entonces, hay varias soluciones (que se pueden combinar):

– Un comando de línea que ponga a la base de datos de TDD en un estado conocido, la “well-known database”

– Tener una base de datos para TDD y otra, también local, para las demostraciones

– En los tests, una vez, al principio, tener una tarea que ponga a la base de datos de TDD en un estado conocido

– Cada test, envolverlo en una transacción y nunca hacer el commit

Con esto, se reduce la fricción de correr los tests locales.

En un servidor de integración continua, seguramente se creará la base y se cargará con los datos iniciales antes de correr los tests (de TDD u otros)

Yendo un poco más en detalle. Supongamos que nuestro sistema debe calcular la retención del impuesto a las ganancias cuando hay que pagar a un proveedor. En Argentina, puede que las reglas sean algo complejas para calcular. No sé el estado actual del tema, pero en su tiempo podía depender del servicio dado por el proveedor, de si el servicio abarcaba varias provincias (por ejemplo, un flete que comenzaba en una provincia y terminaba en otra), de lo que nos había facturado en el último mes, de si el proveedor tenía domicilio en una zona de promoción industrial o no, etc. Sea así o no ahora, me sirve como idea de base.

¿Cómo se encararía programar eso con TDD, y base de datos?

Como siempre, paso a paso, “baby steps”. Seguramente atacaríamos primero algunos casos sencillos y luego otros casos más complicados. Cuando se llegue a estos casos (por ejemplo el proveedor con promoción industrial) ponemos en la base de datos bien conocida, un proveedor X que cumpla con lo que necesitamos para el test que estamos desarrollando. Es decir, a medida que resolvemos los test, va quedando en la base (en scripts de creación con datos iniciales) los escenarios que vamos necesitando. Probablemente, un test solamente necesite crear al proveedor (en la etapa de Arrange). Si lo necesitamos a ese proveedor para varios tests, habrá refactor del test para que haya una rutina que lo cree. Pero cuando ya lo necesitamos para varias situaciones, migrará su existencia directamente a la base de datos bien conocida.

Cada desarrollador del equipo, cuando traer el último código del repositorio, podrá ver si alguien modificó los scripts de creación de la base. Y aún si no se da cuenta, al ejecutar los tests de TDD, seguramente alguno quedará en rojo, adviertiendo que algo de base ha cambiado. Toda esta forma de trabajo también sirve cuando en el desarrollo se va cambiando la estructura de la base. Y les sirve para no tener que adoptar mi consejo de modelo en memoria, si aún no se animan a esa forma de trabajo.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

TDD y Baby Steps

Thursday, January 31st, 2013

Ya saben que TDD (Test-Driven Development) es uno de mis temas favoritos. Y no sólo porque me gusta, sino porque creo que es uno de los temas a difundir para mejorar la calidad de nuestro trabajo, tanto en el código entregado como en la calidad de vida de nuestro día laboral. Soy un convencido de que el código de producción escrito SIN TDD debería estar prohibido, directamente. Y si insisto con el tema, es porque no veo que se aplique y entienda TDD, por lo menos en estos lares, Buenos Aires y Argentina. Por ejemplo, escucho por ahí:

– “TDD es más lento”, no lo veo así, es un caso de “vísteme despacio que estoy apurado”.

– “TDD no es para los programadores junior”, no, cuanto más inexperto es el programador, más va a aprender y mejorar haciendo TDD y usando el cerebro, claro 😉 TDD no produce mejores programadores, pero los hace pensar en lo que están haciendo.

– “TDD es hacer test y code coverage”, por favor, no me presenten a una persona que piense así. O que piense que TDD es aprender a hacer test unitarios, sea lo que sea que “unitario” signifique.

– “TDD es aburrido”, para mí es como un juego, cada test en verde es como superar un nivel de juego.

Una de las actividades que me nacen naturalmente cuando hago TDD, es que lo que escribo va creciendo de a poco, de a “baby steps”, de a pasos de bebé. En vez de hacer un gran salto en la implementación, si uno realmente programa con TDD va agregando poco código en cada test que se agrega. Y no se agrega código que no nazca, que no tenga una traza que lo remita a la necesidad de un test. Esto consiga que el software que vamos creando, crezca como si fuera un organismo vivo, desarrollándose de a poco. Esto trae varias consecuencias:

– Cada código agregado tiene su función específica: hacer que un test pase a verde

– No aparece código “por las dudas” o por casos de uso todavía no implementados.

– No pensamos “por adelantado”, poniendo código que todavía no necesitamos (evitamos romper YAGNI).

– No se adopta tecnología o soluciones (librerías, frameworks, base de datos, etc… ) hasta el momento en el que REALMENTE se necesitan.

Y algo menos evidente:

– El código que vamos armando es pasible de refactorización en cualquier momento

– Y aún puede haber más que refactorización, sino también cambiar algo de nuestro diseño, sin grandes “dolores”

Ahora les advierto: no se puede aplicar todo esto con TDD, si parte del código QUE ESCRIBIMOS NOSOTROS no lo hacemos con TDD. Porque entonces vamos a "sufrir" cuando lleguemos un día a necesitar refactorizar, o rediseñar, y entonces la parte del código que habíamos escrito SIN TDD nos va a pesar y nos va a complicar ese paso de refactor o de rediseño.

Me gustaría mostrarles un ejemplo, pueden ver los posts y series:

TDD Paso a Paso

Escribiendo una aplicación con TDD

Escribiendo un Intérprete en .NET

VAN en Alt.NET Hispano: Desarrollando una Aplicación con TDD

con video en Desarrollando una aplicación con TDD desde cero con código en https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp

y mis posts de TDD.

Pero cada día, en mi cuenta de GitHub, voy haciendo commits por test, así que pueden entrar a algún proyecto y ver cómo va evolucionando. Por ejemplo, hoy voy a empezar a codificar SimpleKeeper (una especie de ZooKeeper pero en Node.js). Pueden en cualquier momento entrar a ver la lista de commits e ir revisando si cumplo o no cumplo con TDD y “baby steps”.

Algo muy interesante, y relacionado con este post, es:

Kent Beck’s Four Hats

Controlling the size of your checkout is a valuable coding skill. You should be able to take small, baby steps, and check-in at any time. There are a number of benefits. If you check-in frequently the merge to source control becomes trivial. Your colleagues won’t get annoyed, because that change which they need is never far away. Most importantly you are in control of your work.

Vean ahí los cuatro sombreros de Kent Beck.

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

SimpleTags (1) Primeras Ideas

Monday, January 28th, 2013

Hace más de una década, escribí un sitio que sirvió luego de base para mi sitio personal. Estaba basado en tener items heterogéneos (enlaces, páginas tipo wiki, etc…) clasificados en categorías. Las categorías se disponían en árbol, y se soportaba el concepto de enlace simbólico: una rama de una categoría podía ser un puntero a otro rama del árbol (como cuando tienen enlaces simbólicos en la jerarquía de directorios de un sistema de archivos). Un item se podía colocar en más de una categoría. Pero después de conocer a Delicious y al tiempo a Gmail, ahora prefiero organizar los items usando tags (en Gmail son las “labels”). Y en vez de tener categorías y un árbol de categorías, pienso que es más flexible tener conjuntos basados en predicados de tags. Por ejemplo, lo que sería en mi viejo sitio la categoría Programming –> C#, sería ahora todos los items con tags “programming”, “c#”. Algunas veces, necesitaría en vez de simples tags, un par key-value, como “author:unclebob”, o “project:storm”.

Así que hace unos días, puse manos a la obra, y comencé un nuevo proyecto, escrito en JavaScript/Node.js, llamado SimpleTags:

https://github.com/ajlopez/SimpleTags

Leo en el README.md:

var itemId = engine.createItem('http://nodejs.org', [ 'nodejs', 'javascript', 'engine', 'programming' ]);

An item has

  • data: Arbitrary value you supplied
  • tags: An array of tags. A tag could be a non-empty string or an object with only one property with non-empty value.

Once created, the item has an associated id, supplied by the engine.

El proyecto tiene un modelo en memoria. Un conjunto de tags puede ser asociado a un item de datos arbitrario. Ese item podría ser los datos de un proveedor o factura, pero seguramente sería más usual tener como dato asociado el id del proveedor o la factura, y que otro sistema se ocupe de recuperar la entidad. Entonces, el dato arbitrario puede ser un id para una tabla en nuestra base de datos, o una URL, o lo que querramos y necesitemos. Lo importante es: asociar un dato arbitrario con un conjunto de tags, y recuperar items con predicados sencillos de esos tags.

Piensen como ejemplo: podemos tener una gran colección de enlaces, y usar SimpleTags para organizarlos. O documentos, fotos, multimedia. Podemos usar los tags en diferentes entornos. Es una idea poderosa y simple que se puede aplciar en varios dominios y escenarios.

Pienso agrega un sitio web como ejemplo concreto, donde se pueda agregar URLs y asociarles tags, y luego definir categorías o conjuntos, usando predicados. Luego de ese ejemplo general, podría implementar algo más concreto, como una lista de cosas para hacer, con tags, o una lista de tareas pendientes/completas por proyecto, iteración, estado, persona asignada, etc… Usé hace un tiempo un sitio así en un cliente para llevar el estado de los proyectos, y me resultó muy útil y flexible.

Podría ser una excusa para aprender más de Express, o para hacer “dog fooding” y consumir mi proyecto web SimpleWeb. En todo caso, me divierto como loco 🙂

Como es usual, escribí SimpleTags usando TDD, pueden consultar el log de commits.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Computación en el Recuerdo (1) Requisitos de un Lenguaje de Programación

Friday, December 21st, 2012

En un mundo con Internet, tablets, lenguajes funcionales y cloud computing, es bueno volver la vista atrás y ver todo en perspectiva. Hoy, en mis lecturas, me encuentro con este fragmento:

…definimos ahora los requisitos de un lenguaje de programación para problemas originados en los campos de la economía y de la administración.

1. Debe ser posible indicar cómodamente en qué unidades periféricas se encuentran los diferentes archivos, y cómo los registros se almacenan físicamente en el medio de almacenamiento, por ejemplo cuántos registros forman un bloque en cinta magnética.

2. Debe ser fácil describir la transferencia de registros entre la memoria central y las unidades periféricas, por ejemplo la lectora de tarjetas perforadas, la impresora de líneas y la memoria auxiliar.

3. Debe ser posible referirse a los datos individuales de un registro. Por lo tanto, debe ser posible describir las propiedades de los datos incluidos en el registro y cómo se agrupan para formar un registro.

4. Debe ser posible presentar los datos de salida, de modo que sea fácil su lectura.

5. Es necesario que se puedan describir operaciones aritm^ticas con números y operaciones lógicas, por ejemplo comparación de números. Además, también debe ser posible trabajar con datos no numéricos, por ejemplo nombres.

Concluye:

El COBOL satisface todos estos requirimientos

Fuente: Sección 2.3 del libro “COBOL” de Torgil Ekman y Kenneth Nilsson, publicado acá en Argentina por la editorial El Ateneo. Lo leía a fines de los setenta, principios de los ochenta. Y encontro guardadas, dentro de algunas páginas, algunos de mis primeros cursogramas 😉

Estoy por comenzar un code-kata (espero que este fin de semana): un intérprete/compilador a JavaScript (browser y Node.js), de COBOL. Cosas veredes, Sancho!

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez