Category Archives: Programación

Cosas que se van descubriendo sobre la programación

Un recorrido por el manifiesto ágil

Hace poco vi un video de una conferencia de Martin Fowler sobre por qué la agilidad funciona. Expone entre él y Neal Ford varias tecnicas agiles como ejemplo de por qué estan añadiendo valor a las empresas que lo usan. Este vídeo  me dió la idea de exponer un listado de tecnologias denominadas ágiles relacionadas con los 4 postulados del manifiesto ágil. Empecemos por el primero.

Individuos e interacciones sobre procesos y herramientas

Este es el que más tiene que ver con el nucleo duro del desarrollo software, el equipo de desarrollo y su trabajo diario.. Cómo empezó a descubrir Fred Brooks en el Mitico Hombre Mes, un desarrollador no se tiene nada que ver con una máquina de producción en serie que se puede establecer un rendimiento fijo. Ese rendimiento depende de mil factores y uno muy importante es su comunicación con el resto de integrantes del equipo. Es importante que cada miembro del equipo esté motivado y tenga un compromiso proveniente de él mismo hacia el equipo y su proyecto.

En el libro Management Rewired de Charles S Jacobs, define como el grupo de producción perfecto el formado por un pequeño numero de personas (5-7) autonomos cuya subsistencia depende  del proyecto que tienen entre manos. Segun Jacobs, esta organización fue la que funcionaba cuando habia grupos de herreros, de carpienteros, de ganaderos… Esto mismo  es lo que plantea Scrum, un grupo de 5-7 personas autonomas. Si se añaden más personas se complica la gestión por una necesidad excesiva de comunicacion y con menos personas no se consigue la sinergía que se genera con un equipo multidisciplinar motivado.
La agilidad plantea la comunicación de tal modo que sea lo más eficiente posible. Las reuniones se establecen para que se interambie la información necesaria para seguir trabajando sin  gastar más tiempo que el estricatamente necesario. Cada reunión tiene definidos un objetivo y un timebox, es decir, un tiempo máximo que una vez terminado se da por finalizada la reunión. La comunicación offline mediante un sistemas de tarjetas, por ejemplo,  aportan un elemento  concreto y una ubicacion (al lado del tablero) para realizar decisiones. El pair programming es otro elemento interesante de interacción entre desarrolladores. Es muy dificil,sino imposible, medir la productividad de una pareja de programadores comparado con lo que produciría uno sólo. Es por esto por lo que la medida en la que mejora el resultado de un desarrollo no es facilmente cuantificable pero es patente en el resultado. En el vídeo que comento al principio del post, Martin Fowler comenta que una pareja que trabaja en el mismo codigo trabaja como un cerebro con sus dos lados activos a la vez. El que está con el teclado usaría la parte logica y matematica del cerebro (el izquierdo) para resolver el problema de código que tiene entre manos y el desarrollador que está al lado, con su visión más amplia aporta el lado más creativo  (el derecho).
El entorno es tambien importante para esta comunicación. El entorno de trabajo debe favorecer la comunicación de todos con todos de modo visual cara a cara. Se descartan los cubiculos y se intenta crear un entorno en el que la información del proyecto esté visible en todo momento para todos y se promueva la creatividad.

Software funcionando sobre documentación extensiva

Los programadores no somos buenos escritores de narrativa. De hecho normalmente somos muy malos en la expresión escrita (yo admito que lo soy). La documentación hay que usarla como herramienta para un proposito concreto. Un diseño de clases basico o un diagrama de interacción entre clases puede ayudar a entender un código y saber dónde hacer un mantenimiento de modo más optimo. Ese diseño, dentro de poco tiempo qudaría obsoleto a no ser que se dedique su tiempo en mantenerlo al día.  Sin embargo, lo que más importa es tener un pedazo de software que pueda aportar valor al cliente. A partir de él se puede generar la documentacion mediante analizadores de código y metadata pero no al reves. Al realizar distintos niveles de test se ofrece un testeo cada vez más amplio. Empezamos con un testeo de los métodos de una clase mediante el testeo unitario en el PC del desarrollador. Seguimos con un test de integracion mediante un build centralizado que testea todo el codigo de los desarrolladores juntos. Al final del sprint hay un test de aceptación realizado por el product owner en el que se ven posibles problemas y se añaden sugerencias.

Colaboración con el cliente sobre negociación contractual

En Scrum se define un rol muy importante que es el  Scrum Owner. Esta persona (unica persona) debe hacer lo posible por conocer el negocio y aportar su conocimiento al equpo de desarrollo entre incrementos de producto. El nuevo requerimiento a mitad de proyecto no es una incidencia que haya que intentar evitar sino que es algo que le dará  valor añadido al producto por lo que hay que aceptarlo. El sistema de gestion de proyectos iterativo es la mejor manera de ir adaptando el software a las necesidades del cliente segun se va dando cuenta de ellas. La demo que se realiza al  final de sprint es para él cliente y/o el Product Owner y todos los que puedan aportar ideas. El cliente no se siente atado por haber firmado un documento de requierimientos ni el equipo tiene que modificar todo el proceso rompiendo el proyecto a mitad por un requerimiento inesperado.

Respuesta ante el cambio sobre seguimiento de  un plan

El permirir introducir cambios a mitad de desarrollo tiene sus métodos, no es un simple ASM (A Salto de Mata). No se hace un diseño complejo al inicio sino que se hace el diseño más simple que cumpla lo necesario por el test. A muchos desarrolladores nos gusta pensar  a lo grande e intentar preveer todos los casos pero esto es algo que normalmente provoca que el proyecto se sobredimensiento. El código basado en ese diseño simple está lo suficientemente cubierto pro tests unitarios para poder refactorizarlo y adaptarlo a las nuevas necesidades. Se cambia la mentalidad de tenerlo todo previsto por la de intentar  tener toda la información (feedback) lo más pronto posible para reaccionar y adaptar si es necesario el proceso  Si hacemos un recuento de tipos de  feedback de más proximo al desarrollador a más lejano empezaremos por el compañero del pair-programming que nos indica un error en el que no hemos caido justo al teclearlo,el  unit-test que nos salta cuando la hemos cagado sin querer en cuanto damos a compilar, el build centralizado diario que nos muestra nada más llegar a la oficina que ha habido un problema de integracion, el kanban a la vista de todos para ver cuando alguien ha cambiedo de estado una tarea nos da la posibilidad de verificar ese cambio inmediatamente, la demo de final de sprint que nos verifica que ese incremento ha sido todo un exito.

Anuncios

Preparados,¡ FUEGO !, apunten…

Estoy leyendo un pequeño libro de Tom Peters. Está definido como el gurú de los gurús en temas empresariales. Ha escrito libros como “En busca de la Excelencia”  y “Triunfar sin que tu jefe te estorbe” de ediciones nowtilus. Entre las muchas cosas que defiente de las que ya hablaré (espero) en un futuro post, habla del concepto “Preparados, ¡FUEGO!, apunten…”. (Ready, FIRE!, Aim en inglés). Lo que defiente en estas tres palabres es el  actuar antes de tener todo definido. Preparar un poco, actuar y mejorar después.

Aplicandola a la creación de software se puede aplicar en varios ámbitos, todos relacionados con la agilidad.

Desarrollo: Preparados, ¡FUEGO!, apunten… Prepara el test, haz que funcione, refactoriza… En esto se basa el testeo unitario y el Test Driven Development. Este es el ritmo más básico en el desarrollo software. Con estos pequeños pasos se realiza software que funciona con baja probabilidad de producir bugs.

Analisis: Preparados, ¡FUEGO!, apunten… Analiza un poco, implementa, mejoralo… En ocasiones no se puede hacer un analisis completo, sobre todo cuando el ámbito del problema es muy abstracto y/o complejo. En esos casos, se define una ventana temporal para el analisis, digamos 15 minutos. Si el tiempo llega a su fin se elige la mejor opción barajada hasta el momento. Una vez esté implementado ya se tiene un ambito más concreto y un elemento sobre el que trabajar que se puede ir mejorando mediante refactorización.

Gestion del proyecto: Preparados, ¡FUEGO!, apunten… Pequeña planificación, pequeña implementación, revisión….  Esta es la base del desarrollo iterativo usado por ejemplo en SCRUM. Se elige un conjunto de requerimientos, se implementan y se revisa lo implementado. A partir de un prototipo o una implementación parcial se puede obtener un software mucho más completo y preciso que haciendolo todo a la vez.

Todo esto que hemos visto proporciona una motivación y unas herramientas para una acción rápida y efectiva en un ambito complejo. El detenerse para tener todo claro,analizado y cerrado podría significar un cambio del entorno o peor aun,  la perdida de la oportunidad de realizar el proyecto.

Busca tu pareja perfecta en facebook

Hace un poco más de un mes mi madre me dejó un libro de Lincoln Child llamado “Armonia Perfecta”. Trata de una empresa llamada Eden que ofrece servicios de búsqueda de la pareja perfecta. Esos servicios cuestan 24.000 dolares y a base de una serie innumerable de tests psicologicos y de otros tipos y un super-ordenador con complejos algoritmos de inteligencia artificial va combinando los “especimes” hasta que encuentra una pareja lo más compatibles posible.
Yo, como ingeniero informatico pensé enseguida la viabilidad de algo parecido. Esta claro que el libro es muy peliculero pero quizá se pueda hacer algo parecido con muchos menos recursos. Y me puse manos a la obra.
Encontré en Facebook la plataforma perfecta para la aplicación. La gente puede darse de alta y lo primero que tiene que hacer es introducir sus parametros de busqueda (edad, sexo y localizacion geografica). Cada poco tiempo incluiré nuevos tests para que intente conocer más el perfil de cada persona: gustos, personalidad, hobbies… Y cuando haya suficiente gente en el sistema, empezaré una busqueda por semana. Buscará las mejores coincidencias en entorno local (20 km), cercano (40 km) y lejano (100 km) indicando cual es el mejor porcentaje de compatibilidad encontrado. Cada persona puede entonces elegir una de los resultados y concertar una cita. Si ambas partes estan de acuerdo se sugiere un sitio en el que se encontrarán fisicamente.
A cualquiera que esté interesado en encontrar su pareja perfecta en facebook sólo tiene que entrar en Eden y esperar que empiece a dar resultados. Todo el mundo está invitado.

Framework para objetos Mock propuesto

Ahora estamos peleando con Unit Testing y claro, a no ser que tu codigo solo calcule series fiabonacci o algoritmos de ordenación, existe una serie de elementos externos como bases de datos, hardware especializado, uso de ficheros y del sistema operativo. Para aislar el codigo a probar de esta serie de elementos se usa los objetos Mock.

Un objeto Mock es un objeto que es llamado por el codigo a probar y que permite especificar su comportamiento al detalle para forzar todas las situaciones posibles. El codigo a testear no debe tener logica que sea distinta segun sea en situacion de testeo o en produccion. Despues de darle muchas vueltas y un par de intentos fallidos se ha llegado a este framework. Esta diseñado en C++ que es el lenguaje que uso más que el castellano.

Se creará una clase abstracta que tendrá todos los metodos necesarios para simular la clase. De esta clase heredaran una clase que será la que realmente haga el trabajo en situacion real y otra clase que será la Mock.

Se pueden definir estas clases para simular DLL’s, acceso a bases de datos, acceso a ficheros, llamadas al api de windows (GetProfileInt, MessageBox, Sleep,…), tambien se puede crear una clase para las peticiones de datos con dialogos al usuario.

Ejemplo: Clase que simula al API de Windows

// Clase abstracta
class CWinApiBaseClass {
CWinApiBaseClass();
virtual CWinApiBaseClass();
virtual int MessageBox(HWND ventanaPadre,LPCTSTR mensaje,LPCTSTR title,int flags)=0;

}

//Clase real (wrapper sobre el codigo llamado)
class CWinApiWrapper:public CWinApiBaseClass {
CWinApiWrapper ();
virtual CWinApiWrapper ();
virtual int MessageBox(HWND ventanaPadre,LPCTSTR mensaje,LPCTSTR title,int flags);

}

int CWinApiWrapper::MessageBox(HWND ventanaPadre,LPCTSTR mensaje,LPCTSTR title,int flags){
return ::MessageBox(ventanaPadre,mensaje,title,flags);
}

//Clase mock
#define WinApiMock_MaxCalls 100 // Permite definir el maximo de los arrays de datos
class CWinApiMock:public CWinApiBaseClass {
CWinApiMock();
virtual CWinApiMock();
virtual int MessageBox(HWND ventanaPadre,LPCTSTR mensaje,LPCTSTR title,int flags);

//Para MessageBox
unsigned int m_nCallsMessageBox; // Permite saber si se ha llamado o no a la funcion
HWND m_ListMessageBoxHWND[WinApiMock_MaxCalls];
CString m_ListMessageBoxMessage[WinApiMock_MaxCalls];
CString m_ListMessageBoxTitle[WinApiMock_MaxCalls];
int m_ListMessageBoxFlags[WinApiMock_MaxCalls];
int m_ListMessageBoxRetValue[WinApiMock_MaxCalls]; //Permite indicarle qué va a retornar

}

CWinApiWrapper::CWinApiWrapper(){
// Se inicializa los contadores a 0 y todos los arrays que lo necesiten a 0 con ZeroMemory
}

int CWinApiWrapper::MessageBox(HWND ventanaPadre,LPCTSTR mensaje,LPCTSTR title,int flags){
m_nCallsMessageBox++;
m_ListMessageBoxHWND[m_nCallsMessageBox]=ventanaPadre;
m_ListMessageBoxMessage[m_nCallsMessageBox]=mensaje;
m_ListMessageBoxTitle[m_nCallsMessageBox]=title;
m_ListMessageBoxFlags[m_nCallsMessageBox=flags];
return m_ListMessageBoxRetValue[m_nCallsMessageBox];
}

Es importante tambien definir una variable global por cada clase que contenga el objeto wrapper real. Este objeto se usará para iniciar por defecto todos los usos al uso el produccion.

// En el WinApiBaseClass.h
#ifndef CWINAPIMOCK_CPP
#define CWINAPIMOCK_CPP
extern CWinApiWrapper glWinApiWrapper;
#endif

// En el WinApiBaseClass.cpp
CWinApiWrapper glWinApiWrapper;

// En el .h la clase a testear
protected:
CWinApiBaseClass *m_winapi;

//En el constructor de la clase a testear se inicia el puntero
CClaseATestear::CClaseATestear(){
m_winapi=&glWinApiWrapper;
}

//Cada vez que el codigo llame a MessageBox se usa el puntero a la clase abstracta, iniciada por defeco a la
// real para que no haya problemas en produccion

int ret=m_winapi->MessageBox(GetSafeHwnd(),_T(“¿Quiere continuar?”),_T(“Mi aplicacion”),MB_YESNO);

//Cuando se testea el codigo hay que cambiarle el puntero para que apunte al objeto mock

CTestClaseATestear::TestFuncionATestear(){
CWinApiMock mock;
CClaseATestear miClase;

miClase.m_winapi=&mock;
mock.ListMessageBoxRetValue[0]=IDYES; //Forzamos el retorno del messagebox
CPPUNIT_ASSERT(miCLase.FuncionATestear());
CPPUNIT_ASSERT(mock.m_nCallsMessageBox==1); // Comprobamos que realmente se ha llamado
}

Y esto es todo. Espero vuestros comentarios

Masoca’s tools

Así llamabamos a los juegos y aplicaciones que instalabamos hace 15 años con una pila de 20 discos de 3 1/2. Eran epocas gloriosas. Para hacer funcionar un juego (backup o con los discos originales) teniamos que trastear el autoexec.bat para cargar unas cosas sí y otras no. Todo esto para liberar las 640 K de memoria base y el juego arrancara.

Aplicaciones como el ‘a.exe’ que le autocompletaban directorios cuando cambiabas usandolo en lugar del ‘cd’, comprimiendo y descomprimiendo con el pkunzip, arj,  formateando los discos con el 2MF para lograr que los discos de 1,4 se conviertieran en 2MB, … Habia que complicarse para lograr pequeños hacks que ibamos necesitando para el dia a dia.

Ahora la administracion de los PCs se ha vuelto mucho más intuitiva, con el boton derecho del raton tienes acceso a todas las opciones que te brinda el sistema operativo, en Internet tienes informacion de cómo mejorar tu sistema operativo hasta hacerlo tan rapido como si tuviera la version anterior del mismo 😉  Sin embargo en cuestiones de administracion uno se vuelve muy perezoso. Puedo aguantar meses y meses pulsando una tecla al arranque para que no me analice mi C: porque tarda la vida, el escritorio se me va llenando de iconos, tengo el mismo wallpaper desde hace más de 2 años,…

Sin embargo en cuestion de programación aun tengo esa costumbre de intentar saber bien que hace exactamente el código que escribo. Desde hace más de 5 años programo en C++ con Visual Studio 6. Me manejo con mucha soltura con MFC, que es una pesadilla para los programadores de Visual Basic pero para los que sabemos que habria que hacer para programar lo mismo con el API de Win32 es una maravilla. Pero el tiempo avanza…

Llegan nuevas tecnologias y APIs de programacion: Windows Presentation Fundation, Windows Communication Fundation, las clases ya trabajadas que se usan en .NET,.. Todo un mundo de tecnologias ya hechas que, aunque quiera resistirme (que no es el caso), noto que necesito aprender y adaptarme. Donde trabajo tenemos mucho, mucho codigo en proyectos como he comentado (C++ con MFC). Hemos decidido dar el gran paso, pero darlo como Dios manda. Cuando empezamos no sabiamos de .NET, de patrones Modelo-Vista-Controlador (MVC) y practicamente nada de Unit Testing. ¿Que hacer para arreglarlo? Hacerlo todo a la vez mientra migramos a Visual Studio 2008.

En este blog voy a intentar ir publicando las cosas que vamos descubriendo que espero que le sirva a otros programadores, tan “masocas” como yo que prefieren seguir usando C++ con toda la parafernalia de nuevas tecnologias que nos llegan.

Empezamos el viaje…

Windows CardSpace, breve descripción y comentarios

Como se habrá visto en mi anterior post de programación, estoy haciendo el curso de desarrollador 5 estrellas de microsoft (www.dce2005.com). El primer curso de la cuarta estrella trata de Windows CardSpace. Esto es una idea de Microsoft para intentar reducir el problema de phising (peticion de password al usuario creando una web haciendose pasar por la original).

El uso de password lo sustituye por tarjetas de identificacion que se almacenan en el ordenador del usuario. Estas tarjetas no contienen informacion del usuario sino que se usan para pedir esa informacion de modo cifrado a una tercera entidad llamada proveedor de identidad (identity provider). Esta entidad le devuelve el grupo de informacion en un token al usuario que a la vez lo envia a la web para identificarse. El token esta formado por una serie de claims que cada uno es un dato, puede ser usuario, dirección, … De estos datos la web coge los que necesita para identificar al usuario.

De aqui surgen varios inconvenientes.

Primero que la informacion se almacena en el ordenador del usuario y necesita exportarlo por ejemplo a un USB e instalarlo en el ordenador que vaya a usarlas, por ejemplo un Cybercafe. Microsoft entiende que esto es un problema e informa que en la proxima version se podrá usar directamente del USB sin instalarla. Esto sí es una buena idea ya que igual que tus llaves de casa puedes llevar encima tus tarjetas de identidad para usar en distintas webs.
Segundo que tampoco eliminan el problema del phising al completo, ya que una persona maliciosa podria crear una web falsa que solicitara el token del usuario. Es el usuario es que debe distinguir la web original de la copia y no aceptar a entregarle la informacion si no es de su confianza. Si el usuario es un poco avispado puede darse cuenta que si ya ha entrado en esa web anteriormente no deberia pedirle el sistema confirmacion para entregar la informacion ya que se hace de forma automatica. Microsoft informa que para evitar esto se esta estudiando el certificar las imagenes de la web (logos) para que el usuario confirme que realmente son de la web que espera. Aqui mi pregunta es: ¿por que no se hace eso directamente con el sistema de password actual?

Me parece que es un buen intento pero no soluciona nada y complica demasiado el sistema de autentificación sobre todo para el desarrollador de la web. Para el usuario se le presenta un sistema muy intuitivo y bonito con tarjetas e imagenes pero aun tiene un par de flecos por mejorar.

Espero vuestros comentarios y correcciones.

Enlaces:

White paper de Microsoft. http://msdn2.microsoft.com/en-us/library/aa480189.aspx
Un pdf de cómo implementarlo (hands on labs) http://www-sor.inria.fr/~galland/papers/HOL07techdays.pdf

Al fin la quinta estrella de desarrollador .NET

Hola.

Existe un curso de programacion online hecho por Microsoft en el que van enseñando las tecnologias .NET de más interes: ASP .NET, Windows Presentation Fundation, Windows Communication Fundation, etc… Es totalmente gratuito y segun vas aprobando examenes te van concediendo estrellas hasta llegar a un total de cinco. Hace unos pocos dias por fin han puesto el contenido para llegar a la quinta estrella y además si haces despues otros cursos te asignan el titulo de Desarrollador Gold o Platinum. Yo por el momento estoy estudiando el primer curso de la cuarta estrella (CardSpace). Se lo recomiendo a todo aquel que quiera estar a la ultima en desarrollo para Windows. El link es www.dce2005.com Date prisa que si sacas la 5ª estrella antes de fin de febrero te envian un diploma a tu casa.