Archive for the '11699' Category

El valor de TDD (Test-Driven Development) (1)

Saturday, July 5th, 2014

Siguiente Post

En estos últimos años he estado practicando deliberadamente TDD (Test-Driven Development) y trabajo en proyectos personales usando el flujo de trabajo de esta disciplina casi todos los días (ver mis posts de TDD y los commits en GitHub) Y también he trabajado en proyectos profesionales, con y sin TDD. Y luego de tanto código y proyectos, pienso que ya tengo un panorama de cuáles son los valores que agrega TDD a un proyecto que tenga desarrollo de software y cuáles son los problemas que podemos tener si no usamos TDD..

Primero, hay que recordar que un proyecto profesional puede ser más que programar código: he escrito que un proyecto BUENO es el que resuelve un problema (ver Un Buen Proyecto). No es solamente programar código, y menos programar código como nos parece o nos gusta. Lo importante es solucionar el problema que tiene quien nos contrata como equipo o como desarrollador individual.

Hecha esa aclaración ¿que es lo que vi de más valor siguiendo TDD, tanto en proyectos personales como profesionales? El primer punto de valor que veo como evidente, espero poder transmitirles el concepto, es:

TDD NOS EMPUJA A LA SIMPLICIDAD EN EL SOFTWARE QUE CONSTRUIMOS

Como cada vez que escribimos un test tenemos que pasarlo de rojo a verde con el código más simple, entonces esa simplicidad se va transmitiendo a lo que estamos construyendo.

Antes de seguir con el tema simplicidad, recordemos que no es sólo hacer TDD. Por ejemplo, tengo en gran importancia implementar casos de uso (ver TDD y Casos de Uso). Sin una serie de casos de uso a implementar, corremos el peligro de salirnos del carril y escribir algo que nos parece lindo, interesante, pero no soluciona el problema que tenemos que atacar en el proyecto.

Entonces, con TDD y guiado por los principales casos de uso, vamos diseñando un software. TDD es un proceso de diseño de software, no de escribir tests o de testing. TDD nos lleva a construir un software lo más simple posible, y los casos de uso nos guían hacia donde realmente esta el problema a resolver. Me gusta decir que aplicamos “baby steps”, hacia un diseño incremental de la solución (ver TDD y Baby Steps). No digo no hacer diseño de antemano: hago algo de diseño,  pero en la servilleta del desayuno, y apenas un poco. No pongo diseño imaginado en el código HASTA QUE NO LLEGUE EL TEST que lo amerite.

No olvidarse del otro importante paso: el refactor. Es ahí donde vamos a poner lo que conocemos para mejorar el código. Y es notable: TDD, como flujo de trabajo, nos va enseñando sobre diseño de código, de forma incremental. Al llegar un nuevo test, podemos ver que lo que habíamos escrito hasta entonces no sea lo óptimo, y refactorizamos la implementación interna. En este paso puede aparece la aplicación de patrones. Y eso es bueno: aparecen en un contexto, el de refactorización, no aparecen “del aire” o porque se nos ocurre a nosotros que hay que aplicar tal patrón. Recordemos que unos de los atributos de un patrón de software es el contexto donde se aplica. En la etapa de refactor podemos descubrir o poner de manifiesto ese contexto y ahí entonces reción aplicar el patrón. Si hacemos diseño de antemano, podemos caer (y lo he visto suceder) en la “patronitis”: agregar todos los patrones habidos y por haber, porque pensamos que son la mejor práctica. Hacer eso es una variante de “optimización prematura es la madre de todos los males”. Lo que nos va a enseñar TDD es que no hace falta pensar todo de antemano, rompiendo YAGNI. Lo que vamos creando con TDD en general va estar en “buena forma” para adaptarse a los nuevos casos de uso y nuevos tests que aparezcan.

Y aca esta el otro valor que agrega, paralelo a la simplicidad: no solamente el código va creciendo con la simplicidad necesaria, sino que tambien esta en su mayor parte ajustado a lo que nuestros tests piden, no a lo que nosotros queremos o imaginamos que necesita tener nuestro código. El diseño del software en construcción, de esta forma, es como la confección de un traje a medida, que va calzando perfecto en cada iteración a lo que necesitamos implementar.

Para que no todo sea cháchara en este post, pongo un ejemplo concreto, que ya he expuesto en otros posts (ver, por ejemplo, Desarrollando una Aplicación usando TDD). Supongamos que necesitamos devolver una lista de nuestros productos por categoría, digamos, en una API. ¿Qué hacemos en el controlador? He visto muchas veces que ya al primer test se le coloca un repositorio “mockeado” porque, claro, necesitamos el patrón repositorio ¿no?. Así nace la “paternitis”. NO: si somos consecuentes con el flujo TDD, lo más simple es ir entregando al controlador…. un LISTA DE PRODUCTOS. Solamente cuando tengamos más casos de uso, y veamos que la lista de productos la necesitamos en otros lados, vamos separando su existencia en otros componentes. He visto también que llegado al primer o segundo test, o aún antes, ya se está diseñando la base de datos para tener una tabla de productos y otra de categorías. Yo pregunto ¿quién, en qué el test, pidió eso? ¿qué test puso persistencia en el tapete? Muchas veces, NINGUNO. De nuevo, hay que ir implementando lo que nos pide el test, nada más, no hay que agregar nuestra propia “bajada de línea”, “ruptura de YAGNI”, como cuando pensamos “vamos a necesitar repositorio, vamos a necesitar persistencia” y entonces, necesitamos YA ponerlo y YA ponerlo como mock y así. Ese es el camino de romper la simplicidad de la que hablo.

De esta forma, el software que tengamos en construcción, crece como un organismo: de a poco, de forma controlada.

Seguiré con el tema del valor que agrega TDD, en los próximos posts: aumenta la calidad de código, permite la evolución y la adaptación al cambio, permite reducir la cantidad de bugs, permite arreglar los bugs detectados de forma más rápida, deja al proyecto en buena forma para que lo tomo otro equipo, etc.

Nos leemos!

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

 

ClojSharp Implementando Clojure en C# (1) El Proyecto

Thursday, June 26th, 2014

Desde la década pasada que me interesa Clojure, y desde siempre Lisp. Clojure está implementando sobre la máquina virtual de Java, pero también está implementado sobre .NET (que recuerde, usando Dynamic Language Runtime). La versión de Java compila a bytecodes Java. También hay una versión para JavaScript, llamada ClojureScript. La comunidad es muy activa, y ha traido un aire de renovación dentro de Java. Tiene características como la inmutabilidad de sus estructuras orientadas al trabajo en múltiples hilos evitando los problemas de lockeo y concurrencia. Tiene Software Transactional Memory, usando refs y transacciones,  pero ha sido menos usada por lo que veo. Han surgido frameworks web, y tiene un manejador de proyectos y dependencias Leiningen muy bien armado. Algunos enlaces en mis posts de Clojure.

Para practicar TDD (Test-Driven Development) y C#, he estado armando un intérprete (no un compilador a bytecodes), en .NET. Ver el proyecto en:

https://github.com/ajlopez/ClojSharp

El estado actual:

Tiene una librería de clases, otra de tests, y ya apareció un REPL (Read Eval Print Loop) sencillo como programa de consola.

En Lisp, una expresión se compone de un verbo y argumentos, expresados en una lista entre paréntesis. Por ejemplo una lista que al evaluarse devuelve la suma de 1, 2 y 3:

(+ 1 2 3)

Acá + (el signo más) es un símbolo que apunta a lo que en Lisp se llama una form, algo que recibe argumentos, opera con ellos y devuelve un resultado. Los argumentos que recibe un form en general se evalúan antes de serle entregados:

(+ 1 (- 3 4) 3)

Acá el primer argumento es una constante que vale uno, y el segundo argumento, antes de llegar al form de suma, ya es evaluado y vale –1 (menos uno). Pero hay forms que no necesitan evaluar los argumentos. Los reciben, digamos, en crudo. Se llaman special forms. Tengo implementados:

Y también tengo implementadas algunas forms (no especiales) como primitivas en C#. Muchas podrían ser implementadas en Lisp mismo, pero por ser tan básicas las implementé directamente en C#, usando TDD como es usual:

Próximos temas: la implementación de Machine, el Context, como se usa Parser y Lexer, más sobre evaluación de expresiones. Y mil temas más, como estructuras inmutables, macros, recursión optimizada, etc.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

RubySharp, implementando Ruby en C# (3)

Saturday, June 21st, 2014

Anterior Post

En RubySharp puedo definir nuevas funciones (en realidad métodos del objeto actual) e invocarlas. Hay algunas funciones que ya están predefinidas en C#:

Veamos primero que toda función tiene que cumplir con la interfaz:

public interface IFunction
{
    object Apply(DynamicObject self, Context context, IList<object> values);
}

donde cada función, al aplicarse, recibe el objeto sobre la que es invocada como método, el contexto de variables (locales, argumentos, otros… ) actual, y una lista (posiblemente vacía) de argumentos.

Por ejemplo, la función puts está implementada así:

public class PutsFunction : IFunction
{
    private TextWriter writer;

    public PutsFunction(TextWriter writer)
    {
        this.writer = writer;
    }

    public object Apply(DynamicObject self, Context context, IList<object> values)
    {
        foreach (var value in values)
            this.writer.WriteLine(value);

        return null;
    }
}

Recibe: el objeto al que pertenece como método, el contexto, y una lista de argumentos. Cada uno de los argumentos ya lo recibe evaluado, y simplemente lo envía a un TextWriter, un argumento por línea. Vean que no imprime a la consola: el TextWriter se lo entregan cuando se crea esta función (veremos más adelante que se crea al crearse un objeto Machine). Esta inyección por constructor facilita el test de esta función predefinida, ejemplo:

[TestMethod]
public void PutsTwoIntegers()
{
    StringWriter writer = new StringWriter();
    PutsFunction function = new PutsFunction(writer);

    Assert.IsNull(function.Apply(null, null, new object[] { 123, 456 }));

    Assert.AreEqual("123\r\n456\r\n", writer.ToString());
}

Pero fue algo que nació no sólo de armar un test, sino de seguir el flujo de trabajo de TDD.

Veamos otro ejemplo de función predefinida, el require:

public class RequireFunction : IFunction
{
    private Machine machine;

    public RequireFunction(Machine machine)
    {
        this.machine = machine;
    }

    public object Apply(DynamicObject self, Context context, IList<object> values)
    {
        string filename = (string)values[0];
        return this.machine.RequireFile(filename);
    }
}

Esta vez, delega el trabajo de cargar un archivo de programa al objeto Machine que se le inyectó al comienzo.

Y finalmente, veamos el código de una función definida, con un cuerpo ya compilado de RubySharp:

public class DefinedFunction : IFunction
{
    private IExpression body;
    private IList<string> parameters;
    private Context context;

    public DefinedFunction(IExpression body, IList<string> parameters, Context context)
    {
        this.body = body;
        this.context = context;
        this.parameters = parameters;
    }

    public object Apply(DynamicObject self, Context context, IList<object> values)
    {
        Context newcontext = new Context(self, this.context);

        int k = 0;
        int cv = values.Count;

        foreach (var parameter in this.parameters) 
        {
            newcontext.SetLocalValue(parameter, values[k]);
            k++;
        }

        return this.body.Evaluate(newcontext);
    }
}

En este caso, se arma un nuevo contexto para que contenga a los argumentos de la función definida, con los valores que se pasaron ahora, y que recuerde igual al contexto desde donde fue definida. Observen que el contexto desde donde fue invocada (el Context context que recibe como parámetro Apply) no es usado. Hay una “closure” con el contexto en el que fue construida la función (el Context context que recibe en el constructor)

Hay más temas para explorar, como implementación de algunos comandos, la Machine que arranca todo, el REPL, etc.

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

SharpBus en C# (1) Primeros Pasos

Monday, June 16th, 2014

Ayer comencé a codificar SharpBus, un simple procesador de mensajes inspirado en algunas ideas de Mule. Ver:

http://en.wikipedia.org/wiki/Mule_(software)

http://www.mulesoft.org/what-mule-esb

Como es usual, estoy usando TDD (Test-Driven Development), tratando de ir implementando pequeños casos de uso, de la manera más simple posible. De hecho, el proyecto es un ejercicio personal de TDD. Espero que alguna vez sea útil más allá de eso. Por ahora, es un ejemplo que quiero compartir de mi flujo de trabajo.

Pueden ver el avance en:

https://github.com/ajlopez/SharpBus

Las ideas principales a implementar son:

– Hay mensajes (Message) con un contenido (Payload) y propiedades (diccionario de nombre/valor)

– Hay flujos (Flow) que procesan mensajes

– Un flujo se compone de varios elementos

Los elementos pueden encadenarse en el flujo, y pueden ser:

– Un transformador (Transformer) que toma un contenido o mensaje completo y lo devuelve transformado

– Un procesador (Processor) que toma un contenido o mensaje completo y opera sobre él, por ejemplo, tomando acciones sobre algún dominio de negocio, pero sin transformarlo

– Un productor de mensajes/contenido (Input)

– Un consumidor de mensajes/contenido (Output)

– Un ruteador (Router) de mensaje/contenido, quien decide a qué próxima rama (Branch) en el flujo se deriva el mensaje/contenido

Y un flujo puede tener ramas con nombre. También habrá elementos que puedan emitir nuevos mensajes aparte del actual, y que puedan emitirlos a distintos flujos del sistema. Los productores de mensajes deberán poder correr en hilos de ejecución (Threads), en principio. Y habrá un conjunto de hilos (Pool de Threads) para atender los mensajes que se produzcan y derivarlos a los respectivos flujos.

Un flujo puede tomar un mensaje, y devolver una respuesta (un Request/Response), o puede tomar un mensaje, procesarlo, sin devolver una respuesta a quien lo envió.

A veces, un elemento necesitará el mensaje completo (Message) y otras veces le bastará operar sobre el contenido (Payload).

Los elementos, en el mundo de Mule/Java, son objetos. Notablemente, en C#, la forma más simple de implementar, es usando lambdas. Así, que siguiendo TDD, las primeras pruebas e implementación ha salido por ese lado. Pueden ver algunos tests simples en:

https://github.com/ajlopez/SharpBus/blob/master/Src/SharpBus.Core.Tests/FlowTests.cs

Por ejemplo, para enviar un contenido y recibir respuesta, en un flujo que está vacío, basta:

var flow = Flow.Create();

Assert.AreEqual(1, flow.Send(1));

Para enviar un contenido y transformarlo, es simple:

var flow = Flow.Create()
    .Transform(x => ((int)x) + 1);

Assert.AreEqual(2, flow.Send(1));

El .Transform espera una Func<object, object> que puede proveerse en el momento con una lambda. En un Mule clásico de Java 7, tendríamos que proveer un objeto que implemente una interface donde hay un método que transformar el Payload. Tengo que pensar si vale la pena tener un .Transform tipado tipo .Transform<T> (que recibe T y devuelve T), o .Transform<T, S> (que recibe T y devuelve S).

Vean que me decidí por configurar el flujo por código. En el ambiente Mule se acostumbra más configurarlo por Spring, escribiendo un XML. Me parece que es hora de explorar esta otra forma, y ponerla como “forma primera”, es decir, como la forma sobre la que todo lo demás se podría montar. Si alguien necesitara alguna vez un DSL (Domain-Specific Language) de creación de flujos, podría implementarse teniendo esta forma por código bien diseñada.

Siguiendo TDD, todavía no tengo un caso de uso de un Message (un mensaje completo, con contenido (Payload) y propiedades (Properties, un diccionario nombre/valor). Todo lo de arriba es procesar el Payload directamente.

Próximos temas: agregar Message con Payload, la salida de mensajes, el ruteo, el armado de ramas, etc..

Nos leemos!

Angel “Java” Lopez

http://www.ajlopez.com

http://twitter.com/ajlopez

Aprendiendo ASP.NET MVC

Monday, January 6th, 2014

En estos días, se preguntó en una lista del MUG sobre recursos para aprender ASP.NET MVC. Yo aprendí de a poco, a lo largo de los años, así que sé exactamente cómo sumergirse rápidamente en el tema. Pero puedo escribir y mencionar algunos pasos y recursos.

Primero, hay que comprender que MVC viene de Model View Controller. Y en el caso de ASP.NET MVC, está claramente implementado. En lugar de tener páginas Web Form, con una parte visible de diseño y una parte de código con eventos de ida y vuelta, el esquema de ASP.NET MVC es distinto.

Cuando un usuario pide una página como /customer, el código de ASP.NET MVC rutea (de hecho, hay un ruteador) ese pedido a un método de una clase controladora. Por ejemplo, al método Index dentro de CustomerController. Luego, ese método tiene que devolver información sobre la vista que hay que mostrar. Las vistas se programan en general como HTML con código embebido, de distintas “engines”, la más popular es Razor. Una vista es algo parecido (sólo parecido) al ASP clásico de los noventas. Pero cada vista recibe lo que se llama un modelo: por ejemplo, la vista de listado de clientes podría recibir un IList<Customer> como modelo (accesible desde la propiedad de la vista Model) y podría iterar sobre el modelo para producir un resultado.

Pero es mejor tener código de ejemplo, ver el resultado de una charla que dí en el MUG:

https://github.com/ajlopez/TddRocks/tree/master/Consorcios

Donde se hicieron algunas páginas, y la lógica del dominio (simple) está en un proyecto de clases aparte. Vean que también puse tests. De hecho, la charla fue sobre cómo programar ASP.NET MVC usando TDD (Test-Driven Development). Ver mis posts sobre TDD. Por ejemplo la serie Escribiendo una Aplicación (ASP.NET MVC) usando TDD

Ver también el video que explica paso a paso el proceso, gracias a la gente de AltNet Hispano

Desarrollando una aplicación con TDD desde cero

No recuerdo dónde quedó el código de esa reunión, debe ser

https://github.com/ajlopez/TddRocks/tree/master/TddApp o
https://github.com/ajlopez/TddAppAspNetMvc

Tal vez es demasiado empezar con TDD en un tema nuevo, pero les recomiendo que una vez comienzen a dominar ASP.NET MVC, pasen a trabajar de esa manera. Puede comenzar top-down (con las vistas y primeros modelos de vistas, sin tener la lógica de negocio y el modelo de negocio), o pueden comenzar por “el medio”, armando con TDD todo el proyecto de clases donde resida la lógica y modelo de negocio.

Otro tema es el lenguaje: prácticamente todos están programando en C#. Si están con VB.NET, puede ser una buena oportunidad para cambiar de lenguaje. No es difícil, los conceptos y clases de .NET son los mismos.

ASP.NET MVC fue evolucionando. Ultimamente, tuvimos ASP.NET MVC 3, 4 y ahora 5. Lamentablemente, no son simples librerías, sino que dependen del framework .NET, y para las últimas versiones de MVC tienen que usar las últimas versiones de Visual Studio. Yo aconsejaría Visual Studio 2010 (no sé por qué, algún genio de Microsoft quitó los botones y funcionalidad de tests que había en VS 2008 y VS 2010, y en el VS 2012 hay un test explorer; por lo menos para mí, que sigo el flujo de trabajo de TDD, es bastante molesto; veré si puedo acostumbrarme). Si tienen VS 2010, iría directamente a ASP.NET MVC 4. Si tiene VS 2012, lo mismo (pero podría intentar instalar el MVC 5 si quieren). Me temo que las vistas generadas varían de versión a versión.

No hace falta, pero si quieren tener un panorama más amplio de la interfaz, pueden leer:

User Interface Patterns

Hay una explicación más detallada de lo que es ASP.NET MVC, para los que se inician en el tema, en:

An Absolute Beginner’s Tutorial on ASP.NET MVC for Web Forms Developers

No lo necesitan tanto al principio, pero si quieren ver más detalles de routing:

Routing in ASP.NET MVC 3 Tutorial

Tienen varios recursos en el sitio de Microsoft:

Learn about ASP.NET MVC

Por ejemplo:

ASP.NET MVC Overview
Learn about the differences between ASP.NET MVC application and ASP.NET Web Forms applications. Learn how to decide when to build an ASP.NET MVC application.

Hay un buen listado de recursos en

ASP.NET MVC 4 Content Map

Si tienen VS 2012, pueden intentar hacer:

ASP.NET MVC Facebook Birthday App

Bien, hay de todo, como en botica. Bastante por hoy. Aprendan MVC (que en el ambiente web ha prendido como patrón, antes que en .NET, en Python y Ruby). Algunos enlaces más, en “potpourri”:

https://delicious.com/ajlopez/aspnetmvc
https://delicious.com/ajlopez/aspnetmvc,tutorial
https://delicious.com/ajlopez/aspnetmvc4
https://delicious.com/ajlopez/aspnetmvc5
https://delicious.com/ajlopez/mvc
https://delicious.com/ajlopez/mvc,computerhistory (interesante para ver de dónde viene MVC, que no nació para la web)

Nos leemos!

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

TDD Rocks! (9) JavaScript y Node.js

Friday, November 8th, 2013

Anterior Post 
Anterior Post con JavaScript 

Ayer tuve el gusto de participar del primer meetup de JavaScript en Buenos Aires:

http://www.meetup.com/Meetup-js/

Y participé dando una charla de TDD con JavaScript y Node.js. Los slides quedaron en:

https://github.com/ajlopez/Talks/tree/master/TddJavaScript

El código que mostré quedó en:

https://github.com/ajlopez/TddRocks/tree/master/JavaScript

Lo importante a entender de la charla es:

TDD NO ES ALGO DE TESTING

A ver, repitan conmigo 🙂

TDD NO ES ALGO DE TESTING

TDD NO ES ALGO DE TESTING

TDD NO ES ALGO DE TESTING

Es un flujo de trabajo de DESARROLLO. Lo que nos dá TDD es un camino de desarrollo, donde se busca la simplicidad y el crecimiento orgánico. Y es más importante cuando trabajamos sobre código de producción, código de una aplicación desarrollada en equipo ágil, y que necesita ser entregada en tiempo y forma. El flujo de trabajo de TDD nos empuja a buscar la simplicidad, no poner más código del necesario para cumplir con los ejemplos de casos de uso (que se llaman tests). Y esa simplicidad en el código es favorable, porque terminamos haciendo aplicaciones con menos partes móviles, sin necesidad de inyectarle librerías grandes o innecesarias. Y como subproducto, tenemos un sistema que otro equipo puede modificar, y darse cuenta, gracias a los tests, qué se rompe y qué no se rompe con esa modificación. Eso igual no es lo fundamental de TDD: insisto, más importante es el flujo de trabajo que nos lleva por el camino de la simplicidad.
 

No confundir simple con fácil. Ruby on Rails es fácil, pero no es simple.

Bien, para las demos, estuve usando:
 
http://nodejs.org/ 
https://github.com/ajlopez/SimpleUnit 
http://qunitjs.com/
 
Hubo otra charla interesante
sobre http://gruntjs.com/ y http://bower.io/ dada por , pero ya era tarde y me tuve que ir.
 
Las dos charlas fueron filmadas, así que revisen el enlace del meetup para ver cuándo quedan publicadas.
 
Actualización:
 
La charla de Grunt no quedó filmada por problemas técnicos. Pero les dejo acá la charla introductoria del grupo, y la charla de TDD:
 
[View:http://www.youtube.com/watch?v=lx6a71LwDIY]
 
[View:http://www.youtube.com/watch?v=iAHxyN6oZjY]
 
Recuerden, el enlace de grupo es
 
http://www.meetup.com/Meetup-js/
 
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

Meetup de JavaScript en Buenos Aires

Wednesday, November 6th, 2013

Como habran leído por acá, o por mi cuenta de Twitter, este mes pasado, Octubre, estuve bastante ocupado con tres charlas en sendas conferencias. Ahora estoy preparando una charla para RubyConf, y espero que otra charla sea aceptada en la fundación Uqbar. Por eso, este tardío aviso: se ha formado un meetup de tema JavaScript en Buenos Aires. Ver:

http://www.meetup.com/Meetup-js/

pero que podría extenderse a otras ciudades.

Mañana jueves será la primer reunión presencial:

http://www.meetup.com/Meetup-js/events/145566692/

Creo que ya estuve en SVC, para cuando fue una meetup de Scala. Bueno, va a haber varias charlas. Yo propuse una de TDD y JavaScript y fue aceptada. Así que mañana estaré ahí con ese tema. La idea es ver lo que siempre predico, por acá con posts y videos y por allá en mi cuenta de GitHub: código de producción debe ser escrito con TDD. Y la combinación TDD JavaScript es muy buena, porque domina y pone bajo control la flexibilidad del lenguaje y la tecnología.

Espero que se entienda: TDD NO ES SOBRE TESTS. Es un flujo de trabajo de diseño de software. Es Test-Driven Development, el sustantivo central es DEVELOPMENT. Lo de tests es una forma de conseguir ese flujo. Y que se entienda: TDD nos permite empujar, “pushear” por la simplicidad, evitando arquitecturas de astronauta.

Bueno, en cuanto pueda, publicaré por acá un resumen de la charla.

También habrá dos o una compartida charla sobre Grunt, algo cada vez más usado en distintas tecnologías, ver:

http://gruntjs.com/

No digan después que les avisé… lo mío es un apostolado 🙂

Nos leemos!

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

 

Mis próximas charlas en Buenos Aires: PHP y Node.js, TDD con ASP.NET MVC, Scala

Saturday, September 28th, 2013

Los días que vienen serán de charlas para mí. El sábado que viene, 5 de Octubre, tengo en PHP Conference Argentina 2013:

PHP, Node.js y tutti li fiocci

http://www.phpconference.com.ar/php-node-js-y-tutti-li-fiocci/

Veremos qué es Node.js para un programador PHP. Programa montado sobre el engine de JavaScript V8 de Google. Ejecución en un loop, con IO asíncronico. Node.js como servidor de consola, y servidor web. JavaScript como “lenguaje manteca”, muy flexible, con mínima ceremonia de programación, similar a PHP en muchos aspectos, y diferente en otros. Ecosistema de paquetes, parecido a lo que tenemos en PHP con Composer, usando NPM, el manejador oficial de paquetes de Node.js. Veremos que en vez de tener muchas funciones, como PHP, Node tiende a tener modulos, que podemos instalar y consumir en cualquier momento.

Donde Node.js comienza a brillar, y diferenciarse de PHP, es en la atención realtime. Veremos soporte de sockets y websockets, y la importancia del asincronismo en IO. Y el precio a pagar: los callbacks, funciones a ejecutar en algún momento futuro.

Pero no queremos perder nuestro querido PHP. Entonces, pasaremos a integrar PHP con Node.js. Primer approach: PHP + browser + Node.js, sin apenas comunicación entre PHP y Node. Luego: cómo llamar a código Node desde PHP. Módulos dnode (asincrónico y sincrónico). Ejemplos (desde un simple chat, hasta aplicación distribuida). Y hacia el final… bueno, espero que alguna sorpresa, e tutti li fiocci!

Luego, el lunes 7 de Octubre en el Microsoft User Group tengo:

TDD con ASP.NET MVC

http://www.mug-it.org.ar/Event.aspx?Event=96

Describiremos brevemente lo que es y no es Test-Driven Development, pasando luego a escribir código. TDD no es testing, es el diseño de nuestro software buscando siempre la simplicidad. Esta vez partiremos desde ASP.NET MVC, creando los primeros pasos desde un diseño "top-down", guiado por casos de uso visuales sencillos (para aprovechar el tiempo). Siguiendo el "mantra": baby steps, make it works, make it right, make it fast.
Armaremos un dominio simple, usando TDD, y el ciclo de: test, rojo, verde,
refactor. Podremos ver como “crece” 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 o ejemplos de uso esperado del software y hasta conseguimos ser más productivos y producir código mantenible, evitando la sobre-ingeniería o las arquitecturas "de astronauta" complicadas.

Y finalmente, el martes 8 de Octubre tengo una charla dentro de Scala User Group Argentina:

Meetup Mensual SUGAR – Octubre 2013

http://www.meetup.com/scala_ar/events/142585062/

Scala Internals: 

Vamos a dar una  introducción al diseño e implementación de Scala:

• ¿De dónde viene Scala? ¿Por qué un lenguaje nuevo?

• La influencia de lo funcional

• La adopción de Java (y .NET en su tiempo)

• ¿Cómo hace para que Java se transforme en lo que vemos como Scala?

• Decisiones de diseño (como las llamadas a los métodos, el acceso a arreglos, sistema unificado de tipos…)

• Implementación interna de algunas features. Por ejemplo, cómo implementa objetos, for, actores, functions

• Y cómo deja la puerta abierta para ir a jugar con Akka

Lo mío es un apostolado …. No digan que no les avisé 😉

Nos leemos!

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

TDD Rocks! (8) SharpBase in C#

Sunday, August 25th, 2013

Anterior Post
Anterior Post con C#  
Siguiente Post 

Hoy grabé una nueva sesión de TDD (Test-Driven Development) usando Visual Studio y C#, sobre mi proyecto de base de datos en memoria, SharpBase.

Pueden verla en (y de paso escuchar Anglish):

http://www.youtube.com/watch?v=ymQePMZ2XEo

[View:http://www.youtube.com/watch?v=ymQePMZ2XEo] 

Esta vez implementé una clase Column. Vean que no era necesaria en los anteriores tests. Como quería tener el caso de insertar datos pero que alguno fuera autonumérico, fui agregando tests y funcionalidad hasta conseguir que esa “feature” quedara implementada. No hizo falta tener todo diseñado de antemano: se puede ir diseñando a medida que aparecen los casos de uso. Y en algún momento, puede que aparezca un gran refactor, rediseño, pero toda la batería de tests que hayamos armado nos va a ayudar en el proceso.

Esta es el último video con SharpBase. Pueden seguir todos los commits que van a seguir en mi cuenta de GitHub:

https://github.com/ajlopez/SharpBase

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

Lo próximo de TDD Rocks! con C# posiblemente sea una aplicación ASP.NET MVC, y en español.

Nos leemos!

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

TDD Rocks! (7) OStore con JavaScript/Node.js

Thursday, August 15th, 2013

Anterior Post
Anterior Post con JavaScript 
Siguiente Post  
Siguiente Post con JavaScript 

Publiqué una nueva Google Hangout, demostrando cómo voy avanzando en el proyecto OStore usando el flujo de trabajo de TDD:

http://www.youtube.com/watch?v=PUTnaTDNCEw

[View:http://www.youtube.com/watch?v=PUTnaTDNCEw]

Acá no estoy aprendiendo JavaScript, sino que ya lo conozco. Uso lo mínimo indispensable, en este caso el módulo assert que viene “builtin” en Node.js. Sacrifico la independencia de los tests por la simplicidad. Luego, si es necesario, habrá refactor de tests. En otros proyectos lo hago, y en otros no ví que ganara algo. Con simplemente dejar los tests separados por archivo, ya tengo bastante independencia.

En esta sesión, implementé un find tipo query by example, como ví que tiene MongoDB. Ahora devuelve un arreglo de objectos JavaScript. Si tuviera que llegar a manejar millones, ahí refactorizaría a tener un cursor que vaya recorriendo la lista interna de objectos y devolviendo los que cumplen con el criterio que le paso.

Pero ya saben: baby steps, make it works. Ya vendrá en make it right y el make it fast. En otro proyecto estoy reproduciendo MongoDb para JavaScript, y pienso seguir ese camino.

Nos leemos!

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