domingo, 30 de enero de 2011

Tutorial Java: Anotaciones.

¿Que son las anotaciones?
Las anotaciones fueron incorporadas a partir de la versión 5.0 de la JVM JSR 175 "A Metadata Facility for the JavaTM Programming Language"


Escencialmente son metadatos, por lo que proveen información acerca del código pero no son parte del código en si. No tienen efecto directo sobre el programa.
Tienen principalmente 3 usos:

  • Brindar información al compilador: previenen errores y advierte de posibles problemas.
  • Automatización de tareas: algunas herramientas y frameworks pueden procesar anotaciones para generar código, archivos XML y otros artefactos.
  • Procesamiento en tiempo de ejecución: algunas anotaciones pueden ser evaluadas en tiempo de ejecución y permitir al código tomar conocimiento de estos metadatos (ejemplo ORM).
Es importante tener en cuenta que no modifican la forma en que los programas son compilados, es decir que independientemente de las anotaciones, los programas deberían generar el mismo código ejecutable.


La JVM trae algunas anotaciones por defecto y también permite que el usuario declare y emplee anotaciones personalizadas. Ejemplo de anotaciones personalizadas son las numerosas anotaciones que proveen diversos frameworks como los ORM (donde por caso, para declarar que una clase es una entidad persistente, alcanza con dos anotaciones básicas, declarar que dicha clase es una entidad y que tiene un ID)


¿Como aplicar anotaciones?


Las anotaciones pueden aplicarse sobre varios de los elementos que componen una clase en Java. 


Básicamente se puede realizar en 3 niveles:

  • Clase
  • Atributo
  • Método.
Ejemplos

Anotaciones a nivel de clase:

@Author(
   name = "Yo",
   date = "02/12/2009"
)
public class MyClass {
  private int pepe;
}


viernes, 18 de septiembre de 2009

Learning JSF2: Navigation

Learning JSF2: Navigation: "

This is a second post in Learning JSF 2 series. The first one on Managed Beans can be found here
.



Before I start, thanks to Nick Belaevski (RichFaces Team Lead – Exadel) for reviewing this posting.



In JSF 1.2 all navigation rules are placed in JSF configuration file. Although you can still places navigation rules inside JSF configuration file, JSF 2 upgrades navigation by introducing implicit navigation and conditional navigation.



Implicit navigation



In JSF 1.2, navigating from one page to another required something like this:




<navigation-rule>



<from-view-id>


page1.xhtml</from-view-id>



<navigation-case>



<from-outcome>


next</from-outcome>



<to-view-id>


/page2.xhtml</to-view-id>



</navigation-case>



</navigation-rule>







JSF 2 now supports implicit navigation where you don’t need to define a navigation rules inside JSF configuration file. You can do this:




<h:commandButton
action
="page2"
value
="Submit"
/>






JSF will try to find a view named page2.xhtml in the current directory.



The following will also work:




<h:commandButton
action
="page2.xhtml"
value
="Submit"
/>






or




<h:commandButton
action
="page2.jsf"
value
="Submit"
/>






Note:
this is assuming that JSF servlet is mapped to .jsf.



or using the new h:link (or h:button) tags in JSF 2 (I’ll cover these tags in a separate posting):




<h:button
outcome
="page2"
value
="Go There"
/>






Implicit navigation can also be used from within an action method:




public
String
next (
)
{

return
"page2"
;
}





The following will also work:




public
String
next (
)
{

return
"page2.jsf"
;
}






public
String
next (
)
{

return
"page2.xhtml"
;
}





All examples above implied that both pages (page1.xhtml and page2.xhtml) are in the same directory (notice there is no / before page name). If pages are in different directories, then full path has to be used:




<h:commandButton
action
="/shopping/page2"
value
="Submit"
/>






or




public
String
next (
)
{

return
"/shopping/page2"
;
}





Conditional navigation



In JSF 1.2, methods in managed beans would return arbitrary string values which are passed into the navigation. Navigation couldn’t use application state to help determine what page to select. The most you could is something like this, you could check what button/link was clicked in addition to using the outcome:




<navigation-rule>



<from-view-id>


/pages/course.xhtml</from-view-id>



<navigation-case>



<from-action>


#{bean.register}</from-action>



<from-outcome>


success</from-outcome>



<to-view-id>


/pages/registered.xhtml</to-view-id>



</navigation-case>



</navigation-rule>







In JSF 2, you can now do this:




<navigation-rule>



<from-view-id>


/pages/course.xhtml</from-view-id>



<navigation-case>



<from-action>


#{bean.register}</from-action>



<if>


#{bean.prerequisiteCompleted}</if>



<to-view-id>


/pages/registered.xhtml</to-view-id>



</navigation-case>



<navigation-case>



<from-action>


#{bean.register}</from-action>



<if>


#{bean.advisingHold}</if>



<to-view-id>


/pages/scheduleAdvisingSession.xhtml</to-view-id>



</navigation-case>



<navigation-case>



<from-action>


#{bean.register}</from-action>



<if>


#{not bean.payment}</if>



<to-view-id>


/pages/payForCourse.xhtml</to-view-id>



</navigation-case>



</navigation-rule>







When #{bean.register} action is invoked, based on ..
condition (evaluates to true/false) in each case, it’s possible to navigate to three different pages. This allows to use application state to determine where to navigate. It’s not longer necessary to have model objects return arbitrary strings and thus could eliminate having your back-end know anything about navigation.



Forward/Redirect



When navigating to another page, both JSF 1.2 and JSF 2 perform a forward (default behavior) to the new page (Seam, for example does a redirect by default). Because it’s a server forward (the browser is not aware that we are displaying a different page), you might have noticed that the page address in the URL is always one behind.



If defining navigation rules in JSF configuration file, then the same tag is used in JSF 1.2 and JSF 2:




<navigation-rule>



<from-view-id>


/bar/enter.xhtml</from-view-id>



<navigation-case>



<from-outcome>


enterBar</from-outcome>



<to-view-id>


/bar/welcome.xhtml</to-view-id>



<redirect
/>


</navigation-case>



</navigation-rule>







When using implicit navigation in JSF2, redirect is setup using faces-redirect=true
request parameter:




<h:commandLink
action
="/bar/welcome?faces-redirect=true"
value
="Go to page 5"
/>






If returning an outcome from action method:




public
String
enter (
)
{

return
"/bar/welcome?faces-redirect=true"
;
}





Using EL in to-view-id



You can also use EL in :




<navigation-rule>



<from-view-id>


/el/page1.xhtml</from-view-id>



<navigation-case>



<from-action>


#{bean.navigate}</from-action>



<from-outcome>


success</from-outcome>



<to-view-id>


#{bean.page}</to-view-id>



</navigation-case>



</navigation-rule>







In the managed bean:





private
String
page;

public
String
getPage (
)
{

return
this
.page
;
}

public
String
navigate (
)
{

this
.page
=
"/el/page3"
;
return
"success"
;
}






A topic closely related to navigation is page parameters and how they are propagated, I will cover that in another posting.



Finally, one thing to be aware of. Suppose you have the following rule:




<navigation-rule>



<from-view-id>


/purchase.xhtml</from-view-id>



<navigation-case>



<from-action>


#{bean.purchase}</from-action>



<if>


#{not bean.creditCardExpired}</if>



<to-view-id>


/confirmation.xhtml</to-view-id>



</navigation-case>



</navigation-rule>







In managed bean:




public
String
purchase (
)
{

...
return
"confirmation"
;
}





Suppose creditCardExpired evaluates to true and thus making condition false. In such case you would think that navigation shouldn’t take place. However, you still navigate to confirmation.xhtml because implicit navigation is used. First, the above case is matched but not selected as ..
evaluates to false. Navigation continues to look for a match and because purchase() method returned a string value of “confirmation” is used by implicit navigation which matches a page with such name. Implicit navigation is used last.

"

sábado, 12 de septiembre de 2009

Migrando de Ant a Maven

Muy buena entrada del blog Artesanía del Software, explicando como un proyecto de tamaño pequeño/ normal (unas 54 kLoc) fue migrado de Ant a Maven.

http://weblogs.javahispano.org/artesanodeprimera/entry/migrando_de_ant_a_maven


Migrando de Ant a Maven: "

Hace tiempo que estamos detras de migrarnos de nuestro sistema de build actual: Ant a Maven. Para poneros un poco en situación se trata de un proyecto medio (54.000 lineas de código aprox) subdividido en varios modulos, unos 5 .jar con la logica y los API's del sistema y un par de aplicaciones web. Como se trata de un framework sobre el que desarrollar otras app's también tenemos varios proyectos a modo de ejemplos de uso de los distintos API's.



Motivos para el cambio



Esto nos suponia un cambio bastante gordo, tampoco se trata de tirarse a la piscina simplemente porque maven 'mola más' o esta más de moda. Varios motivos han motivado este cambio:




  • Mantenimiento de los scripts de Ant: Cada vez nos costaba más y más mantener estos scripts. Cuando empezo el proyecto y eran pequeñitos todo perfecto, pero a medida que ha credido el proyectos los scripts también y con algún hack que otro que dificultaba cada vez su mantenimiento.

  • Mejorar la distribución de las librerías: Hasta ahora entregabamos nuestras librerías simplemente en un zip y a correr. Queriamos facilitar el trabajo de los usuarios de nuestra librería dejando las versiones liberadas en un repositorio, miramos Ivy también, pero maven nos parecia una solución más completa, y ya puestos a cambiar...

  • Facilitar la integración con otras herramientas: Usamos hudson como servidor de CI, y recietemente sonar para control de calidad. Estas herramientas se integran con ant pero su integración con maven es mucho más estrecha.

  • Soporte Multi-proyecto: Ant no tiene ningún tipo de soporte multi-proyecto, si tienes varios proyectos con ant y quieres tener una compilación autoamtica de todos en conjunto te lo tienes que montar 'by hand' mediante ant-call o similares. En mi opinión cualquier sistema de build moderno debería tener soporte multi-proyecto con varios niveles (jerarquico) de forma nativa, que no todo son proyectos 'hola mundo'.



Nuestro ecosistema y maven



Es crucial que el sistema de build se integre en condiciones con el resto de herramientas de tu ecosistema, para nosotros era importante que se integrase bien con:




  • Netbeans: El soporte para maven en netbeans 6.7 ha sido un impulso grande para este cambio, el soporte es fantastico y nos permite seguir trabajando con nuestro IDE favorito y utilizar maven. Y aunque sea 'ironico' el soporte de maven de netbeans también nos aporta la libertad de migrar a cualquier otro IDE que soporte maven (eclipse, JIdea) si fuera necesario, o que cada desarrollador use el que le de la gana.

  • Hudson: Nuestro amado hudson se integra con maven que da gusto. Si subes un proyecto multi-modulo con varios niveles de jerarquia te muestra una vista en árbol (bueno tabula un poco na más) de todos tus sub-modulos, indicando porque modulo va la compilación cuando esta activa. La verdad es que funciona increible hudson con maven, una pasada.

  • Sonar: Nos encanta sonar!, y aunque se puede usar en proyectos no-maven con maven todo es mucho más sencillo.

  • Subversion: Aunque en principio parezca que poco tiene quer ver con tu sistema de build, maven nos ha permitido no tener que guardar en svn todas las librerías de terceros que usamos (ahora están en el repositorio de maven, nexus en nuestro caso). Esto es importante si tienes 20 proyectos en tu empresa, cada uno con su propio svn, y en cada uno de ellos tienes que almacenar de nuevo todas las librerías de teceros y las compartidas entre los distintos proyectos de tu empresa.

  • Nexus: Junto con el uso de maven me parece imprescendible tener en la empresa montado un repositorio maven. Esto te permite no depender de los repositorios remotos, que no están bajo tu control y ¿quien te asegura que no casquen justo el día que te hacen más falta?. También te permite subir a el todas aquellas librerías que no están en los repositorios oficiles, tanto las de terceros que no se distribuyen via maven como las propias librerías que se generan en tu empresa y se comparten entre proyectos. De momento muy bien con nexus, instalación y configuración muy sencillas y 0 problemas, ya veremos claro, que llevamos una semana con el jeje.



Algunos plugins de maven interesantes



Existe una gran cantidad de plugins disponibles para maven, para casi cualquier cosa que te puedas imaginar que necesites en un sistema de build java tienes un plugin de maven que te facilita la tarea, esto ahorra mucho trabajo y sobre todo facilita luego el mantenimiento de los scripts si lo comparamos con Ant, algunos que nos han resultado muy utiles de momento:




  • Maven GWT plugin: Necesitabamos un plugin que nos ayudara con nuestros proyectos GWT, me ha sorprendido lo bien que funciona este plugin, en media mañana tenia los proyectos migrados de netbeans con GWT4nb a maven con el plugin de gwt. El único pequeño incoveniente es que a la hora de hacer debug con el hosted browser te ves obligado a ejecutar mvn gwt:debug y luego hacer attach a mano con el depurador de netbeans, pero creo que podre sobrevivir con esto :P.

  • Maven assembly plugin: Facilita muchisimo la tarea de crear distribuciones de tu proyecto. De momento hemos creado una distribución con jetty integrado, para que con doble click tengas un servidor de aplicaciones arrancado con tus app's montadas y una distribución de nuestras librerías empaquetada en un simple zip (junto con las dependencias de terceros, documentación y código con ejemplos de uso del API), para los usuarios que no usen maven sigue siendo necesario este modo de distribución, a nosotros nos gusta maven pero no podemos obligar a todo el mundo a trabajar como a nosotros nos guste :P

  • Maven ant-run: Quizas ant no sea lo mejor para montar un build muy complejo, pero para pequeñas tareas de copiar ficheros de un lado para otro y cosas de este estilo sigue siendo una herramienta util. Algo que a muchos no les gusta de maven es su rigidez, sin embargo con este plugin tienes la facilidad de la 'convención sobre configuración' que ofrece maven y la flexibilidad de ant cuando sea necesaria. En pequeñas dosis puede ser un plugin muy util.

  • maven sonar plugin: El solito te hace un analisis de tu proyecto utilizando findbugs, checkstyle, pmd, cobertura... y inserta los resultados en la bd de sonar para luego poder consultarlos desde la UI web. Esto mismo con ant lo haciamos con un buen puñado de scripts, y con maven es un simple comando. De todos modos ni siquiera lo usamos directamente, hudson cuenta con un plugin para sonar que te permite activar el analisis sonar despues de cada compilación, más facil y mejor integrado imposible.



Además de estos hemos usado algún otro como el plugin javadoc y el plugin sources para incluir los fuentes y el javadoc al lado de los .jar que distribuimos via repositorio maven, el plugin maven dependency para copiar dependencias en la distribución y se me estará olvidando alguna más seguro...



Nuestra jerarquia de proyectos



En un proyecto complejo, con varios modulos, al final lo que acabas teniendo es una jerarquia de sub-modulos, esto es algo que me encanta de maven, que soporta este tipo de proyectos de forma muy sencilla, la nuestra es más o menos así:




  • Proyecto Principal



    • Api's



      • API 1

      • API 2

      • API 3

      • API 4

      • API 5



    • Ejemplos Api's



      • Ejemplo 1

      • Ejemplo 2

      • Ejemplo 3



    • Aplicaciones



      • App Web 1

      • App Web 2



    • Distribuciones



      • Distribución Con Jetty integrado

      • Distribución de API's con librerías de terceros incluidas

      • Distribución en formato EAR







Es complicadillo, lo bueno es que con maven resulta muy natural motar algo así, y utilizando la herencia en los POM's puedes poner cada cosa en su sitio sin tener que duplicar las dependencias en cada pom. Por ejemplo, las aplicaciones dependen los los API's, con lo que las dependencias no están definidas en cada aplicación sino en el pom de 'Aplicaciones', esto es utilisimo para mantener el build manejable y las cosas en un solo sitio. O por ejemplo puedes cambiar en el super-pom la versión del jdbc de mysql, ejecutar el build desde arriba, y si todos tus test pasan sabes en 5 minutos que tu aplicación funciona con la nueva versión, espectacular!.



Conclusiones



Pues de momento muy buenas, pensaba que iba a ser un cambio mucho más complejo y en menos de una semana hemos montado todo el tinglao sin mucho problema. Quitando algún tema con el encoding, alguna chorradilla con los classpath de ejecución y poco más, y más bien por nuestro desconocimiento que por culpa de la herramienta. Cuando llevemos unos meses así ya os contaré a ver si mi opinión sobre maven sigue siendo tan positiva como hasta ahora jeje.



El único problema 'serio' que tenemos hasta ahora es con los analisis de cobertura, tenemos un proyecto de test funcionales donde metemos pruebas de aceptación y sistema, es decir, pruebas que afectan a código que esta en otros modulos. El problema es que el plugin de cobertura no computa esta cobertura junto con la del resto (la de las pruebas unitarias de cada proyecto) con lo que en el informe final de cobertura perdemos el porcentaje correspondiente a los test funcionales. Con lo que pasamos de un casi 70% de cobertura en los api's a algo menos de 50%. Ya os contare cuando encontremos una solución para esto. Pero vamos, si este es nuestro mayor problema... es que la cosa no va mal jeje

"

jueves, 10 de septiembre de 2009

Disponible la primera versión de los plugins para integrar Maven y Bugzilla

Disponible la primera versión de los plugins para integrar Maven y Bugzilla: "

Autentia ha desarrollado dos plugins de Maven para sacar más partido al Bugzilla (https://sourceforge.net/projects/bugzillachanges/):



Ambos plugins son free-software, y se encuentran bajo la licencia GPL.

En la página de SourceForge (https://sourceforge.net/projects/bugzillachanges/) está disponible todos los binarios, así como el código fuente en el repositorio de Subversion.

En breve se publicarán tutoriales para facilitar su instalación y uso.

Desde aquí os animamos a colaborar.

Un saludo - rcanales



Noticia publicada en www.javahispano.org. Accede a la página web y participa"

martes, 8 de septiembre de 2009

Los puntos grises de la elección de la norma japonesa-brasileña de TV Digital

Los puntos grises de la elección de la norma japonesa-brasileña de TV Digital: "Para Carrier y Asociados, queda por saber si habrá financiamiento para la producción de conversores y televisores, qué sucederá con el actual espectro en uso, o cuál será la relación con Brasil. Criticó que la migración llevará 10 años, que en cuestiones tecnológicas es 'un siglo o más”"

Scrum y XP: planificación de Sprint II

Scrum y XP: planificación de Sprint II: "

Despues de siglos sin escribir nada ya toca seguir con la serie de entradas sobre Scrum y XP, ultimamente he tenido mucho trabajo y poco tiempo para escribir, a partir de ahora espero volver a tener un ritmo más regular publicando entradas en el blog, bueno, al menos eso espero...



En la entrada anterior hablamos sobre la reunión de planificación de sprint, abordamos los requisitos previos que debian cumplirse antes de la reunión y la primera parte de la reunión, en esta entrada intentaré explicar la segunda parte de la reunión, en la que se lleva a cabo el trabajo realmente duro: planificar las historias



División de la historia en tareas



Las historias son funcionalidades definidas desde el punto de vista del product owner, en otras palabras, una historia debe ser algo que aporte valor al cliente, cosas como por ejemplo 'permitir que los usuarios se validen a través de un servidor LDAP'. Lo primero que hace el equipo con cada historia es dividirla en tareas ya desde el punto de vista tecnico para poder estimar mejor la historia. Por ejemplo el equipo podría dividir la historia anterior en cosas como:




  • Crear una nueva implementación de la interfaz de validación que utilize LDAP

  • Crear una nueva opción de configuración que permita elegir entre validación LDAP u otras

  • Sincronizar los usuarios del LDAP con los de nuestra base de datos



Una vez que la historia queda divida en tareas técnicas el siguiente paso consiste en estimar lo que nos costará realizar la historia. Aqui hay dos posibilidades:




  • Dividir N historias en tareas y luego estimarlas todas

  • Estimar una historia justo despues de dividirla en tareas



En nuestro caso preferimos dividir primero en tareas todas las historias que más o menos sabemos que entrarán en el sprint y luego estimarlas, si despues de la estimación vemos que cabe alguna historia más pues cojemos la siguiente del PB y la dividimos en tareas.



Estimación en puntos de cada tarea



Ahora pasamos a estimar en puntos cada tarea, la estimación de la historia completa es simplemente la suma de puntos de las tareas definidas para esta por el equipo. Para la planificación nosotros utilizamos la conocida tecnica de la planificación poquer (lo escribo así, porque si lo escribo bien el blog no me deja publicar la entrada..., y llevo toda la tarde pegandome con esto :P, supongo que será cosa del anti-spam o algo similar que no le gusta la palabra po.. ya sabeis...)





Esta tecnica es muy simple, cada miembro del equipo cuenta con un baraja con varias cartas como las de la imagen, el Scrum Master inicia la ronda de estimación para una tarea, cada miembro del equipo pone una carta sobre la mesa (boca abajo claro :P ) y cuando todos han decidido se levantan las cartas y se decide la estimación como el valor más aproximado a la media de lo que todos han dicho.



Mucho más importante que elegir el valor medio es la discusión que se produce entre los miembros del equipo cuando se ponen valores muy dispares, si por ejemplo alguien estima la tarea en un día y otro la estima en 5 esta claro que algo raro esta pasando, o bien el que estima en 1 día conoce alguna forma de terminar la tarea muy rapido (por ejemplo alguna librería que solventa el problema que el resto no conoce), o bien el que estima en 5 ha visto algún problema que del que el resto no es consciente (de integración con otros modulos, de viabilidad tecnologica o lo que sea).



Esto de la planificación poquer a algunes les parece 'algo poco serio', sin embargo yo creo que es todo lo contrario, mucho menos serio me parece cualquier estimación kilometrica tipo condena de las de 6 meses y un día... aunque le dejes al desarrollador una semana para que estime en detalle, da igual, no va a acertar, probablemente ni se acerque, y cualquier empresa tiene un historico de estimaciones desviadas que lo demuestra, así que despues de llevar años y años fallando en todas y cada una de las estimaciones que se hacen... ¿porque no intentarlon otros enfoques?



Nuestra experiencia despues de mas de un año usando este tecnica es muy positiva, si bien al principio nos equivocamos bastante hemos ido aprendiendo de los errores y ahora nuestras planificaciones son mucho más precisas. Que no quiere decir esto que acertemos siempre, no somos nostradamus, pero si ajustamos bastante bien y como mucho se nos puede quedar una historia fuera del sprint, evidentemente ayuda que las historias sean cortas y los sprints también sean cortos, de modo que si algo se queda fuera pues tampoco es ningún drama, será la historia menos prioritaria y estará lista para el siguiente sprint en dos semanas.



Definición de terminado de una historia



Otro punto critico es definir los criterios para dar una historia por terminada, en las tarjetas de cada historia dejamos un hueco para rellenar donde pone: '¿Como probarlo?', si se cumplen las condiciones que que se indiquen en el '¿Como probarlo?' más lo que hemos definido que tiene que cumplir cualquier historia damos esa historia por cerrada.



Esto que parece facil cuando uno lo piensa en la practica es bastante complejo, en definitiva cuando defines como probar una historia estas definiendo el alcance de la misma, y no simpere es facil, es importante ponerse a definir esto junto con el product owner porque pensando en como probar la historia surjen muchos detalles que ayudan a que se entienda mejor el alcance de la historia tanto por parte del product owner como por parte del equipo.



Por ejemplo para la historia del LDAP podría ser algo tan simple como 'entrar a la aplicación y cuando se nos pida usuario y password introducir los de un usuario creado en el LDAP, deberiamos poder entrar a la aplicación y en nuestra base de datos se crearía el nuevo usuario sincronizandolo con la información del LDAP'.



Fijaros que simplemente con la definición anterior pueden surjir varias dudas: ¿Que información debemos sincronizar?, ¿Cuando el usuario entre por segunda vez volvemos a sincronizar la información?, ¿Si ya tenemos un usuario en nuestra base de datos con el mismo nombre que otro de LDAP que hacemos?



Estas dudas las tendrá que resolver el equipo junto al product owner y decidir que hacer en cada caso completando y haciendo lo más precisa posible la definición de terminado. En muchas ocasiones nos ha pasado que creiamos haber entendido perfectamente una historia y al ponernos a definir esta parte nos hemos dado cuenta de que no teniamos la misma visión sobre la historia que el product owner. Una de las mejores cosas de esta reunión de planificación es precisamente hablar 'cara a cara' con el dueño del producto y no que todo se reduzca a un documento de especificaciones, por supuesto ambiguo.. siempre son ambiguos, que el equipo entiende como buenamente puede...



Además de el '¿Como probarlo?' de cada historia tenemos una serie de condiciones que tienen que cumplirse para dar cualquier historia por terminada, estas son generales a cualquier historia y deben cumplirse siempre:




  • Aceptación: El criterio de cómo probarlo está acordado, escrito, y el programa supera la prueba. Ultimamente hemos empezado a escribir primero las pruebas funcionales de aceptación antes de tirar uno sóla linea de código de la aplicación. Tenemos pendiente revisar herramientas como fitnesse o concordion para mejorar en este apartado

  • Pruebas: El código desarrollado supera las pruebas unitarias y la cobertura de pruebas ha sido revisada y considerada aceptable por el equipo.

  • Calidad del código: revisar que el código cumple con las normas de estilo definidas. Por lo menos verificar que añadido el nuevo código para la historia no se disparan las graficas de incumplimiento de normas de manera alarmarte. Para mejorar esta gestión estamos introduciendo el uso de sonar, magnifica herramienta por cierto.

  • i18n: El código desarrollado está internacionalizado. Es una caracteristica que se debe cumplir en toda nuestra aplicación, no tiene sentido definirla historia por historia como un criterio de aceptación.

  • Trazable: El código desarrollado tiene integrado el log.

  • Documentado: Existe una documentación de desarrollo sobre la historia.

  • Integrado: el código esta integrado con la rama principal de desarrollo y es posible descargarlo de algún lugar y ejecutarlo para probar la historia. Vamos que no vale con 'works on my machine', la historia debe estar integrada con el resto de la aplicación y funcionando.



Estas son las normas que nosotros mismo nos hemos impuesto cumplir para dar una historia por terminada, depediendo del contexto cada equipo debera definir las suyas. Esto que puede parecer mucha cosa para cada historia es fundamental si no queremos estar generando constantemente deuda tecnica, no se trata solo de terminar las historias, hay que terminarlas bien. Y es importante hacer entender esto al PO, que no son caprichos de desarrolladores quisquillosos, es que si no hacemos estas cosas luego lo vamos a pagar con un proyecto inmantenible donde añadir o modificar algo empieze a costar cada vez más y más. Me gusto una frase que lei el otro día no recuerdo donde 'El factor que más influye en la productividad de hoy es la calidad del código que escribiste ayer'



Problemas y malos habitos



Durante el año que llevamos aplicando estas tenicas hemos detectado algunos problemas que pueden echar al traste estas reuniones o convertirlas en totalmente improductivas:




  • El Product Owner no tiene claras la historias. Este es el mayor problema en estas reuniones, que el product owner no tenga claro que es exactamente lo que quiera, que solo tenga 'ideas vagas' y en cuanto el equipo empieza a preguntarle detalles no sepa responder adecuadamente. Cuando ocurre esto al final las reuniones se eternizan porque se dedica más tiempo a discutir el alcance de las historias (que el PO debería tener claro antes de acudir a esta reunión) que realmente en planificar las historias. Cuando ocurre esto el SM tiene que ponerle las pilas al PO para que haga su trabajo, y esto no siempre es facil porque es habitual que el PO sea alguien con más peso en la jerarquia de la empresa. Esto es habitual en organizaciones clasicas que se pasan al agilismo, pero bueno aqui el SM tiene que hacer uso de unos de los valores que exigia XP: 'el coraje' :P


  • Los miembros del equipo son de nivel muy diferente, esto nos es que sea un problema en si mismo, pero un desarrollador senior puede estimar algo en un punto y un junior en 5. Lo importante aqui es que el junior no se deje influir por las estimaciones del senior, si hacemos esto al final saldremos de la reunión con un sprint que podrían asumir 5 seniors, pero nosotros tenemos 1 senior y 4 junior!!. Cada cual debe tratar de ser sincero con lo que EL tardaria en terminar la historia.


  • Estimaciones para cubrirse las espaldas, la gente que viene de otros modelos tiende a sobrestimar (y a veces mucho) para cubrirse las espaldas, es importante dejar claro que en Scrum lo que importa es ser realista y si luego no se puede cumplir algo tampoco se viene el mundo abajo, estamos haciendo entregas parciales cada 2 o 3 semanas, si en una entrega parcial en lugar de 3 historias van 2 y se deja la otra para el siguiente sprint NO PASA NADA. Lo importante es que la gente no estime siempre 3 puntos más 'por si acaso' hay que evitar la cultura del castigo si no llegas a la estimación y fomentar una cultura de sinceridad y colaboración entre el equipo y el PO. Si hay confianza la gente dejara de usar las estimaciones como armas arrojadizas y dedicarse a dar cada uno su mejor esfuerzo por sacar las cosas adelante. Ya se que esto suena muy bonito pero en ciertas organizaciones es más utopico que otra cosa, pero bueno, hay que intentarlo!!.



Fin de la reunión y al tajo!



Cuando ya hemos estimado todas las historias que podemos acometer dentro del sprint (a veces estimamos una más por si luego tenemos tiempo) damos por finalizada la reunión, nos llevamos nuestras cartulinas a la sala de trabajo las pegamos en la pared y empieza un nuevo sprint!.



En las siguientes entradas trataré como llevamos el tema de las demos y la retrospectiva, una vez visto esto ya entraré en materia con la parte que más me gusta, las practicas puramente tecnicas como pruebas unitarias, integración continua y todas estas cosas.



Entradas anteriores de esta serie:



"

miércoles, 2 de septiembre de 2009

How To Behave Like a Professional Project Manager

How To Behave Like a Professional Project Manager: "

  • Have all the facts at hand



  • No searching through your notes.

  • No making things up

  • No trying to convince people your idea is better in the absence of actual field experience and testimony that it is in fact better

  • Understand - in depth - the context and domain of any topic of discussion before provided suggested alternatives



  • Speak only in actionable outcomes



  • What does done look like?

  • How will we recognize done when we see it?

  • Speak with nouns and verbs about the deliverable and its maturity - "The Preliminary Design of the Transaction Processing System is Complete"



  • Speak in units of measure meaningful to the participants



  • These units are always time and money

  • We'll be done on or before this time with this confidence

  • It will cost this much or less with this confidence



  • Have tangible evidence of physical progress to plan



  • First have a plan that shows when you will have tangible evidence of progress

  • This evidence must be a "working" thing that the customer will recognize as something they asked you to build. It can be software, a piece of hardware, or even a document.

  • This evidence must be compared against the quality standards agreed to before the work started.

  • Again this is one of the "what does done look like" questions



  • Use a credible form of measurement for assessing progress to plan



  • Earned Value is the best


"