• Shortcuts : 'n' next unread feed - 'p' previous unread feed • Styles : 1 2

» Publishers, Monetize your RSS feeds with FeedShow:  More infos  (Show/Hide Ads)


Date: Wednesday, 08 Oct 2014 16:52

Hora de escribir las resoluciones del nuevo mes. Pero antes, repasar las de septiembre:

- Aktores con ejemplo distribuido [completo] ver repo
- AjErl con ejemplo distribuido [pendiente]
- Soporte web y ejemplo para RuScript [parcial] ver repo
- Completar Mochy [parcial] ver repo
- Mejorar RSharp [completo] ver repo
- Trabajar con NodeJs en los temas Deep Learning, Internet of Things, Artificial Intelligence [pendiente]
- Trabajar en Code Generation usando AjGenesis para Node [completo] ver repo principal ver repo Express ver repo Sinatra ver repo Laravel
- Trabajar en Liqueed Project [completo] ver repo

También estuve trabajando en:

- Mejorar AjScript [completo] ver repo
- Refactor BasicScript tests para usar SimpleUnit [completo] ver repo
- Crear SimpleColls, simple collection functions in JavaScript, alone or a la Linq [completo] ver repo
- Refactor SimpleStore tests para usar SimpleUnit [completo] ver repo
- Mejorar AjTalkJs, Smalltalk in JavaScript, soporte de primitiva super, primeros ejemplos Express 4 [completo] ver repo
- Refactor MProc tests para usar SimpleUnit [completo] ver repo
- Refactor AjLogoJs tests para usar SimpleUnit [completo] ver repo
- Refactor SimpleKeeper tests para usar SimpleUnit [completo] ver repo
- Refactor SimpleTags tests para usar SimpleUnit [completo] ver repo
- Mejorar SimpleUnit, publicar nueva versión [completo] ver repo
- Refactor SimplePipes tests para usar SimpleUnit, y publicar nueva versón [completo] ver repo

Las resoluciones de este nuevo mes:

- Dar una charla de introducción a Aktores, actor model distribuido en C#
- Armar AjErl ejemplo distribuido
- Más ejemplos Express en AjTalkJs
- Explorar redes neuronales en JavaScript
- Explorar algoritmos genéticos en JavaScript
- Explorar otros temas de Inteligencia Artifical en JavaScript
- Más Aktores distribuidos
- Comenzar Distributed Smalltalk en AjTalkJs

Nos leemos!

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

Author: "lopez" Tags: ".NET, C#, JavaScript, Liqueed, NodeJs, P..."
Comments Send by mail Print  Save  Delicious 
Date: Sunday, 05 Oct 2014 15:10

Voy a usar directamente la expresión en inglés “code coverage” para lo que en español es cubrimiento de código. La pregunta de hoy es ¿hay relación entre un gran nivel de code coverage y calidad de código?

Primero, el code coverage es una métrica: simplemente eso, ni más ni menos. Si conseguimos el porcentaje de code coverage luego, digamos, de ejecutar todos los tests del sistema, un alto porcentaje con todos los tests en verde sólo indica que al ejecutar los tests pasamos por una gran cantidad de líneas de nuestro código, sin provocar un error.

Pero cualquiera que se ponga a meditar sobre eso, no puede concluir así por que sí, que eso indique una buena calidad de código. Bien podemos imaginarnos código que cumpla con todo eso (buen métrica, pruebas que pasan) y que NO TENGA UNA BUENA CALIDAD de código. Por ejemplo, bien podemos refactorizar todo el sistema para que el código quepa en una clase, con cientos de métodos, y el code coverage seguirá alto y las pruebas pasarán. Y así se nos pueden seguir ocurriendo refactorizaciones, que bajen la calidad de código, sin que la métrica de code coverage se vea afectada en gran medida.

Tenemos que ponernos de acuerdo en qué es calidad de código, pero para este post, podemos tomar algunas cualidades:

- Que el código ejecute lo que se espera
‘- Que sea modificable/extensible de una forma accesible

Vean que no pongo que sea “entendible” porque me imagino que esa cualidad es un requisito de la segunda que puse arriba. La primera cualidad se puede dividir en:

- Que el código de el resultado esperado ante las entradas correctas
- Que el código reaccione de la manera esperada ante las entradas incorrectas

y así podríamos seguir refinando. Igual es tema para discutir. Pero aún no podemos esperar, con las cualidades de arriba u otras que se nos ocurran, que ante un gran nivel de code coverage obtengamos, de forma casi mágica, una buena calidad de código.

Entonces, si alguien espera que subiendo el code coverage de una aplicación/sistema/librería, escribiendo pruebas para subir esa métrica, de esa forma vamos a obtener/mejorar la calidad de código, les digo una cosa: es loable lo suyo, pero es tan inútil como alinear las sillas en la cubierta del Titanic. Están haciendo algo que parece bueno, pero no es lo que hay que hacer.

Alguien podría decir: ¿pero acaso las pruebas que acompañan al aumento de code coverage, no nos aseguran que el código inicial tenga la calidad esperada? Si hacen las pruebas DESPUES de escribir el código, muchas veces eso no se cumple. Porque se van a ver motivados a elevar la métrica, no la calidad del código. Pongamos un ejemplo en concreto. Sea un método que recibe los argumentos a y b, y revuelve a/b (su división). Al principio no está cubierta, agregamos una prueba que invoca a ese método pasando a=1, b=2 y vemos que devuelve 0.5. Ahora el code coverage subió, de 0 a 100%. Las pruebas pasan. Pero no tenemos idea de haber cubierto los (MINI)CASOS DE USO de ese método. Por ejemplo, nunca probamos que pasa cuando b=cero.

Ese es uno de los problemas de los “pruebas después”. No se cubren los casos de uso de nuestra aplicación. Y si encima nos dejamos guiar por aumentar el code coverage, menos vamos a concentrarnos en los casos de uso. Y si siguen el camino “pruebas después” también se encontrarán, más frecuentemente de lo necesario, que el código ya armado es difícil de probar, o lo van a modificar de formas extrañas para que podamos tener la recompensa del día: uy! aumentamos el code coverage! ¡Qué buenos programadores que somos, qué buena calidad de código!

No me malinterpreten: el code coverage sirve, pero NO ASEGURA calidad de código. Ni siquiera la mantenibilidad de un sistema. No es difícil encontrar sistemas con alto code coverage, uno los modifica, las pruebas pasan, pero luego, el sistema web vuela luego de dos clicks en las páginas. ¿Por qué? De nuevo, porque el code coverage alto y las “pruebas después” no aseguran para nada que hayamos contemplado todos los casos de uso (como el simple de más arriba, dividor por b igual a cero, el método tiene 100 por ciento de code coverage, pero no tiene el 100 por ciento de los casos de uso).

Algo de valor agrega el subir el code coverage, porque al final, alguna de las pruebas adicionales algo nuevo cubre. Pero es lo que alguien ha llamado “pica pica bajada de cordón (de vereda)”, trabajo que agrega poco valor en general a lo que programamos, y que lleva tiempo.

Bueno, luego de esta larga diatriba, algo de agua para mi molino:

Si en vez de intentar subir el code coverage con pruebas después, seguimos el FLUJO DE TRABAJO de Test-Driven Development, el code coverage alto es como que viene de la mano de ese flujo de trabajo, sin gran esfuerzo. Si aplicamos ese flujo a cubrir cada caso de uso, vamos construyendo software que va creciendo, como un organismo, paso a paso, de la manera más simple, y asegurándonos que cada prueba que agregamos responde a una necesidad del sistema que estamos armando. El código va fluyendo, naciendo, transformándose, y la etapa de refactor es de importancia para aumentar la calidad, no para el code coverage.

Espero que se haya entendido: sin TDD, no hay paraíso :-)

Nos leemos!

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

Author: "lopez" Tags: "Programacion, Test-Driven Development"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 04 Oct 2014 14:53

Había una vez una familia que se reunía una vez por año, para celebrar juntos. La dueña de casa solía cocinar al horno un pavo relleno. Una receta que habia pasado de generación a generación, por vía oral, especificaba qué colocarle, cuánto tiempo cocinarlo, cómo preparar el relleno. Pero había algo que hacía siempre: cortarle la cola al pavo. Alguien preguntó: “¿Por qué hay que cortarle la cola al pavo? ¿Por qué está esa instrucción en la receta?”. Sorprendentemente, la cocinera sólo atinó a responder: “No sé, así lo hacía mi mamá, así me lo enseñó”. Fueron a preguntarle a la madre: “No sé, a mí también me lo enseñó así mi mamá”. Le preguntaron a la abuela: “Yo tampocó sé, así me lo enseñó mi mamá, en mi infancia”. Y al final, llegaron a la bisabuela: “Bueno, cuando vivíamos en Europa, en una casita en el campo, el pavo no entraba en el horno, y teníamos que cortarle la cola”.

¿Cuántas veces nos pasa, en nuestras actividades, profesionales o no, “cortar la cola al pavo”, sin notar que las fuerzas que llevaban a esa conducta ya desaparecieron?

Para poner un poco de contexto, veamos un ejemplo en el desarrollo de software. Cuando aparecieron las primeras microcomputadores, no había discos duros, solamente discos flexibles. Y muchas veces, la computadora sólo tenía disponible una dispositivo de discos flexibles (la “diskettera”). Recuerdo un sistema de sueldos y jornales, a principio de los ochenta. A fin de año había que calcular por empleado cuánto tenía que abonarse de aguinaldo. La ley había cambiado: ya no era un monto asociado al último sueldo, sino lo que había cobrado por cada cada mes. No había forma que un disco flexible tuviera toda esa información. Así que el operador, para calcular el aguinaldo, tenía que introducir y retirar uno por uno los discos de las liquidaciones mensuales. Eran las limitaciones de esos tiempos.

Y en minicomputadores, los discos duros no eran el último lugar de resguardo. Se usaban cintas, para sacar copias de los programas y los datos.

Desde los “mainframes” fue llegando la implementación de bases de datos (relaciones, jerárquicas, en red, aunque sólo sobrevivieron las primeras; la nueva “onda” de NoSQL no es tan nueva :-). Y la próximas implementaciones de los sistemas en computadores personales pasaron a usar bases de datos, en general relacionales.

Y siguió el progreso. Pero algo quedó de resabio, de reliquia, algo como “cortar la cola del pavo”: hoy se piensa en tener todo en la base de datos. Pero hoy tenemos gran cantidad de memoria disponible. Muchas veces, podemos tener nuestro dominio TOTALMENTE en memoria, y muchos casos de uso son de “muchas lecturas, escrituras esporádicas”. Pero en vez de aprovechar directamente la memoria (vean que puse TODO el dominio en memoria, no estoy hablando de “cache” selectivo), todavía se inicia el desarrollo de un sistema viendo el esquema de base de datos.

No digo que sea aplicable a todos los casos, pero en muchos sistemas, la base de datos (o el disco, al final), es la “nueva cinta”: la forma de resolver la persistencia. Pero la operación bien podría hacerse completamente en memoria. Aún en memoria distribuida. Por ejemplo, en Facebook, en su implementación, todo es un objeto (una persona, una relación, un mensaje, una foto, …), y se almacena en un sistema que llaman TAO (de The Abstract Object). Usan MySql (muchas bases) sólo para persistencia. La operación la resuelvan en memoria: TAO corre en multitud de máquinas distribuidas en varios data center, y usa MySQL principalmente para persistencia, y replicación, apenas para el negocio.

No hace falta ser Facebook para aprovecharse de “primero la memoria”, en vez de “hay que cortar la cola del pavo, hay que usar base de datos relacionales”. En un sistema que estuve examinando, con un caso de “muchas lecturas, pocas escrituras”, pude implementar el caso de uso principal en memoria, quedando CUATROCIENTAS VECES más rápido (no digo 400 por ciento, digo 400 VECES). Y otro proceso, que tardaba en el orden de las ocho horas, paso a ejecutarse en minutos, adoptando un modelo en memoria.

Y ése es sólo un ejemplo. Ahora, agua para mi molino:

Test-Driven Development (TDD), al empujarme, como flujo de trabajo, hacia la implementación más simple, casi como que me impide complicarme con soluciones que níngún caso de uso pidió. Sólo se adopta una base de datos relacional, o un NoSQL, cuando el caso de uso lo pide. Y siguiendo TDD he notado que esa decisión, que puede ser diferida, aún cuando se tome, se puede cambiar en el futuro. Por eso soy escéptico cuando alguien quiere plantear cuáles herramientas usar ANTES DE PASAR por los casos de uso.

Con el caso de uso “nuevo horno más grande” desde el principio, nunca se llega a implementar “cortar la cola del pavo”.

Nos leemos!

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

Author: "lopez" Tags: "Programacion, Test-Driven Development"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 30 Sep 2014 17:54

Tengo varios temas que quiero tratar, en distintos lenguajes y tecnologías. Hoy quiero comentar dos charlas que se vienen, que puedo dar gracias al Microsoft User Group:

Aplicaciones Distribuidas en C#, un modelo de actores

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

Lugar: Auditorio del MUG, Rivadavia 1479 Primer Piso “A”, Buenos Aires.
Fecha y Horario: Miércoles 8 de octubre de 2014 de 18:30 a 20:30 hs.

La idea es presentar conceptos de actores, y actores distribuidos, comentar la principal implementación en Java: Akka. Y luego pasar a discutir y mostrar una implementación en C#

Luego

Desarrollando Single Page Applications con JavaScript

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

Lugar: Auditorio del MUG, Rivadavia 1479 Primer Piso “A”, Buenos Aires.
Fecha y Horario: Miércoles 29 de octubre de 2014 de 18:30 a 20:30 hs.

Veremos las fuerzas que llevan a la aparición de aplicaciones web compuestas de una sola página, con dinámica en JavaScript. Siguiendo “baby steps” y simplicidad, exploraremos cómo podemos armar algún ejemplo con simple JavaScript y JQuery, cómo alimentar los datos desde un servidor con una API expuesta (agnóstico de la tecnología) y luego visitaremos algunas librerías JavaScript del lado cliente que nos ayudan, como Angular y Backbone.

Espero que estas charlas aporten algo a estos temas, entre tantos que son interesantes en estos tiempos. Estoy preparando otras charlas, como Inteligencia Artificial en JavaScript para la JSConf 2014 de Argentina. Y espero que me aceptan alguna más, sobre JavaScript y Ruby, en la RubyConf 2014 de Argentina.

Nos leemos!

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

Author: "lopez" Tags: ".NET, Arg, Argentina, Buenos Aires, C#, ..."
Comments Send by mail Print  Save  Delicious 
Date: Sunday, 14 Sep 2014 08:52

Un poco tarde esta vez, es tiempo de revisar mis resoluciones de Agosto:

- Escribir un reemplazo de jQuery para ser usado en tests de consola con Node.js [completo] ver repo
- Escribir funciones simples en JavaScript para manipulación de arreglos [completo] ver repo
- Continuar con proyecto Liqueed [completo] ver repo
- Comenzar con Aktores Distribuido [parcial] ver repo
- Comenzar con AjErl Distribuido [pendiente]

Además, trabajé en:

- Dar una charla de introducción a Express [completo] ver repo ver presentación ver ejemplos
- Mejorar AjScript [completo] ver repo
- Mejorar RuScript, Ruby intérpreter en JavaScript [completo] ver repo
- Refactor SimplePipes [completo] ver repo
- Generar código del servidor Node.js/Express desde RAML [completo] ver repo
- Crear un sitio dinámico descripto en JSON para Express [completo] ver repo
- Mejorar RustScript, intérpreter de Rust en JavaScript [completo] ver repo
- Crear Mochy, test framework a la Mocha [completo] ver repo
- Crear RSharp, language intérpreter de lenguaje R en C# [completo] ver repo
- Refactorizar (y simplificar) SimpleRules, motor de reglas en JavaScript [completo] ver repo
- Primeros ejemplos para SimpleMule [completo] ver repo
- Mejorar salida para SimpleUnit [completo] ver repo

Mis resoluciones para el nuevo mes:

- Aktores distribuidos
- AjErl distribuidos
- Soporte web y ejemplo en RuScript
- Completar Mochy
- Mejorar RSharp
- Trabajar con NodeJs en Deep Learning, Internet of Things, Artificial Intelligence
- Trabajar en Code Generation usando AjGenesis para Node
- Trabajar en Liqueed Project

Nos leemos!

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

Author: "lopez" Tags: ".NET, C#, JavaScript, NodeJs, Proyectos ..."
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 06 Sep 2014 18:07

Desde hace unos meses estoy trabajando en mi tiempo libre en:

https://github.com/ajlopez/RuScript

Y escribiendo todo siguiendo el flujo de TDD (Test-Driven Development) (ver la historia de commits)

La idea es tener un intérprete de Ruby escrito en JavaScript, que pueda correr en el browser o en el server (en este caso con Node.js). No estoy implementando un compilador a JavaScript, porque quiero seguir “baby steps”, y porque veo que la semántica de Ruby puede ser bastante distinta de la de JavaScript en algunos casos. La resolución de métodos a invocar, o ver si una variable es de instancia, de clase o local a una función, son temas que difieren entre los dos lenguajes. Así que me he decantado por escribir un intérprete.

Estoy aplicando “dog fooding”, porque el parser está construido basado en:

https://github.com/ajlopez/SimpleGrammar

Que también estoy aplicando en otros proyectos, como RustScript. (Hay implementación de SimpleGrammar en C#, ver GrammGen). Fragmento de las reglas definidas para el parser de RuScript:

// Expression Level 1
get('Expression1').generate('Expression'),
get('Expression1', 'Plus', 'Expression0')
    .generate('Expression1', function (values) { return new AddExpression(values[0], values[2]); }),
get('Expression1', 'Minus', 'Expression0')
    .generate('Expression1', function (values) { return new SubtractExpression(values[0], values[2]); }),

// Expression Level 0
get('Expression0').generate('Expression1'),
get('Expression0', 'Multiply', 'Term')
    .generate('Expression0', function (values) { return new MultiplyExpression(values[0], values[2]); }),
get('Expression0', 'Divide', 'Term')
    .generate('Expression0', function (values) { return new DivideExpression(values[0], values[2]); }),

// Term
get('Term').generate('Expression0'),
get('Term', 'LeftBracket', 'ExpressionList', 'RightBracket')
    .generate('Term', function (values) { return new IndexedExpression(values[0], values[2]); }),
get('Integer').generate('Term'),
get('@@', 'Name').generate('ClassVariable', 
    function (values) { return new ClassVariableExpression(values[1].getName()); }),
get('@', 'Name').generate('InstanceVariable', 
    function (values) { return new InstanceVariableExpression(values[1].getName()); }),
get('Name').generate('Term'),
get('InstanceVariable').generate('Term'),
get('ClassVariable').generate('Term'),
get('String').generate('Term'),
get('Array').generate('Term'),
get('LeftParenthesis', 'Expression', 'RightParenthesis')
    .generate('Expression0', function (values) { return values[1]; }),
get('LeftBracket', 'RightBracket')
    .generate('Array', function (values) { return new ArrayExpression([]); }),
get('LeftBracket', 'ExpressionList', 'RightBracket')
    .generate('Array', function (values) { return new ArrayExpression(values[1]); }),


Por cada elemento que voy descubriendo, voy armando una expresión, que puede evaluarse dado un contexto (un contexto indica cuales son las variables accesibles en determinado momento, y sus valores respectivos). Ejemplo:


function NameExpression(name) {
    this.evaluate = function (context) {
        var value = context.getValue(name);
        
        if (typeof value == 'function')
            return value();
        
        return value;
    };
    
    this.getName = function () { return name; };
    
    this.setValue = function (context, value) {
        context.setLocalValue(name, value);
    }
}

function InstanceVariableExpression(name) {
    this.evaluate = function (context) {
        if (!context.$self.$vars)
            return null;
            
        return context.$self.$vars[name];
    };
    
    this.getName = function () { return name; };
    
    this.setValue = function (context, value) {
        if (!context.$self.$vars)
            context.$self.$vars = { };
            
        context.$self.$vars[name] = value;
    }
}

function ClassVariableExpression(name) {
    this.evaluate = function (context) {
        if (!context.$self.$class.$vars)
            return null;
            
        return context.$self.$class.$vars[name];
    };
    
    this.getName = function () { return name; };
    
    this.setValue = function (context, value) {
        if (!context.$self.$class.$vars)
            context.$self.$class.$vars = { };
            
        context.$self.$class.$vars[name] = value;
    }
}

function ConstantExpression(value) {
    this.evaluate = function () {
        return value;
    };
}


Tengo acceso a JavaScript desde Ruby, por ejemplo, un test:


exports['Evaluate JavaScript global name'] = function (test) {
    global.myglobal = 42;
    var context = contexts.createContext();
    var parser = parsers.createParser("js.myglobal");
    //parser.options({ log: true });
    var expr = parser.parse("Expression");
    var result = expr.value.evaluate(context);
    test.equal(result, 42);
}



El “namespace” js es el que posibilita acceder a las variables definidas en JavaScript y a todo su ecosistema, ya sea en el browser o en el servidor Node.


Espero poder presentar mi avance en la RubyConf 2014 de Argentina.


Próximos pasos: acceder a los “require” de Node.js, ejemplos de sitios web usando Node.js/Express, ejemplos de consola, ejemplos en el browser, etc.


Nos leemos!


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

Author: "lopez" Tags: "Interprete, JavaScript, Node, NodeJs, Pr..."
Comments Send by mail Print  Save  Delicious 
Date: Friday, 29 Aug 2014 11:48

Argentina (y Buenos Aires) sigue siendo un lugar de gran actividad en la difusión de lo ágil en el desarrollo de software y otros ámbitos. Se vienen dos días de jornadas, viernes 26 y sábado 27 de Septiembre, ver:

http://www.meetup.com/agiles-bsas/events/191103222/

Friday, September 26, 2014 9:00 AM
to Saturday, September 27, 2014, 6:00 PM

Universidad de Belgrano
Lacroze 1947, Buenos Aires (map)

Realizaremos nuestras primeras Jornadas Nacionales de Metodologías Agiles, en Formato Open Space.
Nos juntamos con ganas de compartir experiencias, buenas prácticas y aprender más sobre metodologías agiles.

Más información en el sitio oficial:

http://aa2014.agiles.org/

El formato es Open Space, no hay una agenda predefinida. Se puede ir proponiendo y votando temas en:

https://agilesargentina.uservoice.com/forums/261590-%C3%81giles-argentina-2014-26-y-27-sept-en-buenos-aire

Ágiles Argentina 2014, las Primeras Jornadas Nacionales de Metodologías Ágiles, es un evento de la Comunidad Ágil Argentina. Tendrá como sede a la Universidad de Belgrano , en la Ciudad de Buenos Aires, los dias 26 y 27 de Septiembre. Ver detalles del evento en http://aa2014.agiles.org/

Una novedad, el catering (comida, bebidas, infusiones, etc) será autoorganizado, comprometerse en alguno de los puntos de:

http://aa2014.agiles.org/catering-auto-organizado/

Si esto no es lo ágil, lo ágil ¿donde está? :-)

Nos leemos!

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

Author: "lopez" Tags: "Agile, Argentina, Buenos Aires"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 26 Aug 2014 15:08

El próximo sábado 30 de Agosto, se realizará el primer Hackathon abierto del grupo Java Argentina, en las oficinas de MuleSoft en Buenos Aires. Más detalles en:

http://www.meetup.com/jugargentina/events/197071352/

Saturday, August 30, 2014
11:00 AM to 8:00 PM
MuleSoft
Av Corrientes 316, Capital Federal, Buenos Aires (map)

Planta Baja

Vamos a estar organizando el primer hackathon abierto del grupo. La idea es juntarnos a las 11AM, arrancar al medio dia, y terminar a las 8pm. Ahi vienen las presentaciones, algunos premios y cerramos con algo para comer y tomar.

Las reglas:

• Se puede usar cualquier lenguaje, no solo Java o que corra en la JVM. 

• Hay que contribuir a un proyecto Open Source. Puede ser cualquiera, no necesariamente famoso (ej: Mule ESB, Spring, Go, Vertx, etc). 

• Dura 8 horas. 

• Equipos de 1 hasta 5 integrantes

• Se va a evaluar el impacto de la contribución.

Estamos definiendo algunos premios para el equipo ganador y menciones. Apenas tengamos algo les avisamos.

Prometemos comida, bebidas y diversion!, por lo que pedimos que se registren todos los participantes, así podemos calcular bien las cantidades. 

Apuren a anotarse ya que vamos a tener cupo limitado!

Lo bueno es que puede usarse cualquier lenguaje, y al parecer, puede trabajarse sobre un proyecto nuevo o existente, mientras sea Open Source. Espero que haya cerveza :-)

Nos leemos!

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

Author: "lopez" Tags: "Buenos, Buenos Aires, Hackathon, Java, P..."
Comments Send by mail Print  Save  Delicious 
Date: Monday, 25 Aug 2014 17:08

Se viene en Septiembre el próximo meetup de JavaScript, en Buenos Aires, ver detalles para el 11 de Septiembre en:

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

Retomamos la sana costumbre de reunión y discusión tecnológica con colegas de la comunidad.

Como siempre, la modalidad es la misma, arrancamos 6:30, y para los que van llegando tenemos algo para tomar, comer y charlar. A las 7 arranca la primer charla. Charlas:

Angel ‘Java’ Lopez – Introduccion a Express
Juan Pablo Kutianski – Introducción a D3

Como en la última oportunidad vamos a transmitir el evento por HO para los que no puedan venir.
Los esperamos!

Como otras veces, organizado por la gente de @scvsoft. Seguro, picada y cerveza (también medialunas y bebida cola, urrgg… :-)

Sí, voy a estar dando una charla corta sobre Express, el framework web más popular montado sobre Node.js. Veremos de usar el generador básico que viene con Express 4.x, qué funcionalidad básica da, el manejo de los middleware, el ruteo, la generación de vistas usando lenguajes de templates, y la exposición de APIs devolviendo JSON simple. Haremos código en vivo sencillo, y luego pasaré a ejemplos armados, con acceso, por ejemplo, a MongoDB. Realmente, Express es muy flexible, y se ocupa de pocas cosas, dejándonos a nosotros aprovechar el resto del ecosistema de Node. En ese sentido, no es un framework “pesado” o con mucho “opinionated”. Para algunos, esto es una ventaja, pero para otros no. A mí ese “approach” me gusta, porque permite elegir herramientas y librerías según el contexto y la necesidad, en vez de embarcarse en una gran solución única. Pero verán Uds. que les parece.

También estará el bueno de @baldpower dando una charla sobre D3, la librería de JavaScript para gráficos dinámicos, y hasta en tiempo real. Ver

http://d3js.org/

Nos leemos!

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

Author: "lopez" Tags: "Buenos Aires, JavaScript, Meetup, NodeJs"
Comments Send by mail Print  Save  Delicious 
Date: Tuesday, 12 Aug 2014 18:01

Es tiempo de escribir las nuevas resoluciones, y revisar las de Julio:

- Mejorar AjGenesisNode generación de código para Express [completo] ver repo
- Mejorar AjGenesisNode generación de código para Sinatra [parcial] ver repo
- Primer generación de código de AjGenesisNode para Laravel [pendiente]
- Carga de módulos, exportar, en lenguaje Mass [pendiente]
- Continuar con SharpBus [completo] ver repo
- Continuar con Dynamic Site [pendiente]
- Give a talk about Node.js/Express [completo]
- Mejorar mi sitio personal [completo] ver repo
- Escribir TDD Post [pendiente]
- Escribir C# Posts [completo] ver posts
- Caso distribuido usando Aktores [pendiente]
- Revisar, refactorizar y continuar la implementación de RustScript [completo] ver repo

Additionally, I worked on:

- Comenzar SimpleList [completo] ver repo
- Comenzar SimpleJQuery [completo] ver repo
- Mejorar SimpleMule [completo] ver repo
- Comenzar SharpGD, Graph Database in C# [completo] ver repo
- Mejorar SimpleBus [completo] ver repo
- Mejorar SharpGo [completo] ver repo
- Mejorar ExpressSamples [completo] ver repo
- Mejoras menores en ScaScript [completo] ver repo
- Mejorar ScalaSharp [completo] ver repo
- Escribir Friends sample for JavaScriptSamples [completo] ver repo
- Escribir Angular examples [completo] ver repo
- Agregar método remove a OStore [completo] ver repo
- Colaborar con el proyecto Liqueed [completo] ver repo

Nuevas resoluciones para Agosto 2014:

- Escribir jQuery mock a ser usando en test de consola desde Node.js
- Escribir simples funciones en JavaScript para manipular arreglos de objetos
- Continuar colaborando con el proyecto Liqueed
- Comenzar con Aktores ejemplo distribuido
- Comenzar con AjErl ejemplo distribuido

Nos leemos!

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

Author: "lopez" Tags: ".NET, C#, JavaScript, NodeJs, Proyectos ..."
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 09 Jul 2014 10:45

Un nuevo mes comenzó, tiempo de revisar mis resoluciones de Junio 2014, y escribir las nuevas:

- Continuar AjErl [pendiente]
- Continuar ScalaSharp [completo] repo 
- Continuar SharpGo [completo] repo
- Alcance de variables en lenguaje Mass [completo] repo
- Comenzar SimpleItems [pendiente]
- Continuar SimpleApps [partial] repo
- Continuar ClojSharp [pendiente]
- Continuar DictSharp [pendiente]
- Primer caso de uso distribuido de AjErl [pendiente]
- Primer caso de uso distribuido de Aktores [pendiente]
- Escribir C# Posts [completo] Posts
- Escribir TDD Post [completo] Post
- Mejorar el código de mi sitio personal [completo]

También estuve trabajando en:

- Crear y publicar primer versión SimpleCurry, para programación funcional en JavaScript [completo]  repo
- Crear y publicar primer versión LoadJsons, lee un modelo JSON desde varios archivos, para JavaScript/Node [completo]  repo
- Crear un sitio dinámicado, definido por JSON, para Express 4 [completo]  repo
- Generar código para Express 4 usando AjGenesisNode [completo]  repo
- Generar código Sinatra usando AjGenesisNode [completo]  repo
- Mejorar AjGenesisNode, AjGenesisNode-Model, AjGenesisNode-Entity [completo]  repo repo repo
- Continuar DylanSharp [completo]  repo
- Crear SharpBus, un service bus tipo Mule, en C# [completo]  repo

Estas son mis resoluciones para Julio 2014:

- Seguir mejorando la generación de código de AjGenesisNode para Express
- Seguir mejorando la generación de código de AjGenesisNode para Sinatra
- Primer generación de código de AjGenesisNode para Laravel 
- Mejorar la carga de módulos y la exportación de variables/funciones en el lenguaje Mass
- Continuar con SharpBus
- Continuar con Dynamic Site
- Dar una charla sobre Node.js/Express
- Dar una jornada sobre Node.js/Express
- Seguir mejorar el código de mi sitio personal
- Escribir post de TDD
- Escribir posts de C#
- Caso de uso distribuido en Aktores
- Revisar, refactorizar y continuar la implementación de RustScript

Nos leemos!

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

Author: "lopez" Tags: ".NET, C Sharp, Javascript, Proyectos de ..."
Comments Send by mail Print  Save  Delicious 
Date: Wednesday, 09 Jul 2014 05:45

Un nuevo mes comenzó, tiempo de revisar mis resoluciones de Junio 2014, y escribir las nuevas:

- Continuar AjErl [pendiente]
- Continuar ScalaSharp [completo] repo 
- Continuar SharpGo [completo] repo
- Alcance de variables en lenguaje Mass [completo] repo
- Comenzar SimpleItems [pendiente]
- Continuar SimpleApps [partial] repo
- Continuar ClojSharp [pendiente]
- Continuar DictSharp [pendiente]
- Primer caso de uso distribuido de AjErl [pendiente]
- Primer caso de uso distribuido de Aktores [pendiente]
- Escribir C# Posts [completo] Posts
- Escribir TDD Post [completo] Post
- Mejorar el código de mi sitio personal [completo]

También estuve trabajando en:

- Crear y publicar primer versión SimpleCurry, para programación funcional en JavaScript [completo]  repo
- Crear y publicar primer versión LoadJsons, lee un modelo JSON desde varios archivos, para JavaScript/Node [completo]  repo
- Crear un sitio dinámicado, definido por JSON, para Express 4 [completo]  repo
- Generar código para Express 4 usando AjGenesisNode [completo]  repo
- Generar código Sinatra usando AjGenesisNode [completo]  repo
- Mejorar AjGenesisNode, AjGenesisNode-Model, AjGenesisNode-Entity [completo]  repo repo repo
- Continuar DylanSharp [completo]  repo
- Crear SharpBus, un service bus tipo Mule, en C# [completo]  repo

Estas son mis resoluciones para Julio 2014:

- Seguir mejorando la generación de código de AjGenesisNode para Express
- Seguir mejorando la generación de código de AjGenesisNode para Sinatra
- Primer generación de código de AjGenesisNode para Laravel 
- Mejorar la carga de módulos y la exportación de variables/funciones en el lenguaje Mass
- Continuar con SharpBus
- Continuar con Dynamic Site
- Dar una charla sobre Node.js/Express
- Dar una jornada sobre Node.js/Express
- Seguir mejorar el código de mi sitio personal
- Escribir post de TDD
- Escribir posts de C#
- Caso de uso distribuido en Aktores
- Revisar, refactorizar y continuar la implementación de RustScript

Nos leemos!

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

Author: "lopez" Tags: "1389, 14005, 15035, 15550, 18052, 5374"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 07 Jul 2014 17:18

Gracias a la gente del MUG voy a dar una charla introductoria (gratuita, pero hay que registrarse) ahora en unos días acá en Buenos Aires:

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

Inicio: 23.07.2014 18:30hs, hasta las 20 y monedas | Lugar: Rivadavia 1479 1er Piso

JavaScript no solo tiene cada vez más influencia en el desarrollo cliente/nativo, también ha sabido crecer en el lado del servidor. En esta sesión gratuita veremos la implementación de Node.js, un programa que ejecuta JavaScript. Vacantes limitadas. Inscripción previa obligatoria.

Node.js permite el desarrollo de servidores de distintos protocolos, procesamiento distribuido, y desarrollo web, explotando la entrada/salida asincrónica para mejorar el rendimiento. Bravemente exploraremos como se escribe y ejecuta JavaScript en Node.js, el sistema de módulos, el ecosistema de módulos que tiene, una introducción a desarrollar sitios web con Express, con ejemplos.

Luego, viene una jornada (de un día, con costo, traer notebook para aprovecharla):

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

Lugar: Auditorio del MUG, Rivadavia 1479 Primer Piso "A", Buenos Aires.

Fecha y Horario: Miércoles 30 de julio de 2014 de 9:00 a 17:00 hs. 

 

Contenidos:
1. Introducción a Node.js
1.1. Programación Javascript desde Node sobre el motor V8 
1.2. Entrada/Salida asincrónica 
1.3. Módulos 
1.4. Manejador de paquetes npm
1.5. Elementos de Test-Driven Development 
2. Programación Web con Node.js 
2.1. Módulo HTTP 
2.2. Manejo asincrónico 
2.3. Acceso a MongoDB
3. Programación Web con Express
3.1. Concepto de Middleware 
3.2. Lenguaje de Templates 
3.3. Ejemplos con Páginas y Acceso a Datos
3.4. Programando con JSON
3.5. Elementos de Socket.IO
(*)  Instalar previamente el siguiente software:
Instalador de Node (para Windows y otros) http://nodejs.org/download/
Git bajarlo de http://git-scm.com/
MongoDB bajarlo de http://www.mongodb.org/downloads
La idea de la jornada es practicar Node.js, desde el inicio, y ver de instalar, levantar y examinar ejemplos, de consola y web, para ir viendo cómo es el tema de desarrollo con Node.js, cómo se usan los módulos, el ecosistema que existe, el manejador de paquetes NPM, y Express como framework web. Usaremos MongoDB para la persistencia.
Como siempre, el material de los dos eventos estará en mi cuenta de GitHub, y algún anuncio habrá por acá.
Nos leemos!
Angel "Java" Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez 
Author: "lopez" Tags: "Desarrollo Web, Javascript, NodeJs, Buen..."
Comments Send by mail Print  Save  Delicious 
Date: Monday, 07 Jul 2014 12:18

Gracias a la gente del MUG voy a dar una charla introductoria (gratuita, pero hay que registrarse) ahora en unos días acá en Buenos Aires:


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


Inicio: 23.07.2014 18:30hs, hasta las 20 y monedas | Lugar: Rivadavia 1479 1er Piso


JavaScript no solo tiene cada vez más influencia en el desarrollo cliente/nativo, también ha sabido crecer en el lado del servidor. En esta sesión gratuita veremos la implementación de Node.js, un programa que ejecuta JavaScript. Vacantes limitadas. Inscripción previa obligatoria.


Node.js permite el desarrollo de servidores de distintos protocolos, procesamiento distribuido, y desarrollo web, explotando la entrada/salida asincrónica para mejorar el rendimiento. Bravemente exploraremos como se escribe y ejecuta JavaScript en Node.js, el sistema de módulos, el ecosistema de módulos que tiene, una introducción a desarrollar sitios web con Express, con ejemplos.


Luego, viene una jornada (de un día, con costo, traer notebook para aprovecharla):


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


Lugar: Auditorio del MUG, Rivadavia 1479 Primer Piso “A”, Buenos Aires.


Fecha y Horario: Miércoles 30 de julio de 2014 de 9:00 a 17:00 hs. 


 


Contenidos:

1. Introducción a Node.js

1.1. Programación Javascript desde Node sobre el motor V8 

1.2. Entrada/Salida asincrónica 

1.3. Módulos 

1.4. Manejador de paquetes npm

1.5. Elementos de Test-Driven Development 

2. Programación Web con Node.js 

2.1. Módulo HTTP 

2.2. Manejo asincrónico 

2.3. Acceso a MongoDB

3. Programación Web con Express

3.1. Concepto de Middleware 

3.2. Lenguaje de Templates 

3.3. Ejemplos con Páginas y Acceso a Datos

3.4. Programando con JSON

3.5. Elementos de Socket.IO

(*)  Instalar previamente el siguiente software:

Instalador de Node (para Windows y otros) http://nodejs.org/download/

Git bajarlo de http://git-scm.com/

MongoDB bajarlo de http://www.mongodb.org/downloads


La idea de la jornada es practicar Node.js, desde el inicio, y ver de instalar, levantar y examinar ejemplos, de consola y web, para ir viendo cómo es el tema de desarrollo con Node.js, cómo se usan los módulos, el ecosistema que existe, el manejador de paquetes NPM, y Express como framework web. Usaremos MongoDB para la persistencia.


Como siempre, el material de los dos eventos estará en mi cuenta de GitHub, y algún anuncio habrá por acá.


Nos leemos!


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

Author: "lopez" Tags: "10747, 14005, 15550, 17044"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 05 Jul 2014 17:19

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

 

Author: "lopez" Tags: "Arquitectura, Desarrollo Agil, TDD"
Comments Send by mail Print  Save  Delicious 
Date: Saturday, 05 Jul 2014 12:19

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


 

Author: "lopez" Tags: "10549, 11699, 1392"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 30 Jun 2014 13:30

En los dos últimos años estuve explorando las ideas de Storm (ver https://storm.incubator.apache.org/), implementándo alguna topología local en Node.js. Llegó la hora de practicar más C# y TDD (Test-Driven Development), con:

https://github.com/ajlopez/SharpStorm

El estado inicial del proyecto:

La idea es implementar bolt, spout y un builder de topologies. Leo en

https://storm.incubator.apache.org/about/simple-api.html

There are just three abstractions in Storm: spouts, bolts, and topologies. A spout is a source of streams in a computation. Typically a spout reads from a queueing broker such as Kestrel, RabbitMQ, or Kafka, but a spout can also generate its own stream or read from somewhere like the Twitter streaming API. Spout implementations already exist for most queueing systems.

A bolt processes any number of input streams and produces any number of new output streams. Most of the logic of a computation goes into bolts, such as functions, filters, streaming joins, streaming aggregations, talking to databases, and so on.

A topology is a network of spouts and bolts, with each edge in the network representing a bolt subscribing to the output stream of some other spout or bolt. A topology is an arbitrarily complex multi-stage stream computation. Topologies run indefinitely when deployed.

Como ven, en el proyecto por ahora están definidas las interfaces que espero por ahora tengan bolts y spouts, y un topology builder para armar una topología. Por ahora, quiero una implementación local (sin procesamiento distribuido). Luego, espero implementar el algoritmo de ACK que tiene Storm original, que permite saber cuándo un mensaje entrante quedó completamente procesado (incluso los procesos de los mensajes que produjo en el medio del proceso).

Próximos temas: revisar ISpout, IBolt, y como se arma una topología.

Nos leemos!

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

Author: "lopez" Tags: ".NET, C Sharp, Proyectos de Código ..."
Comments Send by mail Print  Save  Delicious 
Date: Monday, 30 Jun 2014 12:26

Ya estuve experimentando con map-reduce en Node.js/JavaScript. Pero también es interesante implementar algo del algoritmo en C#, para practicar TDD (Test-Driven Development) y para aprender más sobre lo que implica implementar el algoritmo. El proyecto que inicié es:

https://github.com/ajlopez/SharpDoop

El estado del proyecto a hoy:

Tiene un proyecto de librería de clases, y el proyecto de test. Todavía no llegué a pensar en algo distribuido. Lo único que quiero por ahora es especificar el algoritmo de map, el de reduce, y enviarlo a que procese como un job, dentro de este proyecto.

Vean que hay entonces un MapReduceJob. Es la clase base que se encarga de ejecutar un map (un lambda o Action que toma clave, valor y va procesándolo) y un reduce (toma clave, una lista de valores de esa clave, y emite resultado). Gracias a C#, esas dos operaciones se pueden expresar como lambdas o como métodos delegados en un objeto más complejo. Por ahora, están funcionando los casos simples que planteo en los tests.

Como divertimento, armé también un MapProcessJob, que es una variante de map/reduce a discutir. En vez de procesar primero todas las claves, y luego pasarlas por el reduce, trata de hacer todo junto. En algunos casos de uso puede ser más eficiente, pero es un tema a discutir con más detalle.

Próximos temas: revisar más en profundidad la implementación y las ideas, como el map/process.

Nos leemos!

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

Author: "lopez" Tags: ".NET, C Sharp, Proyectos de Código ..."
Comments Send by mail Print  Save  Delicious 
Date: Monday, 30 Jun 2014 08:30

En los dos últimos años estuve explorando las ideas de Storm (ver https://storm.incubator.apache.org/), implementándo alguna topología local en Node.js. Llegó la hora de practicar más C# y TDD (Test-Driven Development), con:


https://github.com/ajlopez/SharpStorm


El estado inicial del proyecto:



La idea es implementar bolt, spout y un builder de topologies. Leo en


https://storm.incubator.apache.org/about/simple-api.html


There are just three abstractions in Storm: spouts, bolts, and topologies. A spout is a source of streams in a computation. Typically a spout reads from a queueing broker such as Kestrel, RabbitMQ, or Kafka, but a spout can also generate its own stream or read from somewhere like the Twitter streaming API. Spout implementations already exist for most queueing systems.

A bolt processes any number of input streams and produces any number of new output streams. Most of the logic of a computation goes into bolts, such as functions, filters, streaming joins, streaming aggregations, talking to databases, and so on.

A topology is a network of spouts and bolts, with each edge in the network representing a bolt subscribing to the output stream of some other spout or bolt. A topology is an arbitrarily complex multi-stage stream computation. Topologies run indefinitely when deployed.


Como ven, en el proyecto por ahora están definidas las interfaces que espero por ahora tengan bolts y spouts, y un topology builder para armar una topología. Por ahora, quiero una implementación local (sin procesamiento distribuido). Luego, espero implementar el algoritmo de ACK que tiene Storm original, que permite saber cuándo un mensaje entrante quedó completamente procesado (incluso los procesos de los mensajes que produjo en el medio del proceso).


Próximos temas: revisar ISpout, IBolt, y como se arma una topología.


Nos leemos!


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

Author: "lopez" Tags: "1389, 15035, 18479, 18480, 5374"
Comments Send by mail Print  Save  Delicious 
Date: Monday, 30 Jun 2014 07:26

Ya estuve experimentando con map-reduce en Node.js/JavaScript. Pero también es interesante implementar algo del algoritmo en C#, para practicar TDD (Test-Driven Development) y para aprender más sobre lo que implica implementar el algoritmo. El proyecto que inicié es:


https://github.com/ajlopez/SharpDoop


El estado del proyecto a hoy:



Tiene un proyecto de librería de clases, y el proyecto de test. Todavía no llegué a pensar en algo distribuido. Lo único que quiero por ahora es especificar el algoritmo de map, el de reduce, y enviarlo a que procese como un job, dentro de este proyecto.


Vean que hay entonces un MapReduceJob. Es la clase base que se encarga de ejecutar un map (un lambda o Action que toma clave, valor y va procesándolo) y un reduce (toma clave, una lista de valores de esa clave, y emite resultado). Gracias a C#, esas dos operaciones se pueden expresar como lambdas o como métodos delegados en un objeto más complejo. Por ahora, están funcionando los casos simples que planteo en los tests.


Como divertimento, armé también un MapProcessJob, que es una variante de map/reduce a discutir. En vez de procesar primero todas las claves, y luego pasarlas por el reduce, trata de hacer todo junto. En algunos casos de uso puede ser más eficiente, pero es un tema a discutir con más detalle.


Próximos temas: revisar más en profundidad la implementación y las ideas, como el map/process.


Nos leemos!


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

Author: "lopez" Tags: "1389, 15035, 17628, 18478, 5374"
Comments Send by mail Print  Save  Delicious 
Next page
» You can also retrieve older items : Read
» © All content and copyrights belong to their respective authors.«
» © FeedShow - Online RSS Feeds Reader