martes, 20 de mayo de 2008

He leído: Agile Project Management with Scrum







Título: Agile Project Management with Scrum
Autor: Ken Schwaber
Editorial: Microsoft Press
ISBN-10: 073561993X
ISBN-13: 978-0735619937
Páginas: 192

En Amazon



Me gustó:
Antes de nada recordar que Ken Schwaber, junto con Jeff Sutherland, es uno de los creadores de SCRUM, por lo que leer un libro suyo es como si Pitágoras te enseñase matemáticas o Kant filosofía.

El libro está planteado mediante una serie de (supuestos) casos prácticos que le sucedieron a Ken durante su trabajo como Scrum Master en varios proyectos. En estos casos se plantean (de forma muy acertada) situaciones tanto de conceptos de SCRUM como de soluciones para el día a día.

Ya sólo con echarle un vistazo al índice nos damos cuenta que se tratarán todos los aspectos relevantes sobre SCRUM: el Scrum Master, el Producto Owner, el equipo, los informes, ... Pero lo interesante es cómo se tratan, porque la base teórica del SCRUM se deja para el primer capítulo y los 3 apéndices finales, mientras que el resto de capítulos son casos sumamente prácticos, en los que se plantea una problemática (que podría suceder en cualquier empresa que esté implantando SCRUM) y se muestra una posible solución. Además, cada capítulo acaba con una reflexión del autor, un “Lecciones aprendidas” que resulta muy didáctico.

El libro es muy fácil de leer, aunque está en inglés no abusa del vocabulario técnico, y es muy ameno porque los casos que se plantean se van encadenando a lo largo de los capítulos pero con cierta independencia, lo que no te obliga a recordar qué había pasado en un momento anterior.

No me gustó:
Algunos casos de los que se plantean en el libro son un poco “increíbles”, digamos que se solucionan de una manera demasiado sencilla y sin que implique las duras batallas que todos hemos librados con nuestros jefes, compañeros o clientes.

En mi opinión se da una visión demasiado subjetiva sobre SCRUM, resaltando todas sus bondades y presentándolo como la solución definitiva para la gestión de proyectos. Pero bueno, no me esperaba otra cosa.

Le falta:
Para mi nada, es un libro bastante redondo.

Lo recomiendo para:
Todo aquel que esté planteándose iniciarse en SCRUM, puesto que es una auténtico lujo que uno de sus creadores te lo explique paso a paso.

lunes, 19 de mayo de 2008

DataBindings automágicos (I)

(No, no me he equivocado quería escribir autoMÁGICOS no automáticos :P el porqué ya ser verá en el post)

Hace un par de semanas me mandó un mail un lector del blog (Germán) comentándome una duda con el uso de Datasets tipados como origen de datos en Windows Forms.


Dado que ya me había pasado algo similar en algún proyecto en el que trabajé pero del que no recuerdo cómo lo solucionamos, decidí ponerme manos a la obra para hacer un proyecto que tenga la problemática que me planteó Germán y tratar de encontrar una solución óptima. Y como le comenté a Germán, lo pongo aquí para que le sirva a más gente ;) Vamos a empezar:

Tenemos una base de datos a la que llamaré PRUEBAS, con únicamente 2 tablas: Pedido y DetallePedido, con el siguiente esquema:

Pedido
id -Identity PRIMARY_KEY
Descripcion -Varchar(10)

DetallePedido
idDetalle - Identity PRIMARY_KEY
idPedido - Int
Cantidad - Int
Precio - Float

Típicas tablas maestro-detalle, relacionadas por Pedido.id – DetallePedido.idPedido


Creamos un proyecto Windows Form en Visual Studio 2005, y añadimos un Dataset donde agregamos las 2 tablas, que nos quedará de la siguiente forma:





Ahora nos vamos al formulario, y desde el explorador de Origenes de Datos, arrastramos los campos de la tabla Pedidos y los relacionados de DetallesPedido (Atención: tiene que ser el que cuelga de Pedido para que nos mantenga la relación)





Con lo que el formulario nos quedará más o menos así:


Ahora nos vamos a código y buscamos el evento pedidoBindingNavigatorSaveItem_Click que es el que se produce cuando presionamos el botón de Guardar Cambios, y añadimos las 2 líneas en rojo para que guarde también las líneas de detalle:

private void pedidoBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
this.Validate();
this.pedidoBindingSource.EndEdit();
this.pedidoTableAdapter.Update(this.dataSet1.Pedido);
this.detalle_PedidoBindingSource.EndEdit();
this.detalle_PedidoTableAdapter.Update(this.dataSet1.Detalle_Pedido);
}

Si lo probamos debería funcionar perfectamente, permitiendo movernos entre registros, agregar nuevos pedidos y sus líneas de detalle correspondientes. Ahora viene el problema que nos plantea Germán, ¿y si hay 2 usuarios añadiendo pedidos a la vez?

Pues vamos a probarlo, compilamos, arrancamos 2 veces el ejecutable y creamos un nuevo pedido en cada instancia. ¿Qué sucede? Como es normal asigna un valor al campo id del pedido, que obtiene de sumarle 1 al último valor más grande que exista en la tabla ese momento (ojo: no es el valor que le corresponda al IDENTITY) con lo que nos dará el mismo valor para las 2 instancias.




No vamos a hacer nada más por ahora, guardamos y vemos que pasa.



Como es normal nos ha actualizado el id del pedido con el valor que le ha asignado en la tabla de la base de datos. Bien, es el comportamiento normal y esperado.

Vale, ahora vamos a introducir líneas en estos 2 pedidos que acabamos de guardar:



Como en el caso de las cabeceras de pedido, nos asigna un valor al campo idDetalle, que vuelve a ser el valor máximo del campo en la tabla sumándole 1, con lo que vuelve a ser el mismo valor para las 2 instancias. Guardamos y nos asigna el valor que le corresponde en la tabla.



Vale, todo va bien, hemos añadido una cabecera y una línea y no hay ningún problema, ¿seguro que no hay problemas?

Vamos a hacer lo mismo que antes pero cambiando un poco la forma de hacerlo, ahora vamos a guardar después de añadir la línea de detalle, a ver qué pasa.

Vaya sorpresa, nos ha desaparecido la línea del 2º pedido que guardemos, ahora si nos movemos por los registros esa línea no aparece en ninguna de las 2 instancias, pero si nos vamos a la tabla veremos que está con el identificador que le asignó a la primera instancia que se guardó.

Si cerramos los formularios y volvemos a abrirlos nos encontraremos un pedido con 2 líneas y otro sin líneas. Esto se debe a que al asignar el valor del identificador a las cabeceras también lo hace con las líneas, pero al guardar no actualiza el identificador del pedido en las líneas, con lo que se queda el que tenía en un principio ... ups, vaya lío que hemos montado, ¿no?

Bueno, creo que ya se puede ver por donde van los tiros: ¿nos fiamos o no nos fiamos del código generado automáticamente al arrastar elementos desde los orígenes de datos?

Como este post ya es bastante largo, os presentaré más cosas sobre DataBinding, más problemas y cómo solucionarlos en un próximo post, permanecer atentos al blog :)