lunes, 28 de diciembre de 2009

Inyectando DataContext en repositorios

Hoy tuve que hacer un refactor de una aplicación para inyectar DataContext en los repositorios por IoC y utilizar el patrón unit of work.

Esta es la interface de un repositorio:

public interface IContactInformationRepository
{
void Save(ContactInformation contactInformation);
}

y su implementación (recibe por constructor el DataContext):

public class ContactInformationRepository : IContactInformationRepository
{
private readonly DataContext dataContext;
public ContactInformationRepository(DataContext dataContext)
{
this.dataContext = dataContext;
}

public void Save(ContactInformation contactInformation)
{
dataContext.ContactInformations.InsertOnSubmit(contactInformation);
}
}

Para inyectar el data context por IoC, usando StructureMap:

ForRequestedType()
.CacheBy(InstanceScope.HttpContext)
.TheDefault.Is.ConstructedBy(() =>
new DataContext(ConfigurationManager.AppSettings["connectionString"]));

Si bien debería haber usado una interface IDataContext (programar hacia interfaces, no implementaciones), elegí el camino más fácil, ya que en este caso no necesito cambiar la implementación del DataContext.

Luego para implementar el patrón unit of work, me basé en este post:
http://weblogs.asp.net/rashid/archive/2009/02/26/implementing-unitofwork-pattern-in-linq-to-sql-application.aspx

Los repositorios no hacen el commit de la unit of work. La service layer tiene la responsabilidad de hacerlo. Para eso, cada servicio que realiza cambios en la base de datos tiene una dependencia a la IUnitOfWork. El IoC es responsable que configurar correctamente los repositorios, servicios y unit of work para que todos vean la misma instancia de DataContext:
http://codepaste.net/zz6g2s

Este es un unit test del servicio, que prubeba la unit of work usando Moq:
http://codepaste.net/hro3ob

En este caso, el servicio usa directamente el repositorio (y no un objeto mock) ya que no se impacta en base de datos, dado que la unit of work es un objeto mock.

saludos!

martes, 15 de diciembre de 2009

Proyecto Generador Savonious

Como comenté hace unas semanas, junto con Andrés Navarro vamos a estar difundiendo temas relacionados con minimizar el impacto ambiental. Esta vez, me gustaría comentar sobre el proyecto en que está trabajando Andrés.

Él junto con Nicolas Losano, un compañero de la tecnicatura superior en energía industrial (orientación energía renovable y arquitectura bioclimática), se propusieron la meta de diseñar y construir un generador eólico. A la derecha se muestra uno de los modelos usados para diseñarlo.

Antes de conocer este proyecto, pensaba que los generadores eólicos eran lo típicos con hélice de rotor horizontal. Existe una variante de rotor horizontal, conocidos como savonius, que tienen algunas características interesantes:
  • Muy bajo mantenimiento
  • Simple de instalar
  • Construcción simple y estable
  • Potencia nominal: 6 m/s de vientos
  • Soporta vientos de hasta 140 km/h (42 m/s)
  • No daña ni provoca un impacto negativo en el medio ambiente
  • Construido para durar toda la vida
Estos generadores, a diferencia de los de rotor horizontal, son más aptos para zonas con poco viento, como Buenos Aires.

Como comenta Andrés, este es el estado del proyecto:
Ya terminamos las aspas, estamos armando la estructura del eje y los discos que agarran las aspas, es un proceso lento, porque para cada pieza hacemos los moldes en madera y eso lleva su tiempo, por los tiempos que manejamos, y porque tan solo quedamos dos, pero aca estamos y vamos a seguir hasta el final.
Respecto al financiamiento del proyecto, por ahora están haciendo todo a pulmón:
Estamos reuniendonos con personas que estan interesadas en ayudarnos a conseguir financiación, en este proceso conocemos gente interesante o personas que estan en la misma que nosotros, si conocen a alguien que nos pueda ayudar, financiar, ayudar tecnicamente, les pedimos colaboración, en lo que se les ocurra.
El objetivo del proyecto, según sus impulsores:
No estamos atras de ganar dinero, pero nos gustaría dedicar nuestro 100 % del tiempo en esto para lo cual necesitaríamos un incentivo, simplemente queremos empezar a desarrollar este tipo de tecnologías simples para de a poco ir animandonos a mas. Creemos en la necesidad de encontrar formas más eficientes y limpias de generar energía que respeten el medio ambiente y puedan generar condiciones de autosustentabilidad para las personas.
Solo puedo agregar que me llevé una grata sensación al ver la pasión y las ganas que le ponen. Ojala puedan ser pioneros en la implementación de este tipo de tecnologías simples, eficientes y económicas en Argentina. Otro aporte que considero valioso de ellos es que además fomentan la industria nacional e innovadora.

saludos!

sábado, 5 de diciembre de 2009

Un almuerzo sobre Scrum

Ayer tuve la oportunidad de almorzar con Ingrid Astiz. Ella es miembro de la cómunidad ágil, en el último encuentro de ágiles Buenos Aires dio una charla sobre retrospectivas:

Ingrid me hizo algunas observaciones interesantes respecto a implementar scrum en una empresa. Comparando scrum con las metodologías tradicionales, hay una diferencia de base sutil, pero muy importante.

Las metodologías tradicionales se basan en el control, en cambio scrum se basa en la confianza. Para alguien que quiere implementar scrum, esto es algo que no hay que dejar de ver. Controlar es más fácil que confiar, por lo que es común usar las técnicas de scrum y seguir controlando. Lo difícil es construir confianza.

Ingrid tiene contacto con el mundo de las ONGs y me dio una buena idea respecto al proyecto estamos empezando con Chicho para organizar grupos scouts, la de pensar en una herramienta para eventos auto-organizados, que pueda servir para ONGs y porque no también para la comunidad agile. Sería sin duda un proyecto muy interesante, que podría aportar valor y re alimentarse de una comunidad más grande.

Me contó sobre cómo los animales superan enfermedades como el cáncer, medicinas alternativas que estudian este comportamiento para curar personas, comercio justo, el permacultivo en Argentina, su experiencia al aplicar scrum en una ONG. Fue una conversación interesante.

Que tiene que ver todo esto con scrum? Muchas de estas ideas se basan en algo simple, auto organizado, orgánico, adaptable.

A los que les interese el tema de las retrospectivas, les recomiendo ver la película 12 hombres en pugna.

saludos!

viernes, 4 de diciembre de 2009

Difusión: otra manera de minimizar el impacto ambiental

Algo interesante a la hora de resolver un problema es aprender a mirar fuera del cuadrante para descubrir nuevas posibilidades. Hoy tuve la suerte de charlar con Andrés Navarro, un especialista en energías limpias que me ayudó a abrir la cabeza. Les dejo el link de la charla:
http://dondevuelaelcondor.blogspot.com/2009/12/un-nuevo-amigo-en-el-desafio-del-cambio.html

Una manera de minimizar el impacto ambiental es por ejemplo minimizar la huella de carbono usando paneles solares. Otra manera que me resultó interesante es la de ayudar a divulgar estos temas, para que tomemos conciencia como sociedad.

La 1ra la asocio con un pensamiento lineal / lógico. La segunda con un pensamiento más lateral / creativo. Además, creo que la segunda puede tener un mayor impacto que la 1ra, lo cual la hace una alternativa interesante.

saludos!

miércoles, 2 de diciembre de 2009

Un proyecto abierto, colaborativo y por una causa

Hoy pasé una tarde de cafe con Fernando Chicho un colega que conocí en un campamento hace menos de 2 semanas. Cuando era chico iba a un grupo scout, hace ya varios años (como pasa el tiempo...). Hace poco los chicos del grupo organizaron un campamento donde invitaron a las generaciones anteriores, las raices, los viejos, los dinosaurios. Fue un encuentro muy emotivo para todos.

En ese viaje, hablamos con Fernando sobre hacer un sistema para facilitar la organización del grupo. Hoy nos juntamos y surgieron ideas muy interesantes. Hablamos sobre hacer un proyecto sin fines de lucro, abierto, colaborativo y por una causa. Creo que es interesante comentar los aspectos que charlamos, para destacar que no todo es plata y el potencial que vimos detrás de la idea.
  • Nos interesa que open source, para que cualquiera lo pueda usar. De hecho, si le sirve a otros grupos scout, sería mayor aún nuestra satisfacción personal, ya que estaríamos ayudando a más gente.
  • Abierto, que cualquiera se pueda sumar y colaborar.
  • Desafiante. Queremos que tenga un elevado nivel de calidad, para atraer a más personas que quieran sumarse. Incluso que sirva de aplicación de referencia sobre las tecnologías que utilice. Hablamos de usar TDD y domain driven design, .net. nhibernate, castle winsor, asp mvc, moq, etc.
  • Ágil. Queremos usar scrum para ganar experiencia en la metodología, maximizar el valor generado e incluso invitar a cualquiera que quiera aprender o dar su experiencia en scrum a colaborar. Pensamos que además, esto hace más atractivo el proyecto.
  • En algún futuro, nos gustaría enseñar sistemas a personas con menos recursos y ayudar a insertarlos laboralmente. Por lo que este proyecto puede ser un punto de partida y una buena experiencia sobre trabajar en proyectos colaborativos.
  • Nos gustaría apoyarnos en la comunidad. También nos gustaría aportar cosas a la comunidad.
Luego hablamos de scrum fuera del mundo del software, sobre la posibilidad de hacer talleres de scrum para los chicos que coordinan, con el objetivo de potenciarlos como equipo y darles herramientas que ellos a su vez puedan potenciar a sus equipos.

El simple hecho de mezclar dos mundos que tienen distintos orígenes pero que no son tan distintos fue un gran disparador de ideas.

Se imaginan un campamento donde referentes del mundo agile compartan su conocimiento con los scouts? Y que los referentes participen a su vez que actividades scout aprendan nuevas dinámicas de equipo.

Cada vez encuentro más apasionante trabajar con el potencial de las personas.

saludos!

jueves, 26 de noviembre de 2009

Testing práctico de repositorios y servicios con xUnit

Una técnica para hacer testing unitario de repositorios y servicios es usar mock objects. Si bien está técnica nos permite probar aisladamente una clase (es el objetivo de una prueba unitaria), en casos simples me parece que es más difícil construir el mock que la funcionalidad.

Supongamos que estamos trabajando con un sitio simple de contenidos. Nuestros repositorios pueden ser del tipo:

IContentRepository {
Content GetById(int contentId);
Ilist GetBySection(int sectionId);
}

Y nuestro servicio:

IContentManagementService {
Content GetContentById(int contentId);
Content GetDefaultContent();
Ilist GetBySection(int sectionId);
}

A veces por cuestiones prácticas conviene no seguir algunas reglas (cómo la de usar objetos mock) y testear directamente sobre los objetos que construimos. Un simple assert, puede hacer mucho por nosotros (para repositorios y servicios):

Ilist contents = repository.GetBySection(1);
Assert.IsNotNull(contents);
Assert.IsTrue(contents.size > 0);

Nos puede ayudar a probar varias cosas, como por ejemplo:
  • Que mapeamos bien los objetos en el ORM.
  • Las expresiones de las consultas (hql, linq, sql, etc.) no dan error al ejecutarse.
  • Las dependencias de IoC. Esto puede no servir de mucho, si tenemos un contexto de IoC para test y otro para la aplicación.
  • Si se hicieron cambios en la base de datos no se rompió nada.
  • Que mínimamente todo funciona, lo cual es muy bueno frente a no probar nada.
Estos tipo de test son muy rápidos y fáciles de crear. Lo único que requieren son de una base de datos especial de testing, para que los test no se vuelvan inválidos con el tiempo, ya que es muy probable que los datos en desarrollo cambien.

Incluso con una pequeña modificación se podrían probar las consultas:

Ilist contents = repository.GetBySection(1);
Assert.IsNotNull(contents);
Assert.AreEquals(5, contents.size);

Es cierto que no sería una prueba unitaria 100%, pero tiene una buena relación costo / beneficio.

saludos!

sábado, 21 de noviembre de 2009

Integración kudewe reports con sistemas legacy

Un punto importante a resolver en una herramienta de reporting es la integración con otros point solutions. Lo primero que pensé fue en una herramienta tipo ETL para extraer los datos de los point solutions, transformarlos y cargarlos en kudewe reports. Buscando encontré esta lista open source:

Quería algo liviano, simple y fácilmente testeable. Algunas de estas herramientas son visuales (kettle, cover etl, talend) seguramente en poco tiempo y sin conocimientos de programación se pueden construir procesos ETL simples. Pero una desventaja es que no tienen automatizados los test (al menos que yo sepa). Leyendo en la lista me encontré con spring batch.

Estás son algunas características interesantes de spring batch:
  • Tiene un lenguaje de dominio muy claro del mundo batch.
  • No tengo que aprender una herramienta nueva, toda la aplicación está construida en java.
  • Clear separation of concerns.
  • Basado en objetos POJO => simple y fácilmente testeable.
  • Cada pieza se puede testear unitariamente, como así también todo el punta a punta.
  • Es escalable, probada, sigue la filosofía de spring.
  • Se complementa con herramientas de schedule, tipo quartz.
El objetivo de este sprint es integrar kudewe reports con una aplicación web asp / ms access. Dado que es la primera vez que hago algo parecido, hay algunas cuestiones que presentan ciertos riesgos y que por lo tanto conviene encararlas tempranamente. Por eso, lo primero a resolver es cómo conectarse a una base de datos ms access desde java. Intenté hacerlo desde ubuntu, pero no encontré como. Leí algunas cosas de un puente odbc-jdbc, pero me parecieron complejas. Por lo que opté hacerlo desde windows, que es el entorno de mi cliente. Para eso encontré un ejemplo simple:

si queremos acceder a través de un dsn, este otro ejemplo explica como:

Lo siguiente es ejecutar los ejemplos de spring batch. Para eso tuve que instalar maven

y agregar a eclipse.ini la ubicación de la vm (requerido por maven, importante escribir la configuración en 2 líneas):
-vm
C:\Archivos de programa\Java\jdk1.6.0_17\bin

Luego, para abrir los ejemplos de spring batch solo que hay crear un nuevo proyecto java en eclipse y seleccionar la carpeta que contiene el ejemplo. Automáticamente se instalarán las dependencias configuradas en el archivo .pom.

Ahora a revisar el ejemplo spring-batch-simple_cli para hacer la prueba de concepto...

saludos!

domingo, 15 de noviembre de 2009

Equipos auto organizados: la cordada

Algo interesante de scrum es que puede aplicarse a otras actividades, no solo al desarrollo de software. De hecho, me imagino sería muy enriquecedor usarlo en escenarios que no tengan nada que ver.

Muchas de las cosas que plante scrum no son nuevas, como por ejemplo los equipos auto organizados. Es muy interesante la dinámica de un equipo que no sigue las reglas de un líder, sino donde el liderazgo es emergente y contextual.

El primer ejemplo que se me ocurre es la cordada. Una cordada es un grupo de personas con un objetivo en común: escalar. Se le llama cordada porque generalmente van encordados (atados). El ir atados es algo muy simbólico para un equipo. Uno a uno los integrantes de van exponiendo al riesgo y los otros lo protegen a través de la cuerda.

Encontrar la mejor manera de escalar una montaña es un problema realmente difícil. Es prácticamente imposible planificarlo todo de ante mano. Generalmente antes de salir acordamos qué equipo llevar, cuanta comida, días, etc. Pero sobre la marcha el equipo se va auto organizando según el contexto. Puede ser que el clima cambie, o que uno se sienta mal o más fuerte o con más ganas. Hay miles de factores que pueden influir.

Me acuerdo de una vez que empezamos a escalar de noche y nos íbamos turnando para abrir huella en la nieve. No pasó que el líder de la expedición dijera "cada uno camina 20 minutos al frente y se va rotando". Todo lo contrario, no había líder. Simplemente acordamos ir caminando por turnos, el que va adelante controla el ritmo y cambia cuando se siente muy cansado o cuando considera que otro puede hacer mejor el trabajo. Y todo se hace en función del equipo, no del interés de un individuo. Según mi experiencia en la montaña, este tipo de dinámicas son muy integradoras y generadoras de buenas amistades.

saludos!

miércoles, 11 de noviembre de 2009

2do día Curso Scrum Master

Durante el segundo día de scrum aprendí un poco más sobre el framework. Hicimos un juego muy bueno en donde construimos algo en 4 sprints, usando user stories, autorganizándonos como equipo haciendo pequeños plannings y retrospectivas. Fue una actividad muy dinámica en la que aprendí scrum haciendo. Ya voy a poner una foto de nuestro "producto".

Otra actividad que me pareció muy buena fue un role play de una daily meeting en un proyecto que "quema". El PO participó de la reunion con un rol activo (en lugar de escuchando), de hecho fue el 1ro que habló y tiró la bomba. El equipo reaccionó hechando culpas, fue un momento tenso. La cosa estaba muy dicícil para el scrum master, tanto que terminó renunciando. Pero entre todos pudimos aprender mucho haciendo una retrospectiva en conjunto.

La daily meeting es una reunión para detectar problemas, no para resolverlos. Es una reunión para el equipo, donde se crea un espacio para descubrir impedimentos. Es importante no olvidar esto, para pedir al PO que no intervenga (él tendrá su momento en la demo o en una meeting especial) y que cada miembro del equipo explique sus problemas sin buscar culpables, para que no se pierda el objetivo de la reunión.

Algo que me llevo de este segundo día es que el trabajo de scrum master no es nada fácil, todo lo contrario. Pero también es desafiante, ya que se trabaja con el potencial humano y lo que éste puede conseguir. Un buen scrum master debe ser un buen facilitador, mantener discusiones abiertas y guiar el equipo por zonas de incomodidad para que al final todos mejoremos.

lunes, 9 de noviembre de 2009

1er día Curso Scrum Master

Hoy asistí al 1er día de entrenamiento de scrum master. Si bien solo vamos la mitad del curso, me pareció buenísimo la dinámica con que se dicta (gracias a Alan y Ariel). Esta ver no quiero comentar sobre scrum, sus roles/responsabilidades, flujos y artefactos. Sino de algo que creo que va más allá de scrum y está presente en casi toda actividad, que tiene que ver con formar equipos, buenos equipos.

Si bien scrum ayuda mucho a conseguir esto, llevarlo a la práctica encierra un desafío muy grande. Ese desafío tiene que ver con sembrar confianza, fomentar la colaboración, potenciar a las personas, generar transparencia, etc.

Algo que rescato de este enfoque es que se trata de un objetivo que trasciende a lo que hacemos todos los días. Va más allá de construir un ABM o probar una funcionalidad. Se trata de mejorar el entorno en el cual trabajamos, de que todos mejoremos profesionalmente, de construir sobre valores. Suena muy idealista, pero es la base para construir un buen equipo, en cualquier ámbito.

Podré decir alguna vez como Pinti:
Pasan los años, pasan los gobiernos,los radicales y los peronistas, quedan los scrum masters?




domingo, 8 de noviembre de 2009

Instalar SVN en Eclipse Galileo y Ubuntu 9.10

Luego de actualizar Ubuntu 9.10 y bajar Galileo, me pasó que dejaron de andar algunos botontes en eclipse. Por suerte encontré cómo arreglarlo:

Tuve algunos problemas para instalar tigris svn (me dejó de andar el eclipse ganymede, por lo que me bajé el galileo). Asi que sobre el galileo instalé subversive svn:

Luego de esto pude subir sin problemas el proyecto a google code:


saludos!

sábado, 7 de noviembre de 2009

Publicando Kudewe Reports Web en el mundo open source

Hoy voy a publicar en google code el código del front end de Kudewe Reports, que se llama Kudewe Reports Web (me maté con el nombre). Se trata de una herramienta web de reporting que permite fácilmente construir tableros de control (dashboard) que contienen vistas (grillas y gráficos) y filtros (por ahora tipo combo).

Esta es la url del repositorio en goolge code:
http://code.google.com/p/kudewe/source/browse/#svn/trunk/reportsWeb

El front end es una aplicación web estática html + javascript estándar, basada en el framework extJs. Me decidí por usar un front end que sea independiente de la tecnología server side, para que cualquiera lo pueda usar, ya sea .net, java, php, etc. También elegí esta alternativa para poder en el futuro agregar la posibilidad de funcionar de manera offline. En mi caso un front end independiente de la tecnología server side me resultó fácil armar y fácil de testear.

Estas son unas demos que armé:

En mi caso estoy usando como pegamento entre el client side y server side spring web y url amigables:

Algo interesante, y sobre lo que tengo que escribir, es que la aplicación está construida como una composite web application. Los filtros y las vistas tienen bajo acople entre si. Pasa eso estoy usando un patrón tipo publish/subscribe implementado con Tibco PageBus.

También me gustaría armar algunos tests usando selenium. Esto es algo que podría hacer fácilmente, ya que el front end no tiene dependencias a ninguna tecnología server side. Cuando este ejecuta un servicio json, el webserver devuelve un archivo ubicado en el path solicitado. Por ejemplo:

services/menu.json: Devuelve el menú de la aplicación
services/sales/yearly.json: Devuelve la definición del dashboard "yearly"
services/sales/yearly/filter/brand: Devuelve el filtro "brand" del dashboard "yearly"
services/sales/yearly/view/byBrand: Devuelve las ventas por marca "byBrand" del dashboard "yearly"

saludos!

Sol + sal = energía

Gracias a idea connection, me enteré de una manera innovadora de generar energía a partir del sol.

Algo parecido había visto hace tiempo, donde leí que google estaba investigando en tecnologías de espejo para abaratar los costos de generación de energía (http://energiasolarok.blogspot.com/2009/09/google-por-la-energia-solar.html)

Me alegra escuchar sobre nuevas iniciativas que ayudan a que esto sea cada más fácil de implementar. En nuestro país la energía solar no es barata, un panel de 80w vale aproximadamente $2500. Todavía tenemos que trabajar en disminuir estos costos, para que este tipo de alternativas sean más accesibles y más personas se animen a utilizarlas. También me parece importante que empecemos a pensar sobre estos temas y a cambiar nuestras prioridades. Me viene a la mente una frase que me sirve para poner las cosas en perspectiva:

No heredamos la tierra de nuestros padres, sino que la tomamos prestadas de nuestros nietos.

saludos!

domingo, 1 de noviembre de 2009

De la relación de dependencia al emprendimiento

Últimamente me pasa seguido de conversar con amigos respecto a trabajar en otra cosa, algo propio. Lo que compartimos en general es que después de estar algunos años en el mismo trabajo, es difícil mantener la motivación.

Una vez escuche en una charla de @bilinkis, que las empresas buscan el engranaje que mejor encaje en su maquinaria. El problema con esto es que nosotros somos personas, no engranajes, tenemos particularidades que nos diferencias y es en nuestras particularidades donde se esconde nuestro potencial. Por lo que en una empresa se hace realmente difícil explotar ese potencial al máximo. Con lo años, uno se va acostumbrando a cómo hacer las cosas para que la maquinaria funcione mejor y poco a poco se va aplacando eso que nos hace distintos.

Muchos me dicen que estando por tu cuenta trabajás más. Si bien esto es algo que parece cierto, ya que conozco algunas experiencias que lo confirman, creo que en mi caso prefiero trabajar 12hs motivado que 8 sin motivación.

Así que este post es para los que buscan motivación en el trabajo. En mi caso me ayudó mucho empezar a leer blogs sobre enterpreneuship. Este fue uno de los primeros que leí, que habla sobre la transformación de desarrollador de software a emprendedor de software:

Este es otro muy bueno, que habla sobre cómo conseguir clientes, organizar el tiempo, etc:

Uno muy bueno, para empezar a concretar algo, es el Santiago Bilinkis:

Me han servido de mucha ayuda sus post para bajar una idea a algo más concreto y empezar a enfocarme:

Ahora me pasa que tengo en claro lo que quiero hacer (construir aplicaciones de software usando energias limpias), de hecho ya estoy trabajado en la primera: kudewe reports. Sin embargo, necesito dedicarle más tiempo a este proyecto. No estoy en condiciones de abandonar mi trabajo actual para dedicarme de lleno a esto, ya que en el super no me pagan por mis aportes a la humanidad.

Pero buscando y buscando encontré una solución, conseguí un trabajo de 4 días a la semana que además es un interesante desafío profesional (.net, arquitectura, scrum). Por lo que ahora puedo dedicar más tiempo a este proyecto.

saludos!

martes, 27 de octubre de 2009

Tuneando la performance de sitios web

Este post describe distintas técnicas de optimización de performance para sitios web. Se basa en la experiencia de una aplicación de reporting construida en asp.net con fuertes constraints de performance (tiempo de ejecución por debajo de 2 segundos para accesos locales y 8 segundos para accesos remotos), teniendo una conectividad pobre desde sitios remotos.
Sin embargo estas técnicas aplican a cualquier aplicación tipo web/html. Las implementaciones y ejemplos de código se corresponden a una aplicación asp .net 2.0, c#, IIS 6, pero pueden extenderse a otras tecnologías.
Un buen lugar para empezar a abordar este tema es el sitio de best practices de yahoo (se pueden encontrar muy buenas recomendaciones):

Según una investigación realizada por ellos (http://yuiblog.com/blog/2006/11/28/performance-research-part-1/), al acceder a una aplicación web el tiempo de download se distribuye un 20% en html y el 80% restante en otro tipo de contenido (javascript, imágenes, etc.) Por lo tanto la primera recomendación es:

Minimizar la cantidad de gets (roundtrips)

Esto puede conseguirse de distintas maneras:

Unificar archivos javascript

En nuestro caso tenemos un archivo .js para cada funcionalidad, de manera tal de hacer el desarrollo más modular. Al armar la version release los unificamos y comprimimos en un único archivo. Lo mismo se puede hacer para las hojas de estilo. Se debe tener en cuenta que cuanto mejor formado esté el código javascript (usando llaves para todas las instrucciones aunque no sea necesario, ";" al final de cada línea, etc.) mayor será el nivel de compresión que se puede aplicar.

Para unificar los archivos utilizamos una simple pagina .aspx que contiene un include a cada fuente javascript. Luego la aplicación detecta si está en modo debug o relase (usando HttpContext.Current.IsDebuggingEnabled) y en función de esto genera del lado del server las referencias a fuentes javascript necesarias.

Juntar varias imágenes en una (css sprite)

Esta ténica se conoce como css sprite. Básicamente se arma una imagen con las imágenes más utilizadas por la aplicación y se referencia con estilos a porciones de esta imagen. Ejemplo:
Definicion de clase para icono de ayuda:
.imgHelpIcon { background: url('/App/Cached/sprite.gif') 0 0 no-repeat; font:1pt; background-position: 10 -20px; width: 15px; height: 15px; }

Uso del estilo:
<span class="imgHelpIcon"></span>

Utilizar cache infinito para recursos estáticos

Esta técnica tiene gran impacto en el download, sobre todo si la mayoría de los usuarios utilizan frecuentemente la aplicación. Con esto se evitan los gets a estos recursos, incluso si el cache del browser está configurado como "every visit to the page".

En nuestro caso lo implementamos de la siguiente manera. Configuramos en el webserver una carpeta cached con fecha de exipiracion en 2035. De esta manera disponemos de 2 altenativas para almacenar los recursos estáticos (con y sin cache). Por ejemplo en modo debug la aplicación utiliza los scripts de la carpeta app/scripts. En cambio, en modo release utiliza app/cached/scripts.

Para los recursos que pueden cambiar (como js y css) los versionamos agregando un parametro a la url. Por ejemplo:
<script scr="cached/all_js.js?v=1.01"></script>

Para recuperar este valor usamos el método ConfigurationManager.AppSettings.Get("jsVersion"). Cada vez que se arma un release, incrementamos este número solo si se realiza un cambio sobre algún fuente javascript.

Aplicando esta técnica a los recursos estáticos, los gets de usuarios frecuentes se redujeron a práctiamente solo uno para obtener el html (ya que el browser recupera todos los recursos estáticos del cache). Esta técnica mejora notablemente los tiempos de acceso desde clientes remotos.
Quitar seguridad integrada a recursos estáticos

Los recursos con seguridad integrada implican 2 o 3 roundtrips al server según el tipo de autenticación. Por lo tanto es conveniente evitarla siempre
que sea posible.

Quitar seguridad integrada a servicios ajax

En algunos servicios ajax se necesita información del usuario para resolver ciertas funcionalidades. Para evitar la seguridad integrada, el usuario forma parte del estado en el server (más adelante se explica mejor cómo resolver esta cuestión). De esta manera todos los servicios ajax se ejecutan sin seguridad integrada.

Quitar seguridad integrada de aplicación.

Aplicar esta técnica nos llevó un poco más de trabajo. Básicamente solo una página (authenticate.aspx) está configurada con seguridad integrada. Cuando el usuario ingresa a la aplicación, esta intenta obtener el usuario del estado. Sino lo puede obtener, entonces asume que no está autenticado, lo redirecciona a authenticate.aspx para que obtenga las credenciales del usuario, lo guarde en el estado y lo redireccione nuevamente a la aplicación. Luego el usuario navega por la aplicación sin seguridad integrada (la aplicación verifica que el usuario esté autenticado usando una variable de sesión).

Al implementar este mecanismo nos encontramos con un problema grave. IE 6 tiene un bug donde a veces no envía los parámetros enviados por post (http://blogs.msdn.com/david.wang/archive/2005/12/01/HTTP-POST-Fails-for-Anonymous-Authentication.aspx). Esto lo solucionamos configurando acceso anónimo y seguridad integrada a la vez.

Si reducimos todo lo posible la cantidad de pedidos al server (GETs) lo siguiente que podemos hacer es reducir el tamaño de la información intercambiada.
Reducir el tamaño de los gets / responses

Comprimir javascript y css

Existen varias herramientas para hacer esto (http://developer.yahoo.com/yui/compressor/). Estas herramientas básicamente eliminan espacios, comentarios, incluso algunas hasta ofuscan el código para reducir su tamaño.

Reducir tamaño html

La idea es simple, cuanto menos se envíe, más rápido va a terminar la transferencia. Se pueden hacer varias cosas para reducir el html:
  • Eliminar espacios
  • Utilizar nombres abreviados para los nombres de estilos y objetos
  • Maximizar el uso de hojas de estilo, dejando el html mucho más limpio. Una herramienta muy útil para hacer esto son los css selector (http://www.w3schools.com/Css/css_syntax.asp)
  • Manejo de estado
La aplicación persiste el estado en el server. En lugar de utilizar campos hidden en el cliente (que se envían en cada postback), utiliza variables de sessión para persistir los cambios realizados sobre un reporte (filtro, paginado, drill, etc.). De esta manera el cliente solo envía al server lo que cambia, reduciendo considerablemente el tamaño de los requests.

Mantener estado en el cliente usando user behaviour

Esto se puede aplicar en los casos que solo se necesita persistir información en el cliente y esta no es requerida por el server (ejemplo: estado de apertura de un árbol). Internet explorer ofrece un behavour que permite persistir información en el cliente (incluso cuando el usuario cierra el browser):

Ajax + json / xml

El los casos donde los servicios ajax devuelven datos, usamos json ya que es más liviano que xml. Solo en algunas ocaciones, cuando el servicio ajax devuelve html, usamos xml. En este caso el html se devuelve dentro de un cdata para evitar problemas de encodeo.


Otrás técnicas que no usamos, pero también son de ayuda

Compresión gzip

Es posible configurar IIS para que comprima gzip archivos javascript y estilos. El beneficio de la compresión gzip es notorio cuando se accede remotamente. También es posible comprimir recursos dinámicos como páginas aspx.

Usar varios dominios para el download de contenido

Por default el browser usa 2 conexiones por dominio para hacer el download. Si el contenido cambia (como ocurre por ejemplo en los portales), es posible utilizar distintos dominios para el mismo, de manera tal de aumentar la cantidad de conexiones usadas por el browser.

En el sitio de yahoo hay otra recomendaciones:

Herramientas

En nuestro caso fue fudamental usar máquinas virtuales como entorno de desarrollo para poder experimentar con estas técnicas y contar con máquinas tipo desktop estandar en sitios remotos para poder evaluar el impacto de las mismas. También nos sirvió de mucho usar un debugger http como fiddler (http://www.fiddlertool.com/fiddler)

Fiddler permite ver gráficamente cómo es el tiempo de download. Para ello, se debe activar el modo streaming (http://www.fiddlertool.com/Fiddler/help/Streaming.asp). Con esta herramienta es fácil encontrar puntos de mejora, revisar errores http 404, ver el impacto de aplicar estas técnicas, etc.

jueves, 22 de octubre de 2009

Cuál es la instalación de paneles solares más sustentable?

Desde hace un tiempo vengo trabajando en esta idea. Conseguí una lista de los proveedores en Argentina (http://www.energiaslimpias.org/categoria/informes-energia-solar/) y me contacté con todos para consultar por una instalación para hacer andar una notebook (80w) durante 8hs x día.

La típica instalación está formada por los paneles solares, regulador (para no sobre cargar la batería), batería (para acumular la energía y usarla cuando no hay sol), inversor (para convertir los 12v de continua de la bateria a 220v de alterna). Encuentro algunas desventajas a este tipos de instalación:
  • Son costosas => difícil que otros quieran implementarlas también.
  • Podrían ser mas eficientes, ya que se pierde energía en el regulador, inversor y cargador de notebook.
  • Requiere varios paneles solares (los paneles se colocan orientados al norte, a 50 grados aproximadamente).
  • Plantean el problema de qué hacer con la batería cuando finaliza la vida útil de esta.
Por lo que se me ocurren algunas variaciones sobre este esquema básico:
  • Usar un único panel solar y orientarlo al sol según la hora. Tendría que buscar la manera de automatizar esto... O podría combinarlo con la técnica pomodoro y aprovechar los breaks para subir a la terraza (me levanto de la silla) y acomodarlo a mano.
  • No usar un inversor y trabajar siempre en corriente continua. Necesitaría un cargador para la notebook que a partir de 12v genere los 19.5 que necesita (encontré uno).
  • Si en lugar de usar batería para acumular la energía, utilizara directamente la batería de la notebook? Como podría hacer para no afectar la vida útil de esta? Luego tendría que ver que hacer con la energía que no uso. Podría volcarla a la red, como hacen en otros paises, o regalarla a mis vecinos.
  • Sirve el regulador para que los paneles generen 12 v constante?
Algo interesante de no usar baterías, es que además de disminuir el costo y contaminar menos, abre nuevas posibilidades que requieren pensar de manera colaborativa respecto a la comunidad en donde vivimos.

saludos!

domingo, 18 de octubre de 2009

Parser para un simple DSL

Dado que estoy empezando a usar un DSL, me gustaría compartir mi experiencia, por si otros deciden incursionar en el mundo de los DSL. Voy a aprovechar para contar que me lleva a usar un DSL.

Uno de los problemas de mi dominio es resolver el binding de los filtros, pertenecientes a mi domain model, en una consulta MDX. Para eso adopté la siguiente sintaxis:

SELECT {[Measures].[SaleAmount], [Measures].[Profit]} ON COLUMNS,
NON EMPTY {[Brand].[All].Children} on rows
FROM [Sales]
WHERE (${category}, ${product}, ${year})

donde si category=A, product=B, y year no tiene valor, la query debería valer:

SELECT {[Measures].[SaleAmount], [Measures].[Profit]} ON COLUMNS,
NON EMPTY {[Brand].[All].Children} on rows
FROM [Sales]
WHERE (A, B)

MDX es un DSL usado para resolver consultas multidimensionales. Lo que estoy haciendo es embebiendo mi DSL adentro de otro DSL (por ahora es tan simple, que no merece llamarse DSL).

El primer paso para usar mi DSL es parsear los ${...} para extraer la expresión del mismo. Seguramente hay muchas formas de parsear los ${...}. Yo decidí usar un tokenizer basado en palabras, que devuelve el texto hasta encontrar el token buscado. Esta es la interface de WordTokenizer:

la implementación basada en la clase String:

y las pruebas unitarias (aguante TDD):

Es simple extraer es las expresiones de mi DSL usando el word tokenizer:

Con esto extraigo mi DSL de la consulta MDX. Este por ahora es simple, pero hay casos que tienen un poco más de complejidad.

Por ejemplo, si un filtro no tiene valor, tengo que aplicar el valor default:

SELECT {[Measures].[SaleAmount], [Measures].[Profit]} ON COLUMNS,
NON EMPTY {[Brand].[All].Children} on rows
FROM [Sales]
WHERE ${year.default([Time].[Year].[2009])}

O distintos filtros que forman una jerarquia (mes, trimestre, año) y solo debe reemplazarse un valor en la consulta:

SELECT {[Measures].[SaleAmount], [Measures].[Profit]} ON COLUMNS,
NON EMPTY {[Brand].[All].Children} on rows
FROM [Sales]
WHERE ${month.parent(quater).parent(year)}

O una combinación de jerarquías y valores default. Para resolver estos y otros casos, usé lo que se llama fluent interface, que permite fácilmente armar DSL para un problema de dominio (es fácil de leer y simple de programar).

Para parsearlo uso un simple StringTokenizer:

La implementación es bastante simple. Seguramente hay casos que no se cubren, pero sobre esta base es fácil agregar nuevos métodos al DSL.

Hay otros conceptos interesantes asociados a un DSL, como:

saludos!

martes, 6 de octubre de 2009

Problema paneles solares y mapa mental

Gracias a http://www.softwarebyrob.com/2009/10/06/micropreneur-spotlight-online-mind-mapping-software-thoughtmuse/ encontré una herramienta en la web para armar mapas mentales. Me pareció muy buena para organizar las distintas aristas de un problema. Asi que aproveché para hacer el ejercicio de alimentar una notebook con paneles solares

Aportes son bienvenidos!

domingo, 4 de octubre de 2009

Expandir disco guest ubuntu, host vista (vmware player)

Hoy me pasó que la virtual con ubuntu se quedó sin espacio en disco (la imagen original tiene 8 GB). Mi sistema operativo host es windows vista y la tengo una virtual machine con Ubuntu Desktop 9.04 (con vmware player).

Estos son los pasos para agrandar el tamaño del disco a 100 GB.

1. Convertir el disco a 2GB split not pre-allocated usando vmware converter. Se puede bajar de la página de vmware.

2. Crear con easyvmx una imagen ubuntu de 100GB. De paso aproveché para configurar 2 procesadores:
http://www.easyvmx.com/cgi-bin/create-easyvmx.cgi?filetime=2009-10-04-23:08:06&vmname=Ubuntu+9.04+Desktop&guestOS=ubuntu&memory=2048&numvcpus=2&vmdesc=UbuntuDesktop&vmlname=UbuntuDesktop&vmurl=http://www.kudewe.com/&hwaddr0=00:0c:29:46:9c:10&conntype0=nat&devtype0=vlance&hwaddr1=00:0c:29:51:cf:6c&conntype1=nat&devtype1=vlance&floppyfile=autodetect&isodev=autodetect&ide1_1file=.iso&disk0_0file=100Gb&disk0_1file=4800Mb&sound=yes&soundcard=es1371&usb=yes&usbconnect=FALSE&com1=yes&com1_flow=TRUE&com2_flow=TRUE&lpt1=yes&lpt1_bidir=TRUE

3. Copiar de la maquina virtual original los archivos de disco Ubuntu_9_04_Desktop-s001.vmdk, Ubuntu_9_04_Desktop-s002.vmdk, Ubuntu_9_04_Desktop-s003.vmdk, Ubuntu_9_04_Desktop-s004.vmdk. No copiar el Ubuntu_9_04_Desktop-s005.vmdk (último archivo)

4. Bajar gparted.iso. Configurar la vm para que vea la iso como cd rom

5. Bootear desde cd, para eso presionar esc cuando bootea vmware. También se puede modificar grub de ubuntu para bootear de cd: http://www.ubuntu-es.org/?q=node/65741

6 Una vez que arranca gparted, es una buena oportunidad para redimensionar el tamaño de la partición swap (originalmente tiene 400 Mb).
https://help.ubuntu.com/community/SwapFaq

Después de estos pasos quedó todo andando sin problemas (milagro!)

martes, 29 de septiembre de 2009

Desarrollar software usando energías limpias

Una idea que vengo trabajando desde hace un tiempo es la de hacer algo para revertir el calentamiento global. Cómo dice el dicho popular "mejor empezar por casa", asi que me propuse estos objetivos:
  • Desarrollar software usando energías limpias. Creo que un objetivo más genérico sería el de minimizar el impacto ambiental.
  • Crear un emprendimiento donde la responsabilidad ambiental sea tan importante como el corazón del negocio. Me gustaría llamarlo algo así como la organización sustentable ideal.
  • Servir de ejemplo / modelo a otras organizaciones y personas. Ayudar a otros a hacer lo mismo.
Si simplificara la actividad de desarrollar software actual, podría decir que consiste en usar una computadora durante 8 hs, 5 días a la semana. Un primer paso para conseguir lo anterior sería imaginar qué cosas podría hacer para que esa computadora funcione con energías limpias.

Algunas ideas:
  • Usar paneles solares.
  • Mudarme a un lugar donde haya viento para usar energía eólica.
  • Idem, pero hidraúlica.
  • Usar una notebook en lugar de una pc, ya que tiene menor consumo. Y dentro de las notebooks, una con bajo consumo.
  • La rueda del hámster, pero para mi perro (un bóxer incansable).
  • Generar electricidad con bicicleta fija o cinta de correr (además entrenaría).
  • Ser más productivo, o que el software sirva a más personas y optimice recursos (lo tengo en la punta de la lengua: cloud computing + software as a service).
  • Trabajar en los horarios de mayor luz solar. Trabajar los días de la semana de mayor luz (si está nublado, trabajo menos). Trabajar más en verano que en invierno (interesante para los que les gusta el montañismo invernal). Trabajar más cerca del sol (delirante...)
De todas, creo que las más aplicables son la notebook, cloud computing, software as a service, mejorar la productividad (metodologías ágiles, TDD, etc.) y las relacionadas con la energía solar… Otras ideas son bienvenidas!

domingo, 27 de septiembre de 2009

1ros pasos con Spring Security

Spring Security es uno de los mejores framework de seguridad web del mundo java. Esta basado en Acegi, un proyecto que luego paso a formar parte de spring. Para mi, una de sus mejores caracterísitcas es que no es invasivo, es decir, no me obliga a modificar mi código o tener alguna consideración para usarlo.

De hecho, yo empecé a construir la aplicación sin tener en cuenta ninguna cuestión de seguridad y ahora agrego este framework sin modificar el código existente. Es probable que tenga que crear código, como un provider de autenticación para que acegi pueda validar usuario y password, pero gracias al principio de diseño "programar hacia interfaces, no implementaciones" y al DI container (spring) no tengo que modificar el código ya existente, lo cual me recuerda otro principio "cerrado para modificación, abierto para extensión".

Configurar acegi era una tarea compleja, la primera vez que lo hice me llevo tiempo. Pero estos tutoriales me ayudaron mucho:

Para entender como funciona acegi:

Ahora, unos años después, leo que spring security facilitó esta tarea:

Paso a paso para configurar spring security:
1. Bajar spring security

2. Copiar spring-security-core.jar a WEB-INF/lib

3. Configurar web.xml. En este caso configuré el http filter (chain of responsability) de spring security para que verifique seguridad solamente sobre los request a /services y a *.html. El resto son recursos estáticos que no requieren seguridad:

4. Configurar spring security context:

Con esto tenemos una aplicación web con seguridad básica basada en spring security. El framework provee muchas más funcionalidades:

Saludos!

jueves, 24 de septiembre de 2009

Creatividad según Einstein

Hoy encontré una nota sobre uno de los creativos más grandes de la historia, Einstein. Casualmente estoy leyendo un libro llamado "Cómo pensar cómo Einstein", donde habla principalmente de romper las reglas y encontrar nuevas soluciones fuera de las restricciónes.


Muy inspirador... Algo interesante para agregar a la creatividad y trabajo en equipo es el de sumar un desafío al equipo.

sábado, 19 de septiembre de 2009

Refactoring como estrategia de construcción

Hace unos años me encontré con un libro muy interesante: Refactoring to Patterns de Joshua Kerievsky

Si bien este libro presenta un catálogo de escenarios o casos sobre los que es un código poco sano se refactoriza a un patrón de diseño, lo más interesante para mi es el enfoque con el que se trata el tema. Cuando construimos software muchas veces no se tiene claro cual es el alcance. Las metodologías ágiles, XP, asumen esto como una regla del juego y se organizan en función del cambio. Una frase muy conocida al respecto es "Lo único constante en el desarrollo de software es el cambio".

El libro introduce 2 ideas que dan claridad al problema de diseñar una aplicación: la sobre ingeniería, que vendría a ser como matar un mosquito con un misil tele dirigido, y la sub ingeniería, donde el problema radica en que la complejidad del código pasa a ser una limitación importante a la hora de modificar una aplicación. De alguna manera, diseñar implica encontrar un equilibrio entre estos dos caminos para lidiar con la complejidad y el cambio. Por lo que es necesario diseñar a lo largo de todo el proyecto.

Qué es refactorizar?

Refactorizar es mejorar el diseño de un código existente. Y también una estrategia de construcción muy eficaz. Podemos comenzar a construir una aplicación, de la manera más simple posible, y refactorizarla a medida que entendemos mejor su contexto y alcance. Esta idea, tomada del mundo XP, fue para mi en un proyecto pasado, una estrategía que resultó clave para llegar a buen puerto. Por lo general no se encuentra el diseño adecuado en el primer intento. De hecho, es bueno darse un tiempo para probar una idea y aprender.

Para qué Refactorizar?
  • Para simplificar el código y responder mejor a los cambios.
  • Para aprender a lidiar con la complejidad en un entorno cambiante.
  • Para hacer el esfuerzo justo.
  • Para potenciar al equipo, es muy didactico refactorizar de a pares, mejora los skills de programación de todos.
  • Para simplificar. Lo simple es mágico, todo es más fácil cuando es más simple.
Cuando refactorizar?

Esta es quizás la pregunta más difícil de responder, ya que depende del caso. Si se refactoriza demasiado tarde, puede ser muy costoso. Demasiado temprano, puede ser que todavía no conocemos suficiente del problema. Pero hay ciertas cosas que podemos oler, que nos dan una idea sobre piezas de la aplicación que no son sanas:
  • Esto es difícil de entender (complejo).
  • Siempre lleva mucho tiempo modificar esto (rígido ante cambios).
  • Cuando tocamos esto, surgen bugs que no detectamos.
  • Es difícil de testear.
Una lista de cosas que huelen mal en el código:

Refactorizar es como invertir en la salud de la aplicación. Tiene un efecto que mejora las condiciones de éxito. Una buena práctica es ir agregando los casos encontrados al backlog y priorizarlos junto como un ítem más en función de las necesidades del negocio.

Cómo refactorizar?

Hay muchas técnicas que ayudan a hacer refactoring efectivamente, como TDD, inyección de dependencias, patrones de diseño, herramientas de refactoring (resharper, eclipse), catálogo de refactoring, etc. Además es importante entender porqué el código no es sano y cómo lo mejoraremos, invirtiendo el esfuerzo justo.

Un enfoque muy interesante del libro, es que para evaluar la solución de refactoring, propone distintos puntos de vista.
  • Comunicación: De que manera el código comunica lo que hace.
  • Duplicación: La duplicación hace que sea más fácil cometer errores. El código duplicado es más difícil de mantener => evitar la duplicación.
  • Simplicidad: Cómo se puede hacer más simple? Para esto es muy importante encontrar el patrón de diseño adecuado.
Se me ocurren otros puntos de vista que se podrían agregar:
  • Testeabilidad: Que tan fácil es de testear?
  • Flexibilidad: Que tan fácil es de cambiar?
  • Esfuerzo: Como llevaría menos esfuerzo?
Más links en delicious

saludos!

lunes, 14 de septiembre de 2009

Grupo Estudio Patrones Diseño

Hace unos años tuve la inquietud de compartir con otros lo que había aprendido acerca de patrones de diseño. Lo primero que pensé fue que no quería hacerlo de manera convencional, es decir, una persona expone un tema y el resto escucha pasivamente. Asi que buscando información sobre como enseñar efectivamente, encontré este link muy interesante que explica cual es la dinámica de un grupo de estudio:

Bien cierto es que uno aprende más cuando lee, escucha, hace y habla, que cuando solo escucha.

Básicamente en un grupo de estudio se forma por gente con interés sobre un tema, de distintos niveles de conocimiento (la diversidad es un factor importante que mejora el aprendizaje del grupo). Un moderador organiza las sesiones (por ej. semanales), comparte con el grupo un material de lectura que todos deben leer previamente antes de asistir y luego durante el transcurso de cada sesión plantea al grupo preguntas abiertas. En este punto la diversidad es importante, porque permite que los que menos saben aprendan y aporten preguntas al grupo. Y los que más saben, que aprendan mientas comparte su conocimiento.

Las preguntas abiertas no son cualquier clase de pregunta. Son preguntas que nos hacen pensar y nos ayudan a tener un mejor conocimiento del tema. Por ejemplo "cuantos patrones de diseño hay?" no es una pregunta abierta. Una pregunta abierta sería algo como "qué patrones de diseño aplican el principio encapsular lo que varía?". Las preguntas abiertas invitan a la reflexión y al debate.

Lo siguiente que tuve que buscar fue un buen material de lectura, que sea fácil de leer y que requiera poco tiempo. Por suerte me encontré con este libro, que tiene una muy buena pedagogía para enseñar:

Finalmente, armar una agenta orientativa sobre los temas a tratar en cada sesión. Comparto los grupos en los que participé:

Algo que creo fue valioso es usar la primera sesión para explicar la dinámica del grupo de estudio, presentar el material, los objetivos y sensar las expectativas de los participantes. Como este tipo de capacitación requiere participación activa, es muy importante aprovechar la 1ra sesión para romper el hielo. En nuestro caso hicimos un juego donde 2 equipos debían construir una casa con rastis. Luego agregar una ventana. Y finalmente explicar que patrón de diseño de casas hubieran aplicado al construir la casa para luego agregar una ventana más eficientemente. Más allá de la analogía con la construcción de software, que puede ser cuestionable, sirvió para introducir el concepto de qué es un patrón y para crear un ambiente que favorezca la participación.

No menos importante fue la última sesión, donde como ejercicio integrador jugamos al pattern poker:

En está última cada participante dio su valioso feedback sobre el grupo de estudio e hicimos el cierre del grupo de estudio.

viernes, 11 de septiembre de 2009

Creatividad y trabajo en equipo

La creatividad es un concepto que está muy ligado al trabajo en equipo, ya que es en las personas donde reside la chispa capaz de crear la idea buscada.

Si bien a nivel individual podemos encontrar personas creativas y con ingenio, el verdadero potencial creativo existe en el equipo. La idea de una persona, por más insensata o incompleta que sea, puede ser el disparador de una nueva idea en otra persona. Es en este mecanismo donde se esconde el gran potencial de trabajar en equipo para resolver problemas con creatividad.

Un aspecto clave para que el equipo funcione de manera creativa, es el de generar las condiciones de éxito necesarias. En este punto creo que lo más importante es generar el espacio de comodidad, distención y respeto, en donde cada uno pueda decir lo que sea, sin ningún tipo de miedo, verguenza o prejuicio. Esto que parece tan simple, muchas veces no es fácil de lograr. Pero hay varias maneras de conseguirlo, como ejercicios de integración, jugar juegos para romper el hielo, etc.

Generalmene conviene empezar plantenado el problema sin demasiadas restricciones y luego generar en equipo un gran abanico de posibilidades. En un primer momento evitamos las restricciones para no limitar ninguna idea tempranamente. En esta fábrica de ideas, es fundamental el respeto entre los compañeros, hablar 1 por vez y escuchar con atención lo que cada uno tiene para decir. Este simple ritual mejora las condiciones de éxito de las que hablamos anteriormente. El juego es uno de los mejores disparadores de ideas, por lo que jugar es una actividad muy recomendable en cualquier proceso creativo.

Luego de generar el abanico de soluciones, es tiempo de bajar a tierra, agregar las restricciones, volver a refinar y combinar las ideas para generar nuevas soluciones. Si bien hay varias técnicas para hacer esto, la herramienta más poderosa es la pregunta. Muchas veces, resolver un problema de manera simple pasa por hacer las preguntas correctas. A esta altura, si durante el desarrollo de la actividad se generó participación, compromiso y ganas, el equipo va contestando y generando las preguntas casi naturalmente.

Estas son algunas técnicas que pueden servir para llegar a una posible solución.

Encontrar las restricciones auto impuestas / romper las reglas

Como personas estamos limitados por nuestra manera de ver las cosas. Nuestra educación / cultura nos dió un marco desde el cual vemos todo. Sin darnos cuenta, podemos caer en la trampa de una restricción impuesta por nosotros mismos. Quizás el ejemplo más famoso de esto sea la teoría de la relatividad de Einstein. Durante años la física clásica explicó los muchos de los fenómenos que vemos. Para nosotros es muy intuitivo pensar que el tiempo fluye siempre de la misma manera. Einstein, al romper esta regla, descubrió una nueva dimensión de soluciones que le permitió explicar fenómenos que hasta el momento eran inexplicables.

Los chicos, al tener mentes menos formadas y más libres, son grandes mentes creativas!

Preguntar, preguntar y preguntar

La pregunta nos permite llegar a zonas oscuras de soluciones que no podemos ver. Por lo que explorar estas zonas es un buen ejercicio para encontrar nuevas soluciones. Incluso puede llegar a ser muy divertido, si se aplica una buena dinámica.

Cada integrante puede tomar un rol y preguntar desde distintos puntos de vista. Un libro que resume muy bien esta técnica es "6 sombreros para pensar".

Otras preguntas que ayudan a encontrar nuevas ideas:
Que pasaría si..?
Y si pasara esto?
Y si en vez de A, pasara B?

Jugar con las dimensiones del problema

A veces pasa que un problema sin solución aparente, tiene solución cuando se consideran nuevos factores o dimensiones. Por ejemplo, el problema de las 3 lamparitas no parece tener solución. Hasta que agregamos nuevas dimensiones como la temperatura por calentamiento, la vida útil del filamento, etc. Lo mismo podemos hacer quitando dimensiones.

Pensar fuera del cuadrante / pensamiento lateral

Otras veces la solución está fuera de nuestra área de foco o dirección de pensamiento. Por ejemplo una posible solución para el problema del tráfico en la ciudad puede ser que en lugar de crear carilles exclusivos o mejorar la sincronización de los semáforos, simplemente la gente pueda trabajar desde su casa.

Cambiar la herramienta

No se si alguna vez escucharon la frase "Para el hombre que tiene sólo un martillo cualquier cosa es clavo". Sin darnos cuenta las herramientas que usamos para resolver problemas nos limitan en el abanico de posibles soluciones.


Resolver problemas con creatividad puede transformarse en una actividad muy sana y gratificante. Descubrí el encanto por este juego gracias a los profesores Juan Ramonet, Silvia Ramos y Diego Sadras que me enseñaron muchas de estas herramientas en una excelente materia que dan en la UBA. Una materia sobre la que sigo aprendiendo y practicando.

jueves, 10 de septiembre de 2009

Fin de semana con PilasBA

Este fin de semana fue algo atípico. La semana pasada me enteré graciar a @juancarloslucas sobre un evento Pilas BA. Lo primero que pensé fue "que bueno, van a empezar a reciclar pilas en Buenos Aires". Luego por otros tweets vi que era algo relacionado con emprendedores, asi que los busqué en google y me encontré en su sitio con 2 palabras clave para mi curiosidad: innovación y responsabilidad social. Un evento para emprendedores, con una dinámica de aprendizaje ágil y orientado a esta problemática, no me lo puedo perder. Asi que sin dudar ni preguntar mucho, me inscribí.

Uno de los compañeros del evento, escribió un buen post con todo lo que hicimos:

Más allá del evento, que me sirvió mucho para derribar mitos, motivarme y establecer contactos, me gustaría destacar algunas particularidades, relacionadas con el grupo de personas.

Lo primero es la diversidad, tuvimos la suerte de contar con gente de distintas provincias y paises. De distintas profesiones, edades y experiencia. Con distintas habilidades. Sin embargo, en toda esa diversidad encontré, y luego otros me comentaron lo mismo, un factor común. Ganas de aprender, de conocer nuevas personas, de participar. Algunos ya tenían un emprendimiento propio. Otros estaban creándolo, o tenían la idea, o la inquietud.

Esa fue una primera impresión... Pero luego de participar en actividades y entablar conversaciones, poco a poco empezábamos a entrar en confianza. Y descubrí gente con ganas de innovar, de espíritu inquieto, interesados por la responsabilidad social en un sentido amplio. Descontentos con algo pero con la idea de que se puede hacer mejor, que hay otras muchas maneras. Y esto lo vi en varios campos (educación, software, negocios, etc.). Con muchos me sentí identificado por poder hablar libremente de ideas locas, como buscar maneras de mejorar el medio ambiente y la comunidad, o mejorar la educación en las escuelas. Cada uno trajo sus ideas, algunas nacidas desde adentro, otras vistas con un lente de otro color. Diversidad y potencial, otras palabras clave que detonan mi curiosidad.

viernes, 28 de agosto de 2009

Saas y RIAs ayudan a reducir el carbon footprint

Hoy encontré otro caso donde la tecnología ayuda a reducir el carbon footprint, es decir, la huella de carbono que dejamos en el planeta. Software as a service + RIA combinadas para minimizar el impacto ambiental:


Odio los buscadores de coincidencias, pero toclasaas es una aplicación software as a service y también está construida como una rich client application.

Porqué Saas? Pues la optimización de recursos (una aplicación para todos), de conocimiento (sinergia entre los tenants), reusabilidad, etc. minimizan el consumo de energía en comparación al modelo opuesto (cada tenant con su aplicación, server, personal dedicado, etc.).

Porqué RIA? Una aplicación RIA bien diseñada ayuda a minimizar la cantidad de rountrips y el tamaño de los mensajes entre cliente y server. Esto se traduce en menor consumo de recursos, por lo tanto un server puede atender más pedidos. Aunque el aporte más grande está en la mejora de la experiencia usuario, su productividad y optimizar el uso que hace de la herramienta.


miércoles, 26 de agosto de 2009

Green IT no es solo optimizar data centers

Hoy leí en la National Geographic sobre un nuevo tipo de letra pensada para consumir menos tinta en las impresiones. Se llama ecofont y es de uso gratuito:

Una idea genial, muy simple, lo que la hace doblemente buena!

sábado, 22 de agosto de 2009

Como hacer el unit testing mas fácil

Cuando se habla de tdd, exiten muchas herramientas y técnicas asociadas al testing unitario. Mi compañero Sergio hizo un muy resumen de ellas en su blog:

Además de estas técnicas, creo que hay algo fundamental para hacer una aplicación fáclmente testeable y tiene que ver con el diseño. A continuación voy a enumerar algunos aspectos que me parecen importantes.

Modelo de dominio

Resolver la lógica de la aplicación usando un modelo de dominio (o domain model pattern). Testear lógica desde un modelo de dominio es relativamente simple, solo hay que crear objetos, asignar propiedades, llamar a métodos y hacer asserts. Esto se debe a que un modelo de dominio no tiene depentencia a ninguna cuestión de infraestructura como persistencia, seguridad, etc. Esta separación natural hace que las pruebas sean más unitarias.

Me ha pasado de trabajar en aplicaciones donde había que modelar las entidades del dominio sin métodos. Esto es conocido como un antipatrón llamado anemic domain model. Construir pruebas unitarias en este caso es una tarea dura, pues generalmente otro objeto encapsula la lógica. En mi caso, las pruebas dependian de los datos cagados en la base de datos, cuando estos cambiaban, las pruebas dejaban de andar. También pasaba que había casos donde el test modificaba los datos y al hacer esto, invalidaba otras pruebas. Estos esfuerzos adicionales dificultan las construcción y el uso de pruebas unitarias. También pasa que con el tiempo las pruebas dejan de ser válidas ya que nadie mantiene los datos en la base. Según mi experiencia, hubiese sido muy bueno en estos casos trabajar con un modelo de dominio.

Para crear buenos modelos de dominio, recomiendo el libro domain driven design.

Programar hacia interfaces, no implementaciones

Este es uno de los principios de diseño que más me gusta. Si cada objeto de una aplicación (excluyendo al model de dominio) fuera una estrategia intercambiable, sería muy fácil aislarlo para poder testearlo unitariamente. Esto nos lleva al siguiente punto.

Inyección de depencias

Un framework de inyección de dependencias facilita la creación de pruebas unitarias (y de la aplicación). Algo que hago es crear un contexto especial para los casos de test que me permite modificar las dependencias según más convenga. Por ejemplo un servicio (service layer) que usa un objeto para la autorización puedo asociarlo a uno que siempre autoriza para probar determinada funcionalidad. Esto se conoce como mock objects.

Algunos trucos para construir pruebas unitarias usando spring framework
  • Crear una clase TestBase que herede de AbstractJUnit4SpringContextTests. Esta clase define el application context de test a usar.
  • Usar notaciones para definir las dependencias de un test

    Para insertar depencias por tipo:
    @Autowired
    private CatalogService catalogService

    Para insertar dependencias por id del bean
    @Resource
    private Client clientMario

  • Si la persistencia se realizar en base de datos, usar AbstractTransactionalJUnit4SpringContextTests. Esta clase realiza automáticamente un rollback de las operaciones realizadas. Yo la uso desde una clase test base:
    http://www.codepaste.net/4poaxh

  • Marcar los casos de test que ensucian los beans cargados por spring. Esto ayuda a eliminar las dependencias entre test. Por ejemplo si en un test se agregan items al cache y en otro test es necesario que el cache esté vacío para no afectar la prueba, se puede marcar el 1er caso de test como @Dirty y spring volverá a cargar todos los beans nuevamente luego de ejecutar la prueba.

    @Test
    @Dirty
    public void addItemsToCache() {...

  • Definir beans de las entidades del modelo con los resultados esperados en el contexto de test. Esto es algo que evita el hardcodeo de los resultados esperados. Luego se le agrega al caso de test una dependecia a este objeto.

    @Resource
    private Client expectedClient
Espero sea de ayuda. Para mi hay un antes y un después de usar spring.

viernes, 21 de agosto de 2009

Ideas para un mundo mejor

Ojalá alguien más tome la idea de plantar árboles para compenzar el CO2 emitido:

Sería muy bueno para alcanzar el objetivo de cero CO2. Y porque no apostar a hacer crecer este número negativamente en el tiempo...

jueves, 6 de agosto de 2009

Energía solar hogareña

Hace poco un amigo me pasó una tienda que vende equipos de energía solar. Este está muy bueno para trabajar con una notebook desde casa:

También está muy bueno el do it your self

Algo que vale la pena analizar, es encontrar donde esta el 80/20 el consumo energético. Hace un tiempo use como herramienta una calculadora para esto. Otra consideración importante es la de usar la energía solar con aparatos de corriente continua, ya que la conversión a 220 alterna es ineficiente.

Con este tipo de alternativas, estamos mas cerca de minimizar el impacto ambiental.

sábado, 1 de agosto de 2009

Convertir java objects a json usando json-taglib y jstlj

Dado que extjs trabaja con stores del tipo json, sería bueno poder convertir facilmente los objetos java que devuelven los servicios (service layer). Para eso json taglib permite convertir java objects a json en una pagina jsp. Se combina muy bien con jstl para trabajar con objetos más complejos.

1ro Instalar json taglib. Bajar del sitio oficial json-taglib.jar y copiar a WEB-INF/lib del proyecto.

2do Bajar los archivos jsl-api.jar y jstl-impl.jar del sitio jstl y copiar en tomcat/lib

3ro Armar un hello world json y jstl

y listo! Aca dejo un buen tutorial que me está siendo de mucha ayuda:

Conectando extjs con el server side usando spring framewok

Una de las ventajas de extjs es que permite fácilmente poder prototipar sin tener que construir ninguna pieza server side. Con este tipo de frameworks es posbile definir como origen de datos de un combo un archivo json:

// Armo filtros
var comboFilter = new Ext.form.ComboBox({
store: new Ext.data.JsonStore({
autoLoad: true,
url: 'services/sales/filter/brands.json',
root: 'data',
fields: ['id', 'name']
}),
valueField: 'id',
displayField: 'name',
triggerAction: 'all',
forceSelection: true,
mode: 'remote',
loadingText: 'Loading...'
})

Para mayor claridad estoy usando url amigables. La url services/sales/filter/brand.json me dice que quiero obtener del dashboard de ventas, el filtro de marcas, en formato json.

Spring, ademas de ser un IoC/DI container, provee una buena forma de manejar friendly urls. Vamos a explicar paso a paso como usar spring como un pegamento entre client side y server side.

1ro Configurar spring web para escuchar los request en /services:

2do Configurar spring mvc para que la url services/sales/filter sea resuelta con el controller OlapServiceController:

3ero Implementar OlapServiceController. Este es quien realiza la ejecucion del servicio (service layer) que devuelve el filtro y selecciona la vista filter2json.jsp para renderizar el filtro en formato json:

Algo interesante de esta implementación es el bajo acople que hay entre el front end (extjs) y backend (jsp, spring, java, mondrian, etc.). Trabajar con simples urls permite definir un punto de entrada y abstraer totalmente su implementación. Sería posible tener fácilmente más de un server resolviendo peticiones (si los servicios son stateless) o acceder al servicio en la nube y escalar ondemand.

Otra posibilidad interesante es al tener un front end estático, es posible aplicar técnicas de caché en el browser para disminuir la cantidad de request, o distribuirlo a través de una cdn.

Y por último sería "no tan difícil" darle features offiline a la aplicación usando google gears (http://gears.google.com/). Aunque sobre esto me gustaría profundizar un poco más en otro post.

viernes, 31 de julio de 2009

Cannon y su iniciativa green

Me alegra mucho enterarme que una empresa como Cannon toma iniciativas green para minimizar el impacto ambiental de sus actividades. Un ejemplo a imitar por todos.

http://www.itbrief.co.nz/200907313528/canon-leads-by-example-with-green-initiative.php

domingo, 26 de julio de 2009

Composite web application con extjs y Tibco pagebus

Se me ocurre que una buena manera de crear un dashboard es componiendo distintas partes, al estilo ratis / lego. Una de los desafios de crear aplicaciones compuestas es el de mantener bajo acople entre las partes. Es decir, que sean lo más idependientes posible. Agregar / quitar un nuevo mashup no debe afectar al resto. Las dependencias entre unos y otros deberían ser mínimas.

Un patron de diseño que resuelve este problema es el observe o publish / subscribe. Y una buena implementacion en javascript es el pagebus de Tibco:
http://developer.tibco.com/pagebus/



En el prototipo se puede ver los filtros del dashboard a la derecha y 2 informes en el centro. El 1ro es una grilla y el segundo muestra los filtros seleccionados. Cuando se cambia un filtro se publica en el bus un evento. Ambos informes se suscribieron al bus y por lo tanto reciben estas notificaciones. La grilla ejecuta una llamada ajax (se puede ver en firebug), el segundo informe muesta el mensaje publicado.

Este es el codigo fuente:
http://codepaste.net/2mcfzz

Todavía hay mucho por hacer, pero la idea parece funcionar!

sábado, 25 de julio de 2009

Agilidad y equipos de trabajo: Shackleton, Kon Tiki, motivación: Messner

Algo que me entusiasma mucho es leer historias de aventura y exploración. Si hay gente que rompieron barreras mentales (paradigmas), hizo cosas que se creían imposibles y tuvo que lidiar con la incertidumbre, fueron los grandes exploradores y aventureros.

Creo que a nivel personal y profesional, conocer experiencias son un aporte invaluable. No deja de llamarme la atención cómo en algunos casos el encare de estos aventureros de alinean con las ideas de las metodologías ágiles.

Una de las historias más impresionantes es la de Shackleton y su tripulación, quienes a principio de siglo intentaron realizar la primera travesía al polo sur. Su barco quedó atrapado en el hielo, sobrevivieron a 2 inviernos polares, estuvieron a la deriva en un mas caótico de témpanos, navegaron en balsa por uno de los mares más tempestuosos del planeta y lo más increible de todo: volvieron todos vivos!

Hay varios libros que cuentan la historia, para mi el más apasionante es este:

Otro libro interesante es el que extrae las lecciones aprendidas:

Su similitud con las ideas de las metodologías ágiles a pesar de los 100 años de diferencia es asombrosa.

Formar equipos de trabajo efectivos es un desafío que requere un alto grado de creatividad. En una materia de la facultad donde trabajábamos la creatividad (Análisis y Resolución de Problemas) hice elegí como tema del trabajo final "Cómo Formar Equipos Efectivos" y tomé como punto de partida 2 grandes historias de expliración: la de Shackleton y Kon Tiki. Esta última es una expedición que cruzó en océano Pacífico en balsa. El motor era demostrar que los habitantes de la Polinesia eran antepasados de los Incas.

Esta es la presentación del trabajo:

y este es el trabajo:

Un tema importante y muy relacionado es la motivación. Hacer cosas imposibles requiere un alto grado de motivación. Uno de los alpinistas mas grandes de la historia, Reinhold Messner,vuelca en su libro Mover Montañas distintas experiencias, convicciones e ideas sobre el alpinismo. En cada capítulo se puede apreciar el trabajo de una persona que dedicó su vida a su pasión más entrañable.

Lo más importante de las capacidades del ser humano es la de establecer un sentido. No he alcanzado el éxito por ser especialmente fuerte, resistente o valiente. Hago ante todo que mi quehacer tenga un sentido.

En mi caso, al leer frases como esta, el efecto es de motivación contagioso.