<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6322324553987609211</id><updated>2011-12-28T19:37:32.785+01:00</updated><category term='integración continua'/><category term='Acceso a datos'/><category term='DataGridView'/><category term='Visual Studio'/><category term='Connection Pooling'/><category term='kata'/><category term='estandarizar'/><category term='procedimientos almacenados'/><category term='bugs'/><category term='CodedUI'/><category term='código'/><category term='desarrollo'/><category term='SQLServer'/><category term='scrum master'/><category term='firebird'/><category term='user stories'/><category term='framework 3.5'/><category term='sprint'/><category term='corral'/><category term='libros'/><category term='estimación'/><category term='Hudson'/><category term='diseño'/><category term='product owner'/><category term='bdd'/><category term='System.IO'/><category term='calendario'/><category term='WinForms'/><category term='xp'/><category term='agil'/><category term='cas2010'/><category term='quesada'/><category term='gestión de proyectos'/><category term='ágil'/><category term='metodologías'/><category term='re-estimating'/><category term='FileSystemWatcher'/><category term='heredar'/><category term='kniberg'/><category term='legibilidad'/><category term='pair programming'/><category term='burndown chart'/><category term='Asynchronous Programming'/><category term='coding dojo'/><category term='planning poker'/><category term='equipo'/><category term='GDI+'/><category term='agilidad'/><category term='programación asíncrona .net multihilo eventos'/><category term='framework'/><category term='Robert C.Martin'/><category term='XNA Studio'/><category term='tablero scrum'/><category term='base de datos'/><category term='subversion'/><category term='entregas'/><category term='albaldejo'/><category term='timers'/><category term='testeo unitario'/><category term='Microsoft'/><category term='Zaragoza'/><category term='.Net'/><category term='sprint backlog'/><category term='evento'/><category term='aos2011'/><category term='testeo funcional'/><category term='jeff sutherland'/><category term='barcelona'/><category term='agile'/><category term='kanban'/><category term='aos2010'/><category term='tdd'/><category term='instalación'/><category term='TextBox'/><category term='Clean Code'/><category term='experiencias'/><category term='monitorizar'/><category term='conferencia'/><category term='agile-spain'/><category term='mitos'/><category term='reuniones'/><category term='stored procedures'/><category term='Market Place'/><category term='geeksms'/><category term='planificación'/><category term='WP7'/><category term='open space'/><category term='estilo'/><category term='C#'/><category term='framework 2.0'/><category term='scrum'/><category term='comunidad'/><category term='CodeRetreat'/><category term='asíncrono'/><category term='TaskBoard'/><category term='product backlog'/><category term='refactorizar'/><category term='programar'/><category term='excepciones'/><category term='medinilla'/><category term='Silverlight'/><title type='text'>DEVNETTIPS</title><subtitle type='html'>Nuestra visión del desarrollo y las metodologías ágiles</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>54</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-8936401514204841396</id><published>2011-06-23T08:36:00.000+02:00</published><updated>2011-06-23T08:36:07.498+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='aos2011'/><title type='text'>Mi AOS2011</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Me encantan los Open Spaces. Mi primera experiéncia fue en &lt;a href="http://devnettips.blogspot.com/2009/03/agile-open-buenos-aires.html" target="_blank" title="Agile Open Buenos Aires 2009"&gt;Buenos Aires&lt;/a&gt; en marzo de 2009, y supuso una revolución para mi  en la forma de encarar la organización de eventos. El segundo fue el del año  pasado en &lt;a href="http://www.aos2010.agile-spain.com/" target="_blank" title="Agile Open Spain Barcelona"&gt;Barcelona&lt;/a&gt;, en el  que, a parte, participé en la organización. Y este fin de semana se realizó el  &lt;a href="http://aos2011.agile-spain.org/" target="_blank" title="Agile Open Spain 2011"&gt;Agile Open Spain 2011&lt;/a&gt; en Pamplona, al que no podia faltar.  Como siempre me encontré allí a un montón de &lt;a href="http://twitter.com/#!/david_bonilla/aos2011" target="_blank" title="Asistentes al AOS2011"&gt;amigos&lt;/a&gt;,  aunque la novedad de este año fue poder ir acompañado de casi la totalidad de la  gente de la oficina de &lt;a href="http://www.plainconcepts.com/" target="_blank" title="Plain Concepts"&gt;Plain Concepts&lt;/a&gt; en  Bilbao.&lt;br /&gt;&lt;br /&gt;Una de las razones por las que me encantan los Open Spaces es porque creo que  ejemplifican a la perfección el espiritu del agilismo. Es un evento hecho por la  comunidad para la comunidad. Por supuesto que necesita un comité organizador ( y  que lo hicieron a la perfección ) para todo el tema logístico, pero la "chicha"  del evento, las 36 charlas que hubo, fueron un trabajo de los miembros de la  comunidad para los miembros de la comunidad. Se formaron 36 equipos enfocados en  dar el máximo valor posible a las charlas.&lt;br /&gt;&lt;br /&gt;&lt;img alt="" border="0" src="http://farm4.static.flickr.com/3247/5849920165_a6a8727789.jpg" style="max-height: 332px; max-width: 500px;" /&gt;&lt;br /&gt;&lt;br /&gt;Yo propuse una charla sobre calidad del código que fue bien recibida y que  creo que estubo bastante bien, aunque no se tocaron todos los temas que me  hubieran gustado. La discusión se centró sobretodo en la cobertura de tests y en  los comentarios en el código. También se habló de los equipos de QA.&lt;br /&gt;&lt;br /&gt;Por otra parte asistí a charlas tan variopintas como Stubs, Mocks y  Spies, taller práctico de histórias de usuario, talento, estimaciones, deduda  técnica y romper la rutina. &lt;br /&gt;&lt;br /&gt;Por encima de las charlas en sí ( que podéis ver en detalle en los diferentes  &lt;a href="https://sites.google.com/site/agilespain/referencias/agile-open-spain-2011?pli=1" target="_blank" title="Resúmenes AOS2011"&gt;resúmenes&lt;/a&gt; hechos por los participantes ) yo me quedo con las  personas que asistieron al evento. Se reunieron 150 personas preocupadas por su  profesión, con ganas de mejorar su entorno, con ganas de hacer cosas para ellos  y para los demás y comprometidos con la excelencia.&lt;br /&gt;&lt;br /&gt;Espero ya con ganas el Agile Open Spain del año que viene, en el que espero  veros a muchos de vosotros.&lt;br /&gt;&lt;br /&gt;Un saludo! &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-8936401514204841396?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/8936401514204841396/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=8936401514204841396' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8936401514204841396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8936401514204841396'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/06/mi-aos2011.html' title='Mi AOS2011'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3247/5849920165_a6a8727789_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-270664738415583181</id><published>2011-06-23T08:35:00.002+02:00</published><updated>2011-06-23T08:35:29.627+02:00</updated><title type='text'>Instalar una plantilla metodológica en castellano en un TFS2010 en inglés</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Puede darse el caso que tengamos un TFS 2010 instalado en inglés pero nos  interese cargar una plantilla metodológica en castellano. Nuestro primer impulso  será cargar la plantilla metodológica sin hacer ningún cambio en nuestro  servidor y crear un proyecto con ella. A veces es bueno seguir los impulsos, así  que vamos a ello.&lt;br /&gt;&lt;br /&gt;En nuestro querido Visual Studio 2010 vamos al menú Team y abrimos el Process  Template Manager:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/OpenProcessTemplateManager.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/OpenProcessTemplateManager.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ProcessTemplateManager.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ProcessTemplateManager.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y seleccionamos nuestra plantilla para cargar. Se carga la plantilla  correctamente y se nos añade a la lista de plantillas disponibles.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ProcessTemplateLoaded.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ProcessTemplateLoaded.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Una vez cargada la plantilla ya podemos crear un nuevo Team Project con ella,  así que creamos un Team Project con el Team Explorer y como plantilla  metodológica escogemos la plantilla recién subida. Todo parece ir bien hasta  que...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ErrorCreacionProyecto.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ErrorCreacionProyecto.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Le hechamos una ojeada al log y vemos que el error está en la creación del  portal de Sharepoint ya que no encuentra un template del site para el idioma  español (3082):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/LogErrorCreacionProyecto.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/LogErrorCreacionProyecto.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para solucionar esto nos vamos a la web de Microsoft a descargarnos el  Language Pack para nuestra versión de Sharepoint, en nuestro caso la 3.0. Y la  instalamos, claro. Al finalizar la instalación nos pedirá si queremos ejecutar  el asistente para configuración de Productos y Tecnologías de SharePoint.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InstalarLanguagePack.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InstalarLanguagePack.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Le decimos que si y nos ejecutará el asistente, que prácticamente no  requiere de nuestra intervención.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Wizard1.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Wizard1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y si todo ha ido bien:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Wizard2.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Wizard2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si nos vamos a la carpeta C:\Program Files\Common Files\microsoft shared\Web  Server Extensions\12\TEMPLATE\1033\XML (inglés) veremos que tiene un fichero (  WEBTEMP.Microsoft.TeamFoundation.SharePoint.Dashboards) que en la carpeta  C:\Program Files\Common Files\microsoft shared\Web Server  Extensions\12\TEMPLATE\3082\XML (español) no está.&lt;br /&gt;&lt;br /&gt;Tenemos que conseguir este archivo de alguna instalación del TFS en español y  copiarlo aquí y volvemos a pasar el asistente para configuración de Productos y  Tecnologías de SharePoint dejando las opciones marcadas por defecto. Una vez  hecho esto ya podemos crear el nuevo proyecto con la plantilla metodológica en  castellano. &lt;br /&gt;&lt;br /&gt;Ahora solo nos faltará editar el portal de proyecto de SharePoint para que  muestre los elementos en castellano en lugar de en inglés.&lt;br /&gt;&lt;br /&gt;Espero que haya servido de ayuda.&lt;br /&gt;&lt;br /&gt;Un saludo!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-270664738415583181?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/270664738415583181/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=270664738415583181' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/270664738415583181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/270664738415583181'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/06/instalar-una-plantilla-metodologica-en.html' title='Instalar una plantilla metodológica en castellano en un TFS2010 en inglés'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1631302695865883337</id><published>2011-06-15T16:57:00.000+02:00</published><updated>2011-06-15T16:57:22.812+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testeo funcional'/><category scheme='http://www.blogger.com/atom/ns#' term='CodedUI'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Codificación manual y enlace a datos de tests funcionales con CodedUI</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;En el &lt;a href="http://devnettips.blogspot.com/2011/06/tests-funcionales-con-codedui.html" target="_blank" title="Tests funcionales con CodedUI"&gt;anterior artículo&lt;/a&gt;, veíamos como hacer un test funcional con  CodedUI grabando nosotros los pasos del test. En el artículo de hoy veremos como  codificar a mano estos pasos, ya que llega a ser más rápido y más flexible  hacerlo así.&lt;br /&gt;&lt;br /&gt;Empezaremos de la misma manera, creando un proyecto de test, añadiéndole un  archivo de test con CodedUI y generando una nueva grabación. La diferencia es  que ahora, en lugar de hacer clic sobre el botón de grabar y empezar a realizar  los pasos, arrancaremos la aplicación y arrastraremos el botón con la cruceta de  la barra del test builder sobre un control de la aplicación, en nuestro caso el  textbox correspondiente a la operación.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/EditSelected.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/EditSelected.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Al hacer esto se nos abrirá la misma pantalla que se nos abrió al hacer la  aserción en el anterior tutorial. Esta vez, haremox clic sobre las dos flechas  hacia la izquierda que hay arriba a la izquierda y se nos abrirá un panel que  contiene un árbol donde se muestran los diferentes controles que vamos  seleccionando.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddControl.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddControl.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seleccionaremos el control que acabamos de añadir y haremos clic sobre el  botón de añadir el control al UI map. Haremos lo mismo con todos los controles,  incluída la cruz de cerrar la aplicación, hasta que nos quede algo parecido a  esto:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FinalAddControl.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FinalAddControl.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora ya podemos hacer clic sobre el botón de generar el código de la  grabación. El Visual Studio detectará que no hemos hecho ninguna grabación y nos  preguntará si queremos que añada los controles seleccionados al UI map del test.  Le diremos que si.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/GenerateUIControlMap.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/GenerateUIControlMap.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si nos fiajmos en el test de donde hemos partido, veremos que no ha cambiado  nada, ya que no se ha realizado ninguna grabación. Vamos ahora a hacer por  código lo mismo que hacia Visual Studio automáticamente por nosotros antes. Para  ello, no vamos a editar el archivo UIMap.Designer.cs, ya que este archivo es  autogenerado y podriamos perder los cambios realizados allí. Para permitirnos  añadir nosotros nuestros tests, Visual Studio nos proporciona una clase parcial  vacia situada en el archivo UIMap.cs. Es aquí donde podemos hacer un método  nuevo con las acciones que queremos que se realicen.&lt;br /&gt;&lt;br /&gt;Empezaremos incluyendo la libreria de testing para los controles Wpf:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/using.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/using.png" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Lanzamos la aplicación a testear:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Launch3.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Launch3.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Launch2.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Launch.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Definimos las variables para manejar los textbox de la calculadora, que en  CodedUI son WpfEdit:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/VariablesWpfEdit.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/VariablesWpfEdit.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora definimos las variables para manejar los botones:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/VariablesButton.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/VariablesButton.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Inicializamos los textboxes con los valores que queremos testear:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InicializacionEdits.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InicializacionEdits.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y simulamos un clic sobre los botones del igual y de cerrar la  aplicación:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ButtonClicks.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ButtonClicks.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora simplemente tenemos que llamar a esta función desde nuestra clase de  test, y veremos que si ejecutamos el test este hace todo lo que le hemos dicho y  pasa correctamente.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CallTest.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CallTest.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Por ahora solo hemos comprobado que la aplicación no le pase nada raro, pero  no hemos comprobado que el resultado sea el correcto. Para ello tenemos que  simular nosotros lo que, cuando grababamos los tests, eran las aserciones.&lt;br /&gt;&lt;br /&gt;Para ello vamos ha hacer algo parecido a lo que hace automáticamente Visual  Studio. Nos vamos a crear una clase que contenga todos los parámetros que  necesitamos ( los dos operandos, la operación  y el resultado de la operación) y  vamos a crearnos una instancia pública de la misma en la clase UIMap.cs:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManualCodedUIParameters.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManualCodedUIParameters.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Modificaremos la función que acabamos de realizar en el UIMap.cs para que  utilice los valores de las propiedades de esta clase y para que, después de  clicar sobre el botón de igual, recupere el valor que hay en el textbox del  resultado:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Parameters.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Parameters.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora sólo nos queda rellenar los valores de los operandos y la operación  desde nuestro test, y hacer un assert del valor esperado con el valor del  parametro Resultado:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConAssert.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConAssert.png" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Y ahora sólo nos queda alimentar este tests con datos provenientes de un XML.  Primero de todo nos creamos el XML, que tendrá una aspecto como este:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DatosXML.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DatosXML.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora le decimos al test que sus datos se alimentaran de este XML. Para  hacerlo, seguiremos los mismos pasos que si quisieramos hacer lo mismo en un  test unitario. Nos vamos a la ventana de test view, seleccionamos el test y en  la ventana de propiedades, clicamos sobre el botón situado en el campo Data  Connection String. Se nos abrirá una pantalla como esta:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/SelectDataSource.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/SelectDataSource.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seleccionamos XML file y clicamos en siguiente. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DataSourceWizard2.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DataSourceWizard2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clicamos sobre siguiente:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/dataSource3.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/dataSource3.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seleccionamos la tabla adecuada en el XML ( en nuestro caso sólo tenemos una  ) y verificamos que los campos sean correctos. Clicamos en finalizar. Nos pedirá  de copiar el archivo en el proyecto y de añadirlo a la lista de items a  desplegar. Le decimos a todo que si.&lt;br /&gt;&lt;br /&gt;Ahora ya estamos preparados para utilizar estos datos. Para hacerlo, nos  ayudaremos de la propiedad DataRow del objeto testContextInstance, de la  siguiente manera:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DataDriven.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/DataDriven.png" /&gt;&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Y ya tenemos el CodedUI tests alimentado con datos de un XML!&lt;br /&gt;&lt;br /&gt;Espero que el tutorial os haya gustado y no os haya aburrido en exceso. &lt;br /&gt;&lt;br /&gt;Un saludo!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1631302695865883337?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1631302695865883337/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1631302695865883337' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1631302695865883337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1631302695865883337'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/06/codificacion-manual-y-enlace-datos-de.html' title='Codificación manual y enlace a datos de tests funcionales con CodedUI'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-6172370328704751380</id><published>2011-06-08T21:44:00.000+02:00</published><updated>2011-06-08T21:44:01.836+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testeo funcional'/><category scheme='http://www.blogger.com/atom/ns#' term='CodedUI'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Tests funcionales con CodedUI</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Como ya muchos sabéis, CodedUI es la tecnología de Microsoft que nos permite  realizar tests funcionales sobre nuestra aplicación, sea esta del tipo que sea.  En el artículo de hoy veremos como crear un test funcional básico y añadirle una  aserción. Empecemos!!&lt;br /&gt;&lt;br /&gt;Lo primero es presentaros la aplicación que vamos a testear. Se trata, como  no, de una pequeña calculadora realizada en WPF y compuesta de 4 textboxes y un  botón. En los tres primeros textboxes introduciremos los operandos y la  operación a realizar y, al apretar el botón, se nos mostrará el resultado en el  último textbox.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Aplicacion.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Aplicacion.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Para realizar los tests vamos a crear un acceso directo a la aplicación en  nuestro escritorio y vamos a añadir un nuevo proyecto de test a la solución. A  continuación, añadiremos un nuevo item al proyecto de test de tipo CodeUITest.  Automáticamente se nos mostrará un cuadro de diálogo que nos da a elegir entre  generar un nuevo grabando acciones o utilizar uno existente. Escogeremos la  primera opción.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/GenerateCodedUITest.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/GenerateCodedUITest.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esto hace que nos aparezca la barra del CodedUI test builder, que es una  pequeña barra que nos ayudará en nuestro cometido.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodedUITestBuilder.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodedUITestBuilder.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Como podéis ver, la barra sólo tiene cuatro botones;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Empezar o pausar la grabación.  &lt;/li&gt;&lt;li&gt;Ver los pasos que llevamos guardados.  &lt;/li&gt;&lt;li&gt;Seleccionar un control para hacer una aserción (luego lo vemos).  &lt;/li&gt;&lt;li&gt;Generar el código de la grabación existente. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Para empezar le daremos al botón de grabar y empezaremos a realizar la prueba  que queremos guardar. En este caso, será hacer doble clic en el acceso directo,  introducir una operación del tipo 5 + 6, darle al botón y cerrar la aplicación.  Esto en nuestra clase de test genera un código tal como este:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodigoTest1.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodigoTest1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ahora veremos un poco más el código interno, pero por ahora nos vamos a  limitar a ejecutar el test. Esto hará magia en nuestro ordenador y se nos abrirá  la aplicación, se tecleará lo mismo que hemos tecleado nosotros, se pulsará el  botón, se mostrará el resultado y se cerrará la aplicación. Ni Tamariz lo haría  mejor!&lt;br /&gt;&lt;br /&gt;Si miramos un poco el código interno, veremos que es prácticamente  auto-explicativo:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InternalTest1.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/InternalTest1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vemos como abre la aplicación, inserta los textos correspondientes y hace  clic en los botones. Destacar sobre todo las tres líneas donde rellenamos los  textboxes, porque lo utilizaremos después para alimenar al test de datos.&lt;br /&gt;&lt;br /&gt;Ahora vamos a hacer una aserción sobre el textbox del resultado. Lo que  queremos es que el test compruebe que la operación es correcta, no sólo que no  hay ningún problema para ejecutarlo. Así pues, vamos a hacer un nuevo test como  si fuera un test unitario, es decir, haciendo un método público decorado con el  atributo [TestMethod]. En el cuerpo del método, hacemos clic con el botón  derecho del ratón y seleccionamos la acción "Generato code for CodedUI test  -&amp;gt; User CodedUI Test Builder":&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NewTest.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NewTest.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Picture.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Picture.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Volvemos a estar como antes, con la barra del CodedUI test builder.  Realizaremos los mismos pasos pero, antes de cerrar la aplicación haremos clic  sobre el botón de pausa y generaremos el códig de los pasos que llevamos hasta  ahora. Ahora, haremos clic en el icono de la aserción y lo arrastraremos hasta  el textbox del resultado. Esto hará que se nos habra la siguiente ventana:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddAssertion.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddAssertion.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hacemos clic con el botón derecho en el campo text y seleccionamos la opción  "Add asertion". Esto nos abre la siguiente pantalla, donde introducimos el valor  que queremos asegurar que se muestre.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddAssertion2.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/AddAssertion2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Generamos el código para la aserción, empezamos otra grabación para grabar el  cierre de la aplicación y generamos el código para esta última acción. El código  resultante tendria que ser algo parecido a esto:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodeTest2.png"&gt;&lt;img alt="" border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/CodeTest2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pasamos el test y vemos que se pone en verde. Si vamos a nuestra  clase calculadora y cambiamos el comportamiento de la suma para que no devuelva  la suma de los dos operandos, veremos que el test deja de pasar.&lt;br /&gt;&lt;br /&gt;Bueno, pues por hoy ya es suficiente. Espero que os haya sido útil el  tutorial. En la próxima entrega, veremos como alimentar este test de datos  provenientes de un XML.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-6172370328704751380?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/6172370328704751380/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=6172370328704751380' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6172370328704751380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6172370328704751380'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/06/tests-funcionales-con-codedui.html' title='Tests funcionales con CodedUI'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-9211407286927965618</id><published>2011-05-16T20:48:00.018+02:00</published><updated>2011-05-17T22:50:19.997+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='desarrollo'/><category scheme='http://www.blogger.com/atom/ns#' term='conferencia'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='metodologías'/><title type='text'>Mis tres días en la XP2011!</title><content type='html'>&lt;div style="text-align: left;"&gt;La semana pasada tuvo lugar en Madrid la conferencia internacional &lt;a href="http://xp2011.org/"&gt;XP2011&lt;/a&gt; sobre metodologías ágiles en desarrollo de software y de sistemas de información, la más grande de Europa y la segunda en tamaño del mundo después de la &lt;a href="http://agile2011.agilealliance.org/"&gt;Agile Conference&lt;/a&gt;que se celebra en Estado Unidos, y tuve la inmensa suerte de asistir durante 3 días (la conferencia duraba 4, pero el primero de ellos no pude estar). Estaba realmente emocionado con la oportunidad ya que se iban a dar cita algunos de los grandes referentes en el mundo del desarrollo ágil de los últimos años cómo &lt;a href="http://www.poppendieck.com/"&gt;Mary y Tom Poppendieck&lt;/a&gt; creadores del término "Lean Software Development", &lt;a href="http://agilemanagement.net/index.php/"&gt;David Anderson&lt;/a&gt; creador de Kanban y muchos otros cómo J.B. Rainsberger, Jurgen Appelo, Michael Feathers...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/-ft5D5XWSyDo/TdLYkIUDsNI/AAAAAAAAALI/Q9o0kmx9iy0/s1600/IMAG0246.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img src="http://4.bp.blogspot.com/-ft5D5XWSyDo/TdLYkIUDsNI/AAAAAAAAALI/Q9o0kmx9iy0/s320/IMAG0246.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5607782601248190674" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 192px; height: 320px; " /&gt;&lt;/a&gt;&lt;div&gt;Así que con las expectativas muy altas llegaba el Miércoles por la mañana con la Keynote de &lt;a href="http://www.estherderby.com/"&gt;Esther Derby&lt;/a&gt; titulada "Still No Silver Bullets" ya empezada. Después de terminar esta y de saludar brevemente a algunos compañeros de diferentes grupos ágiles de España pasamos directamente a las sesiones. El formato de la conferencia durante los dos días intermedios (el primero y el último eran talleres y tutoriales) mezclaba sesiones de una hora entera con lightning talks de 20 o 30 minutos cada una, lo que tiene su lado positivo (dinamiza mucho la conferencia) pero también su lado negativo (muchas veces el tema se toca de manera demasiado superficial).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/-ft5D5XWSyDo/TdLYkIUDsNI/AAAAAAAAALI/Q9o0kmx9iy0/s1600/IMAG0246.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;/a&gt;&lt;div&gt;Aun así salí contento de unas cuantas sesiones sobretodo de las de Jurgen Appelo: "The Purpose of Leadership and Governance"  y la de Angel Medinilla presentando "Scrumban" (divertido e ilustrador como la mayoría de las veces que le he visto).&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;a href="http://2.bp.blogspot.com/-dzjyIk4xLy8/TdLZB3KeDlI/AAAAAAAAALQ/yI_NJraabBc/s1600/IMAG0249.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img src="http://2.bp.blogspot.com/-dzjyIk4xLy8/TdLZB3KeDlI/AAAAAAAAALQ/yI_NJraabBc/s320/IMAG0249.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5607783112040648274" style="float: left; margin-top: 0px; margin-right: 10px; margin-bottom: 10px; margin-left: 0px; cursor: pointer; width: 192px; height: 320px; " /&gt;&lt;/a&gt;&lt;div&gt;El primer día lo acabamos con la creación de la agenda del Open Space que se iba a realizar al día siguiente y más tarde con una cena de gala cortesía de la organización en la casa de campo de Madrid, donde se repartieron los premios a los mejores papers de la conferencia y donde después de la cena unas cuantas personas de la comunidad demostraron que no se les queda pequeño el adjetivo "ágil", con bailes imposibles, saltos fuera de lo común y movimientos de cintura realmente espectaculares... :P&lt;/div&gt;&lt;div&gt;&lt;a href="http://2.bp.blogspot.com/-dzjyIk4xLy8/TdLZB3KeDlI/AAAAAAAAALQ/yI_NJraabBc/s1600/IMAG0249.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;El segundo día siguió un guión  parecido: Keynote de &lt;a href="http://www.exampler.com/"&gt;Brian Marick&lt;/a&gt; (que consiguió que todos los presentes en la sala se pusieran a bailar tango...) y más sesiones y lightning talks. Esta vez creo que acerté un poco más con las sesiones cortas donde hubo cosas realmente curiosas cómo por ejemplo charlas sobre Zombies y Scrum por &lt;a href="http://blog.scrumphony.com/"&gt;Marc Löffler&lt;/a&gt;, sobre rehabilitación de adictos al Command and Control por &lt;a href="http://www.presionblogosferica.com/"&gt;Angel Medinilla &lt;/a&gt; , sobre cómo Scrum podría convertirse en un nuevo paradigma del socialismo por Rafael Viveros (pero socialismo del de verdad, no del que nos venden ciertos políticos del tres al cuarto...) o alguna sesión más convencional sobre cómo empezar a hacer TDD de manera práctica por Thomas Nielssen.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Después de una interesante cena y post-cena por Madrid en compañía de unos chicos Holandeses (de los que no me acuerdo del nombre) nos fuimos a dormir cansados pero con ganas de afrontar el último día de conferencia que a priori se presentaba muy bien ya que se trataba de 2 talleres y tutoriales de 4 horas de duración cada uno.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con 10 minutos de retraso debidos a problemas logísticos entramos al taller sobre Refactoring de Michael Feather's, que supuso una pequeña decepción...ya que la sesión no era de Refactoring!! En disculpa del señor Feathers hay que decir que en la puerta de la sesión había una hoja donde se explicaba cómo iba a ser el taller, pero al llegar tarde no nos dimos cuenta pero... ¿porqué poner ese título?  Aún así la sesión nos sirvió para aprender un poco de Ruby, ya que era el el lenguaje en el que se hacía el taller&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tras pelearnos con Ruby fuimos a comer, y  después una larguísima sobremesa (para mi uno de los únicos fallos de la organización, que por otro lado estuvo genial y además eran gente muy maja y a la que felicito desde aquí) nos dirigimos al último taller. Para el fin de fiesta escogí el taller de Jurgen Appelo, basado en su curso sobre Agile Management y que a priori tenía muy buena pinta. Y la verdad es que no defraudó. Aunque muchos acusan a Appelo de ser un mero recopilador de ideas de otra gente, yo creo que está creando cosas y conceptos interesantes, o por lo menos les está dando una visión que me parece muy adecuada. Además el taller fué entretenido y mezcló la teoría con juegos cómo el &lt;a href="http://www.noop.nl/2011/03/delegation-poker-game-description.html"&gt;Delegation Poker&lt;/a&gt; el &lt;a href="http://www.noop.nl/2011/04/the-art-of-parking-my-car.html"&gt;Meddlers of Catán&lt;/a&gt; o uno sobre una matriz de métricas, todos ellos muy amenos y que además te hacen pensar.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/-HWrpQVxStOg/TdLaWs7tPLI/AAAAAAAAALY/ATGeF3_0c9s/s1600/Meddlers.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img src="http://4.bp.blogspot.com/-HWrpQVxStOg/TdLaWs7tPLI/AAAAAAAAALY/ATGeF3_0c9s/s400/Meddlers.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5607784569583254706" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 352px; " /&gt;&lt;/a&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;Meddlers of Catán de Jurgen Appelo&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Al acabar el taller sólo tuve tiempo de despedirme de la gente y salir corriendo para no perder el AVE de vuelta a Barcelona donde cansado (pero contento por todo lo aprendido, por la experiencia vivida y por poder debatir sobre metodologías ágiles con algunas de las personas más destacadas de este país y de todo el mundo) no tardé en quedarme dormido...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-9211407286927965618?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/9211407286927965618/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=9211407286927965618' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/9211407286927965618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/9211407286927965618'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/05/mis-tres-dias-en-la-xp2011.html' title='Mis tres días en la XP2011!'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-ft5D5XWSyDo/TdLYkIUDsNI/AAAAAAAAALI/Q9o0kmx9iy0/s72-c/IMAG0246.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1490243522680875907</id><published>2011-05-04T20:43:00.014+02:00</published><updated>2011-05-23T22:44:33.622+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mitos'/><category scheme='http://www.blogger.com/atom/ns#' term='agilidad'/><category scheme='http://www.blogger.com/atom/ns#' term='metodologías'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Waterfalacias: Mitos y creencias sobre Scrum</title><content type='html'>&lt;a href="http://4.bp.blogspot.com/-d4FeKwSHTq4/TcmiEyYNqxI/AAAAAAAAAKw/0mxHZRVZ3hQ/s1600/mitos-romanos-aceite-oliva.jpg" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 351px; height: 293px;" src="http://4.bp.blogspot.com/-d4FeKwSHTq4/TcmiEyYNqxI/AAAAAAAAAKw/0mxHZRVZ3hQ/s400/mitos-romanos-aceite-oliva.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5605189414365801234" /&gt;&lt;/a&gt;En toda transición hacia Scrum o cualquier otra metodología ágil es común enfrentarse a un elevado porcentaje de rechazo entre la gente que es parte de ese cambio (de hecho cualquier cambio impuesto suele generar rechazo en primera instancia). Los motivos que esta gente tienen para no aceptar este cambio no  pueden ser de lo mas variado: hay quien tiene miedo a perder poder, otros intuyen que va a tener que "trabajar más" e incluso hay gente que simplemente están contentos con la situación actual, pero curiosamente muchos de ellos suelen coincidir en su argumentario a la hora de explicar el porqué de sus objeciones.&lt;br /&gt;&lt;div&gt;Algunos de estos argumentos comunes los recoge Mike Cohn en su estupendo libro &lt;a href="http://www.amazon.com/Succeeding-Agile-Software-Development-Using/dp/0321579364"&gt;"Succeding With Agile"&lt;/a&gt;, y ciertamente son argumentos que yo mismo me he encontrado o que he escuchado mas de una vez cuando intentas explicar o formar a alguien en metodologías ágiles, y que ya se han convertido en mitos o creencias "populares".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En este artículo voy a intentar desmitificar algunos de estos argumentos, explicando mi visión sobre cada uno de ellos y intentado aclarar el porqué son incorrectos o inexactos. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Empecemos:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;En Scrum no se planifica, por lo tanto no somos capaces de dar estimaciones a nuestros clientes&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Aunque parezca lo contrario en Scrum se planifica bastante más que en las metodologías tradicionales, lo que pasa que esta planificación se lleva a cabo de una manera mucho más "responsable". En lugar de hacer todo el esfuerzo de planificación al inicio, donde la incertidumbre es mayor y estamos sujetos a cualquier tipo de cambio o imprevistos, en Scrum se va planificando durante toda la vida del proyecto, y además a diferentes niveles:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;- Planificación inicial: Donde se crea, prioriza y estima el product backlog inicial del proyecto (normalmente se realiza en una iteración 0 o fase de Inception y los requisitos son definidos a alto nivel)&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;-Planificación durante cada iteración: Donde se refina el product backlog (Product Backlog Grooming) y se decide que se va a llevar a cabo durante la siguiente iteración (Sprint Planning Meeting)&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;-Planificación diaria: Donde el equipo ajusta la operativa del día a día (Daily Meeting)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Así vemos que en Scrum se está planificando continuamente y que la diferencia principal con metodologías más clásicas es que la planificación inicial no es ningún dogma, sinó que a partir de lo que se va aprendiendo durante el proyecto esta se va ajustando para cumplir mejor las expectativas del cliente.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Scrum necesita que todo el mundo sepa hacer de todo&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Otro de los principales mitos de Scrum es que todo el mundo tiene que saber hacer de todo, y esto hace que los especialistas dejen de tener sentido. Aunque bien es cierto que demasiada especialización de los miembros del equipo puede ir en contra de los intereses del proyecto, realmente lo deseable es que "El Equipo" sea multidisciplinar, es decir que entre todos los miembros del mismo reúnan los "skills" necesarios para llevar a cabo el proyecto evitando cosas como equipos de analistas, equipos de testing, etc... que favorecen los nichos de conocimiento y el "lavado de manos" dentro de un proyecto. Si a esto le sumas que las personas que forman estos equipos son capaces de, más allá de su especialidad, ayudar con otras tareas en momentos concretos de los proyectos tenemos equipos donde el conocimiento está muy compartido y donde es difícil ver bloqueos ante la falta de alguno de los miembros.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Tenemos equipos distribuidos y en Scrum es necesaria la comunicación cara a cara&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Al igual que as anteriores ideas, esta proviene de gente que simplemente se ha quedado en la superficie de Scrum y no ha profundizado en la misma. Uno de los principales valores de las metodologías ágiles es la comunicación entre los miembros del equipo , entonces &lt;i&gt;"¿que hacemos si nuestro equipo es distribuido?"&lt;/i&gt; La respuesta más fácil es &lt;i&gt;"no podemos hacer Scrum", &lt;/i&gt;aunque realmente la respuesta correcta sería: &lt;i&gt;"lo mismo que si el equipo está co-localizado", &lt;/i&gt;aunque eso si, con matices. Obviamente la comunicación cara a cara no se sustituye con nada, pero con la tecnología actual deberíamos ser capaces de llevar a cabo un proyecto de manera muy normalizada con nuestros compañeros que trabajan en remoto (videoconferencia, chats, etc...) &lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Los equipos Scrum no documentan y nuestros clientes nos exigen documentación&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;En este punto no voy a comentar demasiado. Simplemente señalar que en Scrum y en las metodologías ágiles en general los documentos son un medio, nunca un fin, y por lo tanto se intenta evitar toda aquella documentación que no sea útil para que el proyecto se lleve a cabo satisfactoriamente y quedarse con aquella que si es importante. Es decisión de cada equipo pensar que es y que no es útil para este fin y actuar en consecuencia.  Pero... ¿de verdad todavía nos creemos que toda la documentación que nos exigen algunas metodologías tradicionales tiene sentido?&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Scrum no tiene en cuenta la arquitectura y el diseño&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Nada más lejos de la realidad. Simplemente que el hecho de definir esta arquitectura y este diseño se lleva a cabo de manera totalmente opuesta a cómo lo intentan hacer las metodologías tradicionales: En Scrum no hay un equipo de "arquitectos" que deciden al principio del proyecto sobre un Power Point cómo va a ser la arquitectura, sino que a partir de unas líneas generales iniciales a alto nivel la arquitectura va emergiendo iteración a iteración a medida que se va desarrollando el proyecto, y además durante todo este tiempo los "arquitectos" trabajan codo a codo con los desarrolladores adaptando la arquitectura a los nuevos requisitos. De hecho en las metodologías ágiles se considera que buena parte del diseño (si no todo) está en el propio código y en consecuencia se le da el estatus y la importancia que eso implica, poniendo mucho énfasis en prácticas de ingeniería que aseguren una alta calidad y mantenibilidad del código (TDD, BDD, Pair Programming, Code Reviews, Continuous Integration, S.O.L.I.D Principles...)&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Nuestros proyectos son demasiado complejos para realizarlos con Scrum&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;Esta es una de las ideas que menos entiendo  ya que en toda la literatura sobre Scrum que he leído nuna he visto nada que pueda dar a entender esto. Precisamente Scrum funciona especialmente bien en proyectos complejos, siendo flexible a posibles cambios durante todo el proyecto, gestionando los riesgos de manera implícita iteración a iteración y potenciando además la creatividad y la innovación de los miembros del equipo lo que garantiza un porcentaje de éxito mucho mayor en cualquier proyecto.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span"  style="font-family:Georgia, serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; "&gt;&lt;div style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;Cómo veis, todos estos argumentos son fácilmente rebatibles desde el raciocinio y el sentido común y no deberían ser un problema real en una implantación de metodologías ágiles. Sin embargo, como ya hemos dicho antes, estas argumentaciones suelen ocultar otro tipo de miedos, y estos son el verdadero desafío a la hora de hacer que la gente esté receptiva o no ante un cambio metodológico.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;/div&gt;&lt;div style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;span class="Apple-style-span"  style="font-family:'times new roman';"&gt;Un saludo!!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1490243522680875907?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1490243522680875907/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1490243522680875907' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1490243522680875907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1490243522680875907'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/05/waterfalacias-mitos-y-creencias-sobre.html' title='Waterfalacias: Mitos y creencias sobre Scrum'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-d4FeKwSHTq4/TcmiEyYNqxI/AAAAAAAAAKw/0mxHZRVZ3hQ/s72-c/mitos-romanos-aceite-oliva.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-5219927781650966978</id><published>2011-03-12T19:34:00.001+01:00</published><updated>2011-03-12T19:34:19.563+01:00</updated><title type='text'>Primeros pasos con Moq ( parte II )</title><content type='html'>&lt;p&gt;Después de unas semanas liadas con el cambio de residencia y la incorporación a &lt;a title="Plain Concepts" href="www.plainconcepts.com" target="_blank"&gt;Plain Concepts&lt;/a&gt; volvemos a la carga con los artículos referentes a &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt; ( &lt;a title="Primeros pasos con Moq ( parte I )" href="http://geeks.ms/blogs/devnettips/archive/2011/01/29/primeros-pasos-con-moq.aspx" target="_blank"&gt;aquí&lt;/a&gt; está el primero de la serie ).&lt;/p&gt;  &lt;p&gt;Empecemos por el principio, es decir, por el constructor de nuestro mock. Al hacer el new tenemos dos opciones a la hora de indicar el comportamiento de nuestro objeto imitador:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;MockBehaviour.Loose: el mock devolverá siempre valores por defecto si no está definido el Returns y si se llama a una función del mock que no tenga un Setup, no lanzará ninguna excepción&lt;/li&gt;    &lt;li&gt;MockBehaviour.Strict: si se llama a una función del mock que no tenga un Setup, se lanzará una excepción y el test fallará.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Yo recomiendo utilizar la segunda opción ( MockBehaviour.Strict ) ya que seremos mucho más conscientes de lo que está haciendo el test.&lt;/p&gt;  &lt;p&gt;En el &lt;a title="Primeros pasos con Moq ( Parte I )" href="http://geeks.ms/blogs/devnettips/archive/2011/01/29/primeros-pasos-con-moq.aspx" target="_blank"&gt;anterior&lt;/a&gt; artículo vimos el uso de la función Verify. Esta función tiene 9 sobrecargas, en las que básicamente se pueden configurar dos cosas:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;El string de error en caso de no cumplirse la condición.&lt;/li&gt;    &lt;li&gt;El número de veces que queremos verificar que se ha hecho la llamada a la función.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Esta segunda opción se hace mediante la utilización de los métodos estáticos de la estructura Times. Ejemplos de utilización podrían ser:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Times.Never(): queremos verificar que la función nunca se llama.&lt;/li&gt;    &lt;li&gt;Times.Once(): queremos verificar que la función sólo se llama una vez.&lt;/li&gt;    &lt;li&gt;Times.Exactly(3): queremos verificar que la función se llama tres veces.&lt;/li&gt;    &lt;li&gt;Times.Between(1, 5, Range.Inclusive): queremos verificar que la función se llama entre 1 y 5 veces, ambas incluidas.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;En el &lt;a title="Primeros pasos con Moq ( Parte 1 )" href="http://geeks.ms/blogs/devnettips/archive/2011/01/29/primeros-pasos-con-moq.aspx" target="_blank"&gt;anterior&lt;/a&gt; artículo también vimos como verificar que se había establecido el valor de una propiedad. Obviamente también podemos verificar que el valor de una propiedad se haya recuperado. Podemos verlo en el siguiente ejemplo:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0080c0"&gt;[TestMethod]       &lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Verify_Timeout_was_get()      &lt;br /&gt;{      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;var&lt;/font&gt; mockDao = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#0080c0"&gt;Mock&lt;/font&gt;&amp;lt;&lt;font color="#0080c0"&gt;IDAO&lt;/font&gt;&amp;gt;();      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0080c0"&gt;AssetManager&lt;/font&gt; assetManager = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#0080c0"&gt;AssetManager&lt;/font&gt;(mockDao.Object);      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mockDao.VerifyGet(dao =&amp;gt; dao.Timeout);      &lt;br /&gt;}&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Siguiendo con las propiedades, también les podemos hacer un setup. La versión más sencilla es tratarlas como una función, de manera que podemos especificar el valor que queremos que devuelvan cuando se les hace un get. Para hacer esto, actuamos como si de una función se tratara:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;mockDao.Setup(dao =&amp;gt; dao.Timeout).Returns(1500);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;La segunda versión es un poco más compleja, no en el código que tenemos que teclear ( muy sencillo ) sino en las funcionalidades que nos da. Si utilizamos el siguiente código:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;mockDao.SetupProperty(dao =&amp;gt; dao.Timeout);&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;estamos indicando a Moq que empiece a trackear la propiedad Timeout, con lo que el mock será consciente de cuando estemos intentando establecer un valor a Timeout y se guardará tal valor para futuros usos. Esto nos permitirá poder escribir un código tal como este:&lt;/p&gt;  &lt;p&gt;&lt;font color="#0080c0"&gt;[TestMethod]     &lt;br /&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;void&lt;/font&gt; Track_timeout_property()    &lt;br /&gt;{    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0000ff"&gt;var&lt;/font&gt; mockDao = new &lt;font color="#0080c0"&gt;Mock&lt;/font&gt;&amp;lt;&lt;font color="#0080c0"&gt;IDAO&lt;/font&gt;&amp;gt;();    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; mockDao.SetupProperty(dao =&amp;gt; dao.Timeout);    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0080c0"&gt;IDAO&lt;/font&gt; idao = mockDao.Object;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; idao.Timeout = 400;    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;font color="#0080c0"&gt;Assert&lt;/font&gt;.AreEqual(400, idao.Timeout);    &lt;br /&gt;}&lt;/p&gt;  &lt;p&gt;Y esto es todo por por hoy. En futuros artículos veremos más características de este framework.&lt;/p&gt;  &lt;p&gt;A testear!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-5219927781650966978?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/5219927781650966978/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=5219927781650966978' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5219927781650966978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5219927781650966978'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/03/primeros-pasos-con-moq-parte-ii.html' title='Primeros pasos con Moq ( parte II )'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-2384519161227189906</id><published>2011-02-21T11:28:00.000+01:00</published><updated>2011-02-21T11:28:01.058+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Market Place'/><category scheme='http://www.blogger.com/atom/ns#' term='XNA Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Silverlight'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><category scheme='http://www.blogger.com/atom/ns#' term='WP7'/><title type='text'>Un vistazo al ecosistema de Windows Phone 7</title><content type='html'>&lt;p&gt;El crecimiento que ha tenido el desarrollo para dispositivos móviles en los últimos años, propiciado por tecnologías como Cloud Computing, el auge de las redes sociales y también, por qué no decirlo, la facilidad de obtener beneficios que tienen los desarrolladores con las tiendas&amp;#160; de aplicaciones (appstore, android market…) invita pensar que el desarrollo para dispositivos móviles (ya sean teléfonos, tablets o lo que venga después) va a ser uno de los mercados más importantes en los próximos años (si no lo es ya), y entrar en él va a ser prácticamente indispensable para todo desarrollador o compañía.&amp;#160; &lt;/p&gt;  &lt;p&gt;Pero entrar en el desarrollo de Smartphones se antoja complicado. La multitud de plataformas ya existentes, y las que están apareciendo, provoca una gran fragmentación en el ecosistema móvil, haciendo difícil la elección de por dónde empezar: ¿Apostamos seguro por los IPhone y IPad? ¿O mejor tirar por la opción “libre” que representa Android?¿Quizás sea mejor apuntar a un tipo de cliente más de negocio cómo el que representa Blackberry?¿Bada, WebOs…? También existe la opción multiplataforma, donde estándares cómo el promovido por WAC y la W3C prometen interoperabilidad total, pero por ahora no pasan de ser intentos más o menos acertados. &lt;/p&gt;  &lt;p&gt;Uno de los últimos grandes actores en sumarse a este mercado ha sido Microsoft, con su SO Windows Phone 7, que viene a sustituir al ya caduco Windows Mobile. A priori se podría pensar que el salto llega un poco tarde, con Apple ya consagrada y Android creciendo cada vez más, pero el buen trabajo realizado con el SO, la gran comunidad de desarrolladores y su reciente alianza con Nokia (anunciada en el pasado Mobile World Congress de Barcelona) hacen que se les haya que tener en cuenta.&lt;/p&gt;  &lt;h3&gt;Interfície gráfica&lt;/h3&gt;  &lt;p&gt;La original y sencilla interfície de usuario hacen de WP7 un sistema fresco y muy atractivo visualmente. Centrándose en el contenido y la tipografía han conseguido desmarcarse de las características interfícies de usuario de sus competidores basadas en listas e iconos, añadiendo además conceptos interesantes cómo el sistema de vista panorámica.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/_EX9ub8lGIsQ/TWI8Dsznx6I/AAAAAAAAAKQ/taM_81JKuQs/s1600-h/image5.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="209" alt="image" src="http://lh3.ggpht.com/_EX9ub8lGIsQ/TWI8ECHYWmI/AAAAAAAAAKU/6NS0_WzYjHA/image_thumb1.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt;&lt;font size="1"&gt; Menú principal de un dispositivo con Windows Phone 7 &lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/_EX9ub8lGIsQ/TWI8IQm83lI/AAAAAAAAAKY/siw7cvaH9i0/s1600-h/image9.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="211" alt="image" src="http://lh4.ggpht.com/_EX9ub8lGIsQ/TWI8J1CCObI/AAAAAAAAAKc/CSh6Btq9RPQ/image_thumb3.png?imgmax=800" width="296" border="0" /&gt;&lt;/a&gt;&lt;font size="1"&gt;Sistema de vista panorámica&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;Desarrollo&lt;/h3&gt;  &lt;p&gt;Siendo el número potencial de usuarios de nuestras aplicaciones mucho menor, por el momento, que el de las otras grandes compañías, ¿qué nos ofrece a los desarrolladores Microsoft para que nos decidamos por ellos?&lt;/p&gt;  &lt;h5&gt;Plataformas y Herramientas &lt;/h5&gt;  &lt;p&gt;Una de las grandes ventajas de Microsoft, es su set de plataformas y herramientas, ya que son las mismas que utilizan los desarrolladores de .Net para web o escritorio. Visual Studio cómo IDE (pudiendo desarrollar en C# o VB.Net), Blend Expression, y Silverlight o XNA Game Studio (para aquellos que quieran desarrollar videojuegos en WP7) permiten una curva de aprendizaje muy pequeña a todos aquellos acostumbrados a desarrollar con ellas, en comparación con el coste de aprender otros lenguajes y plataformas.&lt;/p&gt;  &lt;p&gt;Además estas herramientas, así cómo el emulador de WP7, están disponibles de manera gratuita en &lt;a href="http://create.msdn.com/en-US/" target="_blank"&gt;AppHub&lt;/a&gt;, donde también podéis encontrar otros recursos en forma de foros, tutoriales, etc.&lt;/p&gt;  &lt;h5&gt;Servicios y funcionalidades&lt;/h5&gt;  &lt;p&gt;Las APIs de WP7 proporcionan acceso a funcionalidades del teléfono como la geo-localización, la pantalla multi-táctil, el acelerómetro o el micrófono, además de servicios como la reproducción multimedia o las notificaciones Push (que permiten actualizar los bloques de la pantalla principal).&lt;/p&gt;  &lt;p&gt;Por contra, el sistema no soporta multitarea, dejando en manos de los desarrolladores la opción de implementar opciones de salvar y recuperar el estado (de hecho lo recomiendan cómo Best Practice) para dar la sensación de que la aplicación no deja de funcionar en ningún momento.&lt;/p&gt;  &lt;p&gt;WP7 tampoco permite el acceso a la API nativa de Windows. Microsoft justifica esta decisión en base a asegurar la fiabilidad de las aplicaciones desarrolladas, pero esto penaliza en la extensibilidad y personalización de la plataforma. &lt;/p&gt;  &lt;blockquote&gt;   &lt;p align="center"&gt;&lt;a href="http://lh4.ggpht.com/_EX9ub8lGIsQ/TWI8LyYCJnI/AAAAAAAAAKg/Nid8GtggUOU/s1600-h/image13.png"&gt;&lt;img title="image" style="border-top-width: 0px; display: block; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; border-right-width: 0px" height="150" alt="image" src="http://lh3.ggpht.com/_EX9ub8lGIsQ/TWI8NBrwcbI/AAAAAAAAAKk/xb-8TI4rEws/image_thumb5.png?imgmax=800" width="244" border="0" /&gt;&lt;/a&gt; SDK de WP7&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;La distribución de aplicaciones WP7 se realiza “únicamente” a través del Windows Marketplace. En este sentido la política de Microsoft es bastante cercana a la de Apple, no permitiendo instalar aplicaciones por otra vía que no sea la de su tienda (aunque es probable que haya gente que encuentre atajos :P). La cuota de acceso al Marketplace (para poder subir y vender aplicaciones) son de 99$ al año, y si no lo he entendido mal, el precio mínimo para una aplicación son 0,99$ (no se pueden subir aplicaciones gratuitas??)&lt;/p&gt;  &lt;p&gt;Además, como anécdota, Microsoft no permite subir código libre al Market, lo que ha generado reacciones no muy positivas por parte de la comunidad Open-Source.&lt;/p&gt;  &lt;p&gt;De nuevo Microsoft justifica estas medidas argumentando que así evitan que el Market se llene de aplicaciones absurdas que en muchos casos sólo sirven para perder el tiempo (por ejemplo,Android Market está lleno de ellas) y garantizan un alto nivel de calidad y una gran experiencia de usuario en todas sus aplicaciones.&lt;/p&gt;  &lt;p&gt;Para abrir una cuenta en el MarketPlace se puede hacer también&amp;#160; través del &lt;a href="http://create.msdn.com/en-US/" target="_blank"&gt;AppHub&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Conclusiones&lt;/h3&gt;  &lt;p&gt;El nuevo SO de Microsoft puede llegar a ser un importante animador en el sector de los Smartphones.Aunque de momento esté lejos en cuanto a números de las grandes dominadoras (Apple, Android, RIM…), su nombre, su gran comunidad de desarrolladores y su alianza con un gigante cómo Nokia hace que no haya que perderlo de vista.&lt;/p&gt;  &lt;p&gt;A su favor tiene, además de lo mencionado:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Un SO realmente atractivo visualmente y original que además, da la sensación, funciona con una gran fluidez. &lt;/li&gt;    &lt;li&gt;Herramientas conocidas por todos los desarrolladores Microsoft, permitiendo una curva de aprendizaje muy pequeña &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Y cómo posibles puntos en contra:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Un sistema de distribución bastante restrictivo (aunque a Apple, con un sistema similar no le ha ido nada mal) &lt;/li&gt;    &lt;li&gt;Un SO aún un poco verde &lt;/li&gt;    &lt;li&gt;El limitado número de aplicaciones y clientes en comparación a las otras grandes compañías. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Espero que este pequeño artículo os haya ayudado a tener una idea global sobre WP7 y todo lo que le rodea.&lt;/p&gt;  &lt;p&gt;Un saludo!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-2384519161227189906?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/2384519161227189906/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=2384519161227189906' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2384519161227189906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2384519161227189906'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/02/un-vistazo-al-ecosistema-de-windows.html' title='Un vistazo al ecosistema de Windows Phone 7'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_EX9ub8lGIsQ/TWI8ECHYWmI/AAAAAAAAAKU/6NS0_WzYjHA/s72-c/image_thumb1.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-237649622050969202</id><published>2011-02-01T22:44:00.001+01:00</published><updated>2011-02-01T22:44:28.903+01:00</updated><title type='text'>Estimando en Puntos de Historia</title><content type='html'>&lt;p&gt;Después de una interesante discusión producida ayer en twitter y en la lista de &lt;a href="http://groups.google.com/group/agile-spain" target="_blank"&gt;agile-spain&lt;/a&gt; sobre la estimación en puntos de historia, he estado dándole vueltas al tema y me da la sensación de que es algo que mucha gente cuando empieza con Scrum no tiene demasiado claro. Lo viví en primera persona cuando me tocó supervisar la implantación de Scrum en mi última empresa, llegando incluso a tener discusiones grandes sobre porqué debíamos estimar así y no cómo se había hecho “toda la vida”… Así que me he decidido a aportar mi granito de arena y tratar de explicar de manera sencilla en qué consiste esto de los puntos de historia y qué beneficios aporta.&lt;/p&gt;  &lt;p&gt;Antes de empezar, simplemente explicar, para quien no lo sepa, que los puntos de historia es la medida de estimación utilizada cuando se trabaja con Historias de Usuario, una de las técnicas mas utilizadas al trabajar con la metodología Scrum.&lt;/p&gt;  &lt;h3&gt;Relatividad&lt;/h3&gt;  &lt;p&gt;En primer lugar&amp;#160; los PH son relativos no absolutos. Es decir estimamos en función de la diferencia relativa entre una historia y otra. Si a una historia le damos 1PH, y a otra 3PH, esto únicamente indica que una es el triple que la otra. ¿Pero el triple de qué? Pues eso lo veremos después. Además, la relatividad se aplica entre diferentes equipos, es decir que 3PH para un equipo no tienen que significar lo mismo para otro equipo (aunque trabajen en el mismo proyecto, no importa!!)&lt;/p&gt;  &lt;p&gt;De ahí viene el utilizar la famosa escala de&amp;#160; 0, 1, 2, 3, 5, 8, 13, 40.., ya que lo que interesa no es el valor absoluto, únicamente el orden de magnitud, además de que nos ayuda a evitar la tentación de estimar hasta el más mínimo detalle: ¿Que importancia tiene estimar 40 o 42? Cuanto mas grande es la historia a estimar, menos certeza y precisión tenemos sobre la misma, con lo cual la escala nos ayuda a ser conscientes de esa imprecisión.&lt;/p&gt;  &lt;h3&gt;Tamaño&lt;/h3&gt;  &lt;p&gt;Cuando se estima en puntos de historia, lo que se intenta es dar un valor del TAMAÑO de la historia. ¿Y qué implica Tamaño? Pues yo entiendo que una combinación de:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Complejidad: No es lo mismo implementar una alta en un formulario que, por ejemplo, un algoritmo de inteligencia artificial para un juego &lt;/li&gt;    &lt;li&gt;Esfuerzo: ¿Es una tarea que tengo que repetir en muchos sitios? ¿Me va a llevar mucho tiempo aunque sea una cosa fácil? &lt;/li&gt;    &lt;li&gt;Riesgo: ¿Estamos trabajando con una tecnología desconocida? ¿Tiene la gente del equipo experiencia en el negocio? &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Utilizando cómo métrica el tamaño, sacamos al tiempo de la ecuación, de manera que evitamos la tentación de buscar conflictos del tipo “esta historia debería estar hecha en 3 días, y tu llevas 4”, o cosas de este estilo que suelen aparecer cuando se utiliza la métrica del tiempo.&lt;/p&gt;  &lt;p&gt;Entonces, alguien se preguntará, ¿cómo les decimos a nuestros clientes cuando tenemos listo el producto? Eso lo vamos a ver en el siguiente apartado.&lt;/p&gt;  &lt;h3&gt;Velocidad&lt;/h3&gt;  &lt;p&gt;La velocidad es el factor que nos sirve para ver cuanto trabajo somos capaces de entregar en cada sprint. Si nuestra velocidad son 15PH, estamos diciendo que entregamos 15PH de media en cada iteración. Con esto conseguimos ese factor de conversión de los puntos de historia a fechas, es la manera que tenemos de poder decirle a nuestro cliente cuando estimamos que nuestro producto estará listo (ojo, es una estimación, no hay que caer en el típico error de considerar que las estimaciones son contratos!!)&lt;/p&gt;  &lt;p&gt;Hay que tener cuidado con esto, ya que se puede caer en la tentación de hacer cuentas y empezar a pensar en tiempo en lugar de estimaciones (1 tío 8 horas = 1PH). Esto aunque en media sea cierto no lo va a ser para todas las historias, e incluso es posible que haya historias de 1 punto, que por ejemplo se tarden mas en hacer que una de dos puntos. Por suerte, la velocidad actúa también cómo factor de corrección y a la larga, todas las historias que estén estimadas con los mismos PH van a caer mas o menos en la misma zona (la distribución aproximada debería tener forma de campana de Gauss)&lt;/p&gt;  &lt;h3&gt;Tareas&lt;/h3&gt;  &lt;p&gt;Conviene aclarar que lo que he dicho hasta ahora se refiere a la estimación de historias, no a la de las tareas en las que descomponemos dicha historia durante la planificación de Sprint. No es el objetivo de este post entrar en este tema, así que sólo diré que mi recomendación para la estimación de tareas es:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;No estimarlas &lt;/li&gt;    &lt;li&gt;O dividir la historia en tareas que ocupen aproximadamente un día &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;En Conclusión…&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;Los puntos de historia permiten abstraernos del tiempo a la hora de realizar estimaciones, de manera que podemos centrarnos en aspectos cómo la complejidad o el riesgo de la historia, y valorarla en función de eso. &lt;/li&gt;    &lt;li&gt;Al indicar el tamaño relativo de una historia respecto a otra, es sencillo realizar estimaciones triangulando, con lo cual el proceso,con el tiempo, se vuelve muy eficiente. &lt;/li&gt;    &lt;li&gt;Los PH evitan la especificación al detalle, poniendo de manifiesto el aumento de incertidumbre de una especificación a medida que esta aumenta. &lt;/li&gt;    &lt;li&gt;La velocidad actúa cómo factor de corrección de las desviaciones en las estimaciones y nos permite realizar la conversión a fechas para poder dar plazos de entrega a nuestros clientes o superiores cuando sea necesario. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;A partir de aquí lo que toca es experimentar y probar,e intentar encontrar la medida de estimación que mejor se adapte a nuestro equipo, aunque yo sin duda recomiendo encarecidamente probar con los PH!&lt;/p&gt;  &lt;p&gt;Ya sabéis, cualquier comentario será bienvenido!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-237649622050969202?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/237649622050969202/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=237649622050969202' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/237649622050969202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/237649622050969202'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/02/estimando-en-puntos-de-historia.html' title='Estimando en Puntos de Historia'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-6382063630655674771</id><published>2011-01-29T22:05:00.001+01:00</published><updated>2011-01-29T22:05:17.680+01:00</updated><title type='text'>Primeros pasos con Moq</title><content type='html'>&lt;p&gt;Aprovecho que en los últimos días los compañeros &lt;a href="http://geeks.ms/members/lruiz/default.aspx" target="_blank"&gt;Luís Ruiz Pavón&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/elbruno/about.aspx" target="_blank"&gt;Bruno Capuano&lt;/a&gt; han escrito sendos artículos sobre Moles ( &lt;a href="http://geeks.ms/blogs/lruiz/archive/tags/Moles/default.aspx" target="_blank"&gt;aquí&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/elbruno/archive/tags/Moles/default.aspx" target="_blank"&gt;aquí&lt;/a&gt; ) para hacer una pequeña introducción a otro framework de mocking llamado &lt;a href="http://code.google.com/p/moq/" target="_blank"&gt;Moq&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Lo primero que tenemos que hacer es bajarnos la dll de su &lt;a href="http://code.google.com/p/moq/downloads/list" target="_blank"&gt;web&lt;/a&gt; . Una vez hecho esto ya podemos incluir la librería (Moq.dll ) en nuestro proyecto de test.&lt;/p&gt;  &lt;p&gt;El código que vamos a testear se compone de una clase llamada AssetManager que tiene una dependencia a IDAO, una interfície para definir la manera en que se persistirán los objetos, ya sea en una base de datos, en un fichero o en memoria. Es esta interfície la que &amp;quot;mockearemos&amp;quot;, evitando así tener que codificar una implementación para testear AssetManager.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_ZaNkQuiMjcA/TUSA-WaifsI/AAAAAAAACvI/cPMaUi_s6cQ/s1600-h/ClassDiagram1%5B2%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://lh5.ggpht.com/_ZaNkQuiMjcA/TUSBBqWmqWI/AAAAAAAACvM/cfpDCbDCBaI/ClassDiagram1_thumb.png?imgmax=800" width="244" height="137" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Lo primero que vamos a hacer es crear un stub para la función SaveAsset de IDAO. Para tener clara la diferencia entre un Mock y un Stub, consulta este artículo de &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting" target="_blank"&gt;Martin Fowler&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Veamos el código para testear esta función:&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000" size="2"&gt;&lt;font style="font-size: 9pt"&gt;[&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;TestMethod&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;]           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt; SaveAsset_returns_true()           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; mockDao = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;Mock&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;IDAO&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;gt;();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; assetManager = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;(mockDao.Object);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;#160;&amp;#160;&amp;#160; Asset&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; asset = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;Asset&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;mockDao.Setup(dao =&amp;gt; dao.SaveAsset(asset)).Returns(&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;true&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;#160;&amp;#160;&amp;#160; Assert&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;.AreEqual(&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;true&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;, assetManager.SaveAsset(asset));           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Como podemos ver estamos creando un stub de nuestra interfície IDAO indicando que cuando se llame a la función SaveAsset nos devuelva el valor true. Así, al invocar al método SaveAsset de la clase AssetManager, que a su vez llama al método SaveAsset de la interfície IDAO, nos devolverá true y el test pasará. Para comprobar que esto es cierto, basta con cambiar el valor de retorno de la función de IDAO y veremos que el test no pasa.&lt;/p&gt;  &lt;p&gt;En el ejemplo anterior, nada nos garantiza que realmente se haya llamado a la función de IDAO, ya que SaveAsset de AssetManager podria haber devuelto true directamente. Ahora vamos a ver como podemos &amp;quot;mockear&amp;quot; una función y verificar que realmente se llama:&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font face="Consolas"&gt;&lt;font color="#000000" size="2"&gt;&lt;font style="font-size: 9pt"&gt;[&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;TestMethod&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;]           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt; GetAssetByName()           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; mockDao = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;Mock&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;IDAO&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;gt;();           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; assetManager = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;(mockDao.Object);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;assetManager.GetAssetByName(&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#a31515"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;quot;MyFirstAsset&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;mockDao.Verify(dao =&amp;gt; dao.GetAssetByName(&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#a31515"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;quot;MyFirstAsset&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;));           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Como podemos ver claramente en el código, con la función Verify verificamos que se haya llamado a la función GetAssetByName de la interficie IDAO con el parámetro MyFirstAsset. Podemos comprobar que esto es cierto modificando el string &amp;quot;MyFirstAsset&amp;quot; de una de las dos llamadas por otro string. El resultado será que el test no pasará. Este tipo de cosas puede hacer que nuestro test sea demasiado frágil y, por lo tanto, difícil de mantener. Moq nos ofrece la classe It para lidiar con este tipo de problemas. Podriamos substituir el string &amp;quot;MyFirstAsset&amp;quot; por sentencias del tipo:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;It.IsAny&amp;lt;string&amp;gt;() -&amp;gt; pasa como parámetro cualquier string&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;It.Is&amp;lt;string&amp;gt;(s =&amp;gt; s.StartsWith(&amp;quot;My&amp;quot;)) -&amp;gt; pasa como parámetro un string que empieza por &amp;quot;My&amp;quot;&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;It.IsRegex(&amp;quot;\ba&amp;quot;) -&amp;gt; pasa como parámetro un string que empieza por la letra a&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Al igual que podemos comprobar que se ha llamado a una función, quizá también nos pueda interesar comprobar que se ha seteado una propiedad. Para hacerlo, nos apoyaremos en la función VerifySet del mock:&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;[&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;TestMethod&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;]           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;public&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;void&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt; Verify_ConnectionString_was_set()           &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;{           &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;var&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; mockDao = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;Mock&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;IDAO&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;gt;();&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;#160;&amp;#160;&amp;#160; AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; assetManager = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;new&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;AssetManager&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;(mockDao.Object);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p style="line-height: normal; margin-bottom: 0cm"&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;&amp;#160;&amp;#160;&amp;#160; mockDao.VerifySet(x =&amp;gt; x.ConnectionString = &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font style="font-size: 9pt"&gt;&lt;font color="#2b91af"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;It&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;.Is&amp;lt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#0000ff"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;string&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;gt;(s =&amp;gt; s.StartsWith(&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#a31515"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&amp;quot;Non&amp;quot;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;)));            &lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;font color="#000000"&gt;&lt;font face="Consolas"&gt;&lt;font size="2"&gt;&lt;font style="font-size: 9pt"&gt;}&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Con este código comprobaremos que se ha seteado la propiedad ConnectionString con un valor que empieza por &amp;quot;Non&amp;quot;.&lt;/p&gt;  &lt;p&gt;Y por hoy ya tenemos suficiente. Hemos visto que es muy fácil utilizar Moq y hacer los primeros pasos con él. En posteriores tutoriales veremos más características de este framework.&lt;/p&gt;  &lt;p&gt;Hasta la próxima!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-6382063630655674771?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/6382063630655674771/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=6382063630655674771' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6382063630655674771'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6382063630655674771'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/01/primeros-pasos-con-moq.html' title='Primeros pasos con Moq'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_ZaNkQuiMjcA/TUSBBqWmqWI/AAAAAAAACvM/cfpDCbDCBaI/s72-c/ClassDiagram1_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-7995809563640928937</id><published>2011-01-26T19:42:00.001+01:00</published><updated>2011-01-26T19:42:24.400+01:00</updated><title type='text'>La importancia de un buen Product Owner y un buen Product Backlog</title><content type='html'>&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_ZaNkQuiMjcA/TUBq_2UMXtI/AAAAAAAACus/86sjDCrHfyY/s1600-h/product-owner%5B2%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 10px 10px 10px 20px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="product-owner" border="0" alt="product-owner" align="right" src="http://lh6.ggpht.com/_ZaNkQuiMjcA/TUBrCoHTB6I/AAAAAAAACuw/whZC8lHDSzI/product-owner_thumb.png?imgmax=800" width="196" height="177" /&gt;&lt;/a&gt;Muchas de las implantaciones de Scrum ( u otras metodologías ágiles ) que he conocido estos años son implantaciones que podríamos llamar bottom-up, es decir que parten del equipo de desarrollo. Estos se dan cuenta que no pueden continuar con la organización que llevan ahora y deciden tomar cartas en el asunto y empezar a hacerlo por ellos mismos. Es lo que se denomina comúnmente agilismo de guerrilla.&lt;/p&gt;  &lt;p&gt;Aun siendo una muy buena opción para empezar ( yo empecé así ) a la larga se acaba quedando corta y es necesaria la implicación de la gerencia para llegar a algo más completo. Para mi los principales puntos débiles son:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Adolecen de un mentor experimentado: en la mayoría de los casos, el equipo se ha documentado sobre Scrum y empieza a probarlo.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Mala repartición de los roles: sobretodo si sólo está utilizando Scrum un equipo, hay gente que tiene dos roles: equipo y Scrum Master o equipo y Product Owner. La por situación es si hay alguien que tiene los tres roles, en lo que esto tiene muchos números de convertirse en un command and control encubierto.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Product Owner poco implicado: al ser un miembro del equipo le va a costar hacer de Product Owner. No va a tener relación directa con el cliente, no va a saber todo lo que se tiene que hacer a lo largo del tiempo o no le va a gustar definir bien las historias.&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Veamos este punto con un poco más de detalle. Todas las cosas en contra que he comentado no tienen porqué pasar... pero tienen muchos números de que pasen. A los desarrolladores en general no nos gusta demasiado hacer especificaciones, definiciones de acabado y cosas por el estilo. Por lo menos a mi no me entusiasma ni a ninguno de mis compañeros. Esto desemboca en que nuestro Product Backlog no sea lo que tendría que ser.&lt;/p&gt;  &lt;p&gt;Pero llega un día en que alguien con mucha más relación con el cliente y con visión del producto se instala en tu equipo. Y empieza a generar un Product Backlog con todas las historias que quiere que a corto/medio plazo se implementen, las prioriza, detalla más las más importantes, especifica las condiciones de aceptación de cada una de ellas. Este día será un día importante en tu historia dentro del proyecto. Los cambios más importante que se producirán en tu equipo para mi son:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;p&gt;Ánimo dentro del equipo: ver que la gerencia se preocupa por el proyecto y pone toda la carne en el asador para que tire adelante anima a la gente.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Mayor cuidado con la aplicación: todos somos profesionales y estamos comprometidos, pero no es lo mismo que cada quince días el equipo le haga a un Product Owner &amp;quot;externo&amp;quot; la demo del sprint que se la hagan entre ellos.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Mayor acierto con la implementación de las histórias: el equipo desarrollará lo que el Product Owner quiere, no lo que él cree que el Product Owner quiere.&lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;p&gt;Mayor visión del producto: el equipo sabe hacia donde tirará el proyecto y puede tomar decisiones en función de ello.&lt;/p&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Por lo tanto, si tienes ya un buen Product Owner en tu equipo, cuídalo y no lo dejes marchar, y sinó búscate uno en quanto puedas!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Nota 1:&lt;/strong&gt; este post está basado en hechos reales. Ningún Product Owner, Scrum Master o miembro del equipo ha sido maltratado en la realización del mismo.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;strong&gt;Nota 2:&lt;/strong&gt; este post está basado en mi experiencia. Si la tuya es diferente, no dejes de contarla en los comentarios!&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-7995809563640928937?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/7995809563640928937/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=7995809563640928937' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7995809563640928937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7995809563640928937'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/01/la-importancia-de-un-buen-product-owner.html' title='La importancia de un buen Product Owner y un buen Product Backlog'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_ZaNkQuiMjcA/TUBrCoHTB6I/AAAAAAAACuw/whZC8lHDSzI/s72-c/product-owner_thumb.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-505860916833093154</id><published>2011-01-25T11:44:00.001+01:00</published><updated>2011-01-25T11:44:36.723+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='libros'/><category scheme='http://www.blogger.com/atom/ns#' term='Robert C.Martin'/><category scheme='http://www.blogger.com/atom/ns#' term='Clean Code'/><title type='text'>He leído: Clean Code</title><content type='html'>&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_EX9ub8lGIsQ/TT6oTKo9L4I/AAAAAAAAAKA/rl8ovav5Ekc/s1600-h/cleancode-225x300%5B4%5D.jpg"&gt;&lt;img title="cleancode-225x300" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="244" alt="cleancode-225x300" src="http://lh5.ggpht.com/_EX9ub8lGIsQ/TT6oUYkpl4I/AAAAAAAAAKE/etAwJ2laUKk/cleancode-225x300_thumb%5B2%5D.jpg?imgmax=800" width="184" border="0" /&gt;&lt;/a&gt;Empiezo nuestra aventura en &lt;a href="http://geeks.ms/" target="_blank"&gt;geeks&lt;/a&gt; con la review de un libro que tengo pendiente desde hace algún tiempo, y que no es otro que &lt;a href="http://www.amazon.com/s/ref=nb_sb_noss/178-2509850-3274965?url=search-alias%3Daps&amp;amp;field-keywords=Clean+Code&amp;amp;x=0&amp;amp;y=0" target="_blank"&gt;Clean Code&lt;/a&gt;, de Robert.C. Martin.&lt;/p&gt;  &lt;p&gt;Lo primero que tengo que decir de Clean Code, es que es un “Must Have” de cualquier desarrollador que se precie de serlo! Es un de esos libros que debería ser obligatorio que te hagan leer en la facultad, y no sólo leer, sino casi recitar de memoria! &lt;/p&gt;  &lt;p&gt;¿Y porqué hago tales afirmaciones? Pues porque Clean Code es un libro genial, bien explicado, con ejemplos claros y concisos, va al grano, y además, es entretenido de leer (bueno, algunos capítulos son un poco pesados, pero en general es bastante ameno)&lt;/p&gt;  &lt;p&gt;Si, si,¿pero de que va el libro? os estaréis preguntando muchos... Pues el libro trata simplemente de cómo escribir código limpio (el propio título lo indica). Algo que parece una chorrada pero que es sumamente difícil. En el libro, Robert no das las claves para&amp;#160; ser capaces de escribir código lo más legible posible, algo que además de facilitar la lectura (según él. el 90% del tiempo que pasamos programando, estamos leyendo código nuestro o de otras personas) va a afectar de manera directamente proporcional al diseño, la reutilización o la escalabilidad de nuestro código. &lt;/p&gt;  &lt;p&gt;Cómo ya he comentado antes, el libro es muy conciso, presentando en cada capítulo soluciones a diferentes errores comunes que la mayoría de gente comete o ha cometido en diferentes ámbitos del código: Comentarios, Clases, Funciones, Tratamiento de errores, tests unitarios… todo ello aderezado con múltiple ejemplos sacados de proyectos reales. Esta estructura de los capítulos permite tanto una lectura secuencial cómo a modo de libro de consulta. Y además, y vuelvo a repetirme, el libro es muy ameno. &lt;/p&gt;  &lt;p&gt;En definitiva, un gran libro que recomiendo a todos los desarrolladores (presentes, pasados y futuros) ya que puede ser una muy buena guía para intentar mejorar en nuestro trabajo.&lt;/p&gt;  &lt;p&gt;Un saludo!!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-505860916833093154?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/505860916833093154/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=505860916833093154' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/505860916833093154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/505860916833093154'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/01/he-leido-clean-code.html' title='He leído: Clean Code'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_EX9ub8lGIsQ/TT6oUYkpl4I/AAAAAAAAAKE/etAwJ2laUKk/s72-c/cleancode-225x300_thumb%5B2%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-5853911368379643016</id><published>2011-01-24T22:17:00.001+01:00</published><updated>2011-01-24T22:19:46.765+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comunidad'/><category scheme='http://www.blogger.com/atom/ns#' term='corral'/><category scheme='http://www.blogger.com/atom/ns#' term='geeksms'/><title type='text'>Ahora también en geeks!</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: 'Droid Sans', arial, sans-serif; font-size: 13px; border-collapse: collapse; color: rgb(32, 32, 32); "&gt;&lt;div&gt;Pues si, la popular comunidad de blogs sobre desarrollo y tecnologías Micrsosoft, &lt;a href="http://geeks.ms/"&gt;geeks.ms&lt;/a&gt; nos ha abierto las puertas para que participemos en ella desde nuestro blog. Así que a partir de ahora podréis encontrar nuestros posts tanto aquí cómo en &lt;a href="http://geeks.ms/blogs/devnettips/" target="_blank" style="color: rgb(103, 117, 58); "&gt;http://geeks.ms/blogs/&lt;wbr&gt;devnettips/&lt;/a&gt;.  Desde aquí queremos dar las gracias a Rodrigo Corral por permitirnos participar en la comunidad, a la cual intentaremos aportar material interesante y de calidad!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo desde devnettips!&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-5853911368379643016?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/5853911368379643016/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=5853911368379643016' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5853911368379643016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5853911368379643016'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2011/01/ahora-tambien-en-geeks.html' title='Ahora también en geeks!'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-921423326124040536</id><published>2010-12-17T14:30:00.001+01:00</published><updated>2010-12-17T14:31:31.987+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='testeo unitario'/><category scheme='http://www.blogger.com/atom/ns#' term='CodeRetreat'/><category scheme='http://www.blogger.com/atom/ns#' term='evento'/><category scheme='http://www.blogger.com/atom/ns#' term='desarrollo'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='Zaragoza'/><category scheme='http://www.blogger.com/atom/ns#' term='kata'/><title type='text'>CodeRetreat de Zaragoza... allí estuvimos!</title><content type='html'>Después de un más que interesante &lt;a href="http://devnettips.blogspot.com/2010/12/primer-coding-dojo-en-barcelona.html"&gt;Coding Dojo en Barcelona&lt;/a&gt; el pasado viernes, unos cuantos valientes con ganas de más nos íbamos al día siguiente al &lt;a href="http://www.coderetreat.com/"&gt;CodeRetreat&lt;/a&gt; de Zaragoza! Para el que no lo sepa, un &lt;a href="http://www.coderetreat.com/"&gt;CodeRetreat&lt;/a&gt; consiste, simplificando mucho, en juntarse un grupo de desarrolladores un día entero para programar  (da igual el lenguaje, la experiencia... sólo importan las ganas) , en una serie de iteraciones de 45 minutos, una y otra vez el mismo ejercicio (normalmente el &lt;a href="http://en.wikipedia.org/wiki/Conway's_Game_of_Life"&gt;Juego de la Vida de Conwa&lt;/a&gt;y), por parejas, usando &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; e introduciendo una nueva restricción en cada una de las iteraciones. Además, por si no fuera suficiente, cada iteración se realiza con una pareja diferente! Viva la promiscuidad!! La verdad es que suena muy freak, y efectivamente lo es, sobretodo si se realiza a 300km de tu ciudad y tienes que levantarte a las 5:30 de un sábado para asistir! pero aparte de eso, es una manera excelente de aprender y mejorar, de conocer gente, de hacer networking y también de divertirse por supuesto! &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Así que con muchas ganas y mucho sueño &lt;a href="http://twitter.com/Juanan_Sosa"&gt;yo&lt;/a&gt; y &lt;a href="http://twitter.com/vgaltes"&gt;Vicenç&lt;/a&gt; cogíamos al AVE las 7 de la mañana dirección  Zaragoza. El resto de gente de Barcelona , &lt;a href="http://twitter.com/#!/jgomezz"&gt;Javier &lt;/a&gt;&lt;a href="http://twitter.com/#!/jgomezz"&gt;Gómez&lt;/a&gt; y su mujer (ingeniera informática que hace 4 años que no programa, y a la que según Javier había que devolver la sonrisa) iban en el siguiente tren!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con el tiempo justo  y gracias a que nos encontramos a &lt;a href="http://twitter.com/amaliahern"&gt;Amalia&lt;/a&gt; (con quien habíamos colaborado en la organización del&lt;a href="http://www.aos2010.agile-spain.com/"&gt;AOS&lt;/a&gt;&lt;a href="http://www.aos2010.agile-spain.com/"&gt;2010&lt;/a&gt;) y a Jorge(alias &lt;a href="http://twitter.com/semurat"&gt;Semurat&lt;/a&gt;) conseguimos llegar al peculiar "Water Pavillion", el lugar donde se iba a celebrar el evento.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/TQtiH7Ye1DI/AAAAAAAAAJc/39jHGUF6n2M/s1600/digital-water-pavilion-imagen1.jpg"&gt;&lt;img src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/TQtiH7Ye1DI/AAAAAAAAAJc/39jHGUF6n2M/s400/digital-water-pavilion-imagen1.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5551638854003250226" style="cursor: pointer; width: 240px; height: 320px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Digital Water Pavillion&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Más de 20 personas estábamos inscritas, y ya mayoría de gente ya había llegado y tenía los portátiles preparados cuanto entramos nosotros! Aparte de mucha gente de Zaragoza y los que íbamos de Barcelona había gente de diferentes lugares de la geografía Española, cómo Madrid, Valladolid, Valencia.. Únicamente tuve tiempo para saludar brevemente a &lt;a href="http://agilismo.es/index.php?option=com_content&amp;amp;view=category&amp;amp;layout=blog&amp;amp;id=36&amp;amp;Itemid=68"&gt;Xavi Gost&lt;/a&gt;, que iba a ser el facilitador del evento, a &lt;a href="http://twitter.com/tolivern"&gt;Teresa &lt;/a&gt;&lt;a href="http://twitter.com/tolivern"&gt;Oliver&lt;/a&gt; (a quién también conocía de la organización del AOS2010 y una de las culpables de la realización del CodeRetreat) y a alguna persona más que conocía de haber asistido al mismo evento justo antes de que llegara los dos catalanes que faltaban y nos pusiéramos manos a la obra.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Después de una breve ronda de presentaciones, donde de se vio que había dos grandes grupos en lo que a lenguajes de programación se refiere (Java y .Net) Xavi nos explicó la dinámica del evento, básicamente la que he explicado arriba, nos explico las 4 reglas del juego de conway que había que implementar y nos dijo que empezáramos!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_EX9ub8lGIsQ/TQtjlZDDIyI/AAAAAAAAAJk/TfJuUG9_3eU/s1600/IMAG0101.jpg"&gt;&lt;img src="http://2.bp.blogspot.com/_EX9ub8lGIsQ/TQtjlZDDIyI/AAAAAAAAAJk/TfJuUG9_3eU/s400/IMAG0101.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5551640459694252834" style="cursor: pointer; width: 400px; height: 240px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Antes de empezar&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;La primera iteración la hice con Vicenç, y después de los primeros 45 minutos, nos pensábamos que teníamos un código bastante bueno y bonito, ingenuos... Al acabar Xavi nos reunió y fue preguntó¡ando a la gente por sus impresiones, por cómo habían enfocado el problema, etc... Hubo un poco de todo,desde gente que  había empezado a desarrollar en universo entero donde situar a las células del juego hasta gente que prácticamente no había hecho una sola línea de código. Hay que tener cuenta que mucha gente no había programado con TDD en su vida. A partir de ese momento y durante las siguientes iteraciones, Xavi nos iba poniendo nuevas restricciones a la hora de implementar los tests, por ejemplo:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;No instanciar nada más allá de lo estrictamente necesario&lt;/li&gt;&lt;li&gt;Desarrollar el test dentro del propio test &lt;/li&gt;&lt;li&gt;Darle semántica al código (cómo ejemplo, la mayoría de le gente utilizaba una variable boleana para indicar si una célula estaba viva o no, y Xavi nos dijo que una persona cuando muere no está a "False"...)&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Al final hicimos unas 5 iteraciones, en las que tuve la oportunidad de tocar 3 lenguajes de programación (C#, Java e incluso Python!!) y de desarrollar con personas diferentes que tienen diferentes puntos de vista y diferentes maneras de buscar la solución, lo cual creo que es muy enriquecedor e interesante.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Después de la 5ª iteración y de una breve videoconferencia con &lt;a href="http://ecomba.org/"&gt;Enrique Comba&lt;/a&gt; desde Londres (Enrique es uno de los firmantes originales del &lt;a href="http://manifesto.softwarecraftsmanship.org/"&gt;manifiesto por la artesanía del software&lt;/a&gt;, además de ser un asiduo facilitador de CodeRetreats) la gente estaba bastante cansada, y se decidió acabar con un pequeño reto a Xavi Gost: Seleccionamos una Kata que él no conocía y tenía que implementar la solución utilizando TDD,  sin leerle el enunciado, únicamente a base de tests que Amalia le iba escribiendo! La kata elegida fue la de &lt;a href="http://tiopetrus.blogia.com/2005/042501-multiplicacion-a-la-rusa-1-.php"&gt;La Multiplicación a la Rusa&lt;/a&gt;, muy muy complicada para realizar con TDD puro y duro, así que hubo que darle alguna pista adicional a Xavi para que pudiera deducir la implementación!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_EX9ub8lGIsQ/TQtjlhvBsqI/AAAAAAAAAJs/LRfEr4VtsfI/s1600/IMAG0102.jpg"&gt;&lt;img src="http://1.bp.blogspot.com/_EX9ub8lGIsQ/TQtjlhvBsqI/AAAAAAAAAJs/LRfEr4VtsfI/s400/IMAG0102.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5551640462026191522" style="cursor: pointer; width: 400px; height: 240px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Xavi Gost enfrentándose a "La multiplicación a la Rusa"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Con esto, y unas cervezas cortesía de los chicos de &lt;a href="http://www.masterbranch.com/"&gt;M&lt;/a&gt;&lt;a href="http://www.masterbranch.com/"&gt;asterbranch&lt;/a&gt; finalizaba "oficialmente" el CodeRetreat!! Y digo "oficialmente" porque el evento se alargaba para que los querían (o podían) con unas cervezas, cena y lo que surgiera! Lástima que nosotros nos tuvimos que volver esa misma noche!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cómo conclusión, aparte de las ganas y la motivación de la gente, el buen ambiente y el poder conocer a personas muy interesante (y volver a ver a las que ya conocía) , me quedo con la idea de que es necesario buscar la excelencia en nuestra profesión (cómo en toda profesión de hecho) y que esa búsqueda debe empezar por elevar el grado de auto-exigencia a nosotros mismos, y buscar siempre y de manera continua el ir mejorando poco a poco en todo aquello que hagamos (ya sea código o cualquier otra actividad). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Por suerte parece que empieza a haber cada vez más gente que comparte esa misma idea cómo se puede ver con los diferentes eventos que están surgiendo últimamente en diferentes lugares  y de las diferentes comunidades (muchas de ellas ágiles) repartidas por el estado.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para finalizar: muchas gracias a los organizadores, que hicieron posible este evento, a Xavi Gost por su facilitación y a todos los que asistieron por darme la posibilidad de poder aprender de ellos (especialmente a la gente con la que pude sentarme a desarrollar) y de conocerlos!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;PD: &lt;a href="http://twitter.com/dani_latorre"&gt;Dani Latorre&lt;/a&gt; ha recopilado una &lt;a href="http://twitter.com/dani_latorre/coderetreatzgz"&gt;lista&lt;/a&gt; con muchas de las cuentas de twitter de los asistentes! Por si os falta alguna!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-921423326124040536?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/921423326124040536/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=921423326124040536' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/921423326124040536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/921423326124040536'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/12/coderetreat-de-zaragoza-alli-estuvimos.html' title='CodeRetreat de Zaragoza... allí estuvimos!'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_EX9ub8lGIsQ/TQtiH7Ye1DI/AAAAAAAAAJc/39jHGUF6n2M/s72-c/digital-water-pavilion-imagen1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-6403692435566200814</id><published>2010-12-14T21:03:00.001+01:00</published><updated>2010-12-15T17:11:46.336+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='coding dojo'/><category scheme='http://www.blogger.com/atom/ns#' term='barcelona'/><title type='text'>Primer Coding Dojo en Barcelona</title><content type='html'>Después del fantástico&amp;nbsp;&lt;a href="http://www.aos2010.agile-spain.com/"&gt;AOS 2010&lt;/a&gt;&amp;nbsp;celebrado en Barcelona había una idea flotando en el ambiente: hay que montar más cosas!! Así que, ni cortos ni perezosos, el grupo local de &lt;a href="http://agile-spain.wikidot.com/quedadas-barcelona"&gt;Barcelona&amp;nbsp;&lt;/a&gt;organizamos nuestro primer&amp;nbsp;&lt;a href="http://codingdojo.org/cgi-bin/wiki.pl?WhatIsCodingDojo"&gt;Coding Dojo&lt;/a&gt;. El evento lo realizamos en las fantásticas oficinas de&amp;nbsp;&lt;a href="http://www.runroom.com/"&gt;Runroom&lt;/a&gt;&amp;nbsp;con&amp;nbsp;&lt;a href="http://www.carlosiglesias.info/"&gt;Carlos&lt;/a&gt;&amp;nbsp;como anfitrión.&lt;br /&gt;&lt;br /&gt;La convocatoria fue un éxito y enseguida se apuntó mucha de gente, aunque el echo diferencial fue la promesa de Gin Tonics subvencionados por&amp;nbsp;&lt;a href="http://www.ubedagintapas.com/"&gt;Úbeda Gin &amp;amp; Tapas&lt;/a&gt;. Todo un detallazo!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5044/5252261161_a42047769a.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://farm6.static.flickr.com/5044/5252261161_a42047769a.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;La kata que seleccionamos para hacer el Coding Dojo fue la de&amp;nbsp;&lt;a href="http://codingkata.org/katas/unit/caesar-lottery"&gt;Cesar juega a la loteria&lt;/a&gt;. Es una kata interesante que se puede resolver de varias maneras y que da bastante juego. Entre los 18 participantes se realizó la kata en .Net, en Java y en JavaScript. Eso si, todos con&amp;nbsp;&lt;a href="http://www.carlosble.com/2010/05/virtual-altnet-sobre-test-driven-development/"&gt;TDD&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5283/5252864032_a9802a471d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://farm6.static.flickr.com/5283/5252864032_a9802a471d.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;No se exactamente por qué, pero me parece que en Barcelona hay más programador en .Net y, en cambio, en otras comunidades hay más programador en Groovy, Rails y compañía. Por lo menos en las comunidades ágiles. Curioso.&lt;br /&gt;&lt;br /&gt;Hicimos dos iteraciones de 40 minutos. Después de la primera iteración tocaba cambio de pareja, pero quizá por ser la primera la gente no se animó y todos continuamos con nuestra primera pareja, y con nuestro segundo Gin Tonic, claro :D.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5161/5252266247_37b8445726.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://farm6.static.flickr.com/5161/5252266247_37b8445726.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Al final de ambas iteraciones, hicimos un poco de retrospectiva de la kata. Cada uno comentó como se había encontrado haciendo &lt;a href="http://es.wikipedia.org/wiki/Tdd"&gt;TDD&lt;/a&gt;, como había encarado la kata, etc.Surgieron opiniones para todos los gustos: gente que no se acababa de encontrar cómoda con &lt;a href="http://www.agiledata.org/essays/tdd.html"&gt;TDD &lt;/a&gt;( para muchos era su primer vez ), gente que se encontraba muy cómoda y la kata le iba saliendo muy bien, gente que estaba refactorizando tranquilamente por el echo de tener tests por debajo, etc.&lt;br /&gt;&lt;br /&gt;Y para acabar vimos todos el vídeo del "&lt;a href="http://www.youtube.com/watch?v=l1wKO3rID9g"&gt;The downfall of Agile Hitler&lt;/a&gt;" para echarnos unas risas antes de continuar con las cervezas ágiles mientras cuatro afortunados nos preparábamos para ir a la mañana siguiente al&amp;nbsp;&lt;a href="http://www.coderetreat.com/"&gt;coderetreat&lt;/a&gt;&amp;nbsp;de&amp;nbsp;&lt;a href="http://agilismo.es/index.php?option=com_content&amp;amp;view=article&amp;amp;id=104:coderetreat-en-zaragoza&amp;amp;catid=35:evento"&gt;Zaragoza&lt;/a&gt;. Pero eso ya es otro post...&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://farm6.static.flickr.com/5045/5252275501_93593678a5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://farm6.static.flickr.com/5045/5252275501_93593678a5.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-6403692435566200814?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/6403692435566200814/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=6403692435566200814' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6403692435566200814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6403692435566200814'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/12/primer-coding-dojo-en-barcelona.html' title='Primer Coding Dojo en Barcelona'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5044/5252261161_a42047769a_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-5252211048491376949</id><published>2010-11-23T09:26:00.001+01:00</published><updated>2010-11-23T09:26:09.541+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='diseño'/><category scheme='http://www.blogger.com/atom/ns#' term='refactorizar'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='open space'/><category scheme='http://www.blogger.com/atom/ns#' term='bdd'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Diseño Ágil</title><content type='html'>El presente post está basado en las conclusiones e ideas que surgieron en la sesión del mismo nombre (Diseño Ágil) en el reciente &lt;a href="http://www.aos2010.agile-spain.com/"&gt;Agile Open Spain 2010&lt;/a&gt; de Barcelona. La sesión, egoístamente propuesta por mi (:P), tenía cómo objetivo el determinar aquellas técnicas o maneras de diseño que mejor pueden funcionar en equipos que trabajan de manera ágil, ya sea con Scrum o con cualquier otra metodología, aunque al final el tema se desvió un poco y se acabó hablando de algunas otras cosas, aunque todas ellas muy interesantes!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se empezó hablando de la necesidad de eliminar los&lt;a href="http://en.wikipedia.org/wiki/Big_Design_Up_Front"&gt; grandes diseños y arquitecturas iniciales&lt;/a&gt; para poder tener una mejor respuesta ante cambios en los requisitos o las necesidades del cliente, y para evitar el sobrediseño, algo que suele suceder muy a menudo. En su lugar se apuesta mas por un micro diseño o arquitectura inicial a alto nivel que permita a las personas que van a trabajar en el proyecto hacerse una idea general del mismo: los diferentes subsistemas que intervienen, como se relacionan entre ellos, etc. pero sin entrar en demasiados detalles. Este micro-diseño se realizaría en el Sprint 0, antes de empezar con el desarrollo de las diferentes funcionalidades del sistema.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A partir de aquí se empezaron a enumerar las diferentes técnicas que utiliza la gente desde el punto de vista del desarrollo para garantizar un buen diseño, por ejemplo:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Diseño emergente con &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; y/o &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development"&gt;BDD&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;Tests unitarios&lt;/a&gt; para garantizar que no se rompe código anterior&lt;/li&gt;&lt;li&gt;Utilizar &lt;a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)"&gt;principios S.O.L.I.D&lt;/a&gt; y desarrollar utilizando interfaces (lo que a su vez facilita el testing)&lt;/li&gt;&lt;li&gt;Refactorizar, refactorizar, refactorizar!!&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)"&gt;Patrones de diseño&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;La conversación, fue derivando entonces hacia la documentación, posicionándose la mayoría de la gente en que la mejor documentación es el propio código (o incluso los tests unitarios), y que documentar exhaustivamente los diseños puede tener un coste elevado, aunque también se aceptó que en ocasiones puede ser interesante que algunos diseños se documenten (por ejemplo con UML) de manera que todo el mundo  pueda acceder a ellos, eso si, siempre y cuando esta documentación sea consistente con el código y no esté desincronizada. Una manera de conseguir esto, era tener una tarea en cada Product BackIog Item (o historia de usuario) del Backlog dedicada a ello.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;El siguiente foco importante de discusión y comentarios, fue el decidir el momento adecuado de realizar el diseño y análisis técnico de cada historia de usuario. El consenso fue que el diseño de cada historia se debía realizar durante el proceso de estimación y división en tareas de esa historia, en la reunión de planificación de Sprint, momento en el cual el Product Owner está disponible para explicar la historia y aclarar cualquier posible duda que pueda surgir.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Se habló también de como integrar a los desarrolladores juniors o la gente nueva en el proceso de diseño, de manera que sus diseños no afecten o comprometan la calidad del trabajo de todo el equipo. Casi todo el mundo nombró Pair-Programming como la solución a este posible problema, y alguien habló que en su empresa utilizaban un sistema de mentoring, en el cual un desarrollador senior se "hacía cargo" de un junior, de manera que le supervisaba el trabajo, desarrollaban juntos, etc. durante un tiempo y éste último no empezaba a trabajar para un cliente hasta que llevaba un tiempo y ya sabía cómo debía de programar (tanto a nivel de calidad cómo de estilo, estándares, etc)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Hacía el final se empezó a hablar de que hacer con los requisitos no funcionales: seguridad, rendimiento, etc. Aquí hubo un poco más de discordia, ya que había gente que abogaba por intentar optimizar desde el principio y otras personas que preferían desarrollar sin tener muy en cuenta estos parámetros y después optimizar en función de las necesidades del cliente. Aunque casi todo el mundo opinaba que ahora la tendencia es desarrollar pensando mas en la mantenibilidad y en la escalabilidad que no en la optimización del detalle.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cómo último punto, se trataron las revisiones de código., que todo el mundo consideró cómo necesarias. Enumero algunos de los métodos expuestos (además de Pair-Programming cómo revisión continua):&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;En una empresa utilizan una herramienta online (un plugin de JIRA creo) donde se registran posibles mejoras en un código que hace un "moderador". Posteriormente el moderador y la persona que ha realizado el código lo miran juntos y se buscan posibles soluciones y mejoras.&lt;/li&gt;&lt;li&gt;En otros lugares realizan sesiones de revisión, donde se junta todo el equipo y se realiza la revisión de un código.&lt;/li&gt;&lt;li&gt;En otra empresa  de manera periódica hacen una reducción de código de cada proyecto, de manera que se intenta una especie de gran refactorización con todas las modificaciones hechas desde la última vez.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;Seguro que salieron muchas mas ideas interesantes que me olvido o que no apunté en su momento, pero fue una sesión muy fructífera y muy entretenida debido al alto nivel de los asistentes y alto porcentaje de gente que participó con opiniones y ideas en la charla!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Espero que alguna de estas técnicas puedan servir de ayuda a equipos que estén intentado trabajar con metodologías ágiles, y si alguien tiene alguna idea o sugerencia sobre el tema, adelante!! Explicadnos cómo realizáis diseño vuestros diseños ágiles!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo!!&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-5252211048491376949?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/5252211048491376949/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=5252211048491376949' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5252211048491376949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5252211048491376949'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/11/diseno-agil.html' title='Diseño Ágil'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-3986541232067965835</id><published>2010-11-16T23:07:00.001+01:00</published><updated>2010-11-16T23:09:46.655+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jeff sutherland'/><category scheme='http://www.blogger.com/atom/ns#' term='aos2010'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum master'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='equipo'/><title type='text'>ScrumMaster: ¿Parte o no del equipo?</title><content type='html'>Me ha parecido, en el último Agile Open de Barcelona escuchar en varias ocasiones frases similares a esta. En algunas sesiones, en los pasillos e incluso en alguna de las cenas he oído comentarios y opiniones dándole vueltas a esa idea. De entrada,creo que sería interesante re-formular la cuestión, ya que creo que lo que se intenta debatir no es si el ScrumMaster debe estar o no en el equipo (por supuesto!!) sino si además de sus funciones cómo ScrumMaster, debe también tener otras funciones dentro del equipo (desarrollo, testing, usabilidad...). La pregunta que yo lanzo es ¿ScrumMaster full-time o part-time?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Antes de dar mi opinión, veamos lo que dice el propio &lt;a href="http://jeffsutherland.com/ScrumPapers.pdf"&gt;Jeff Sutherland&lt;/a&gt; sobre el rol en cuestión: &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;"The &lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;ScrumMaster&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; &lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;helps the product group learn and apply Scrum to achieve business value. The ScrumMaster does whatever is in their power to help the team be successful. The ScrumMaster is &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;not &lt;/span&gt;&lt;/i&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;the manager of the team or a project manager; instead, the ScrumMaster serves the team, protects them from outside interference, and educates and guides the Product Owner and the team in the skillful use of Scrum. The ScrumMaster makes sure everyone on the &lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; "&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;team (including the Product Owner, and those in management) understands and follows the practices of Scrum, and they help lead the organization through the often difficult change required to achieve success with agile development. Since Scrum makes visible many impediments and threats to the team’s and Product Owner’s effectiveness, it is important to have an engaged ScrumMaster working energetically to help resolve those issues, or the team or Product Owner will find it difficult to succeed. &lt;/span&gt;&lt;/i&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Scrum teams should have a dedicated full-time ScrumMaster, although a smaller team might have a team member play this role (carrying a lighter load of regular work when they do so)&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;. Great ScrumMasters can come from any background or discipline: Engineering, Design, Testing, Product Management, Project Management, or Quality Management."&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Leyendo el párrafo anterior, la respuesta a la pregunta sería: Depende!! Si puedes permitírtelo, ten un ScrumMaster full-time, sino puedes porque tú equipo o organización es demasiado pequeño, usa a un miembro del equipo a modo part-time (aunque eso sí, aligerando su carga de trabajo en otras responsabilidades). Ahora bien, ¿porqué sería interesante tener un ScrumMaster full-time? &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;La responsabilidad del ScrumMaster es, entre otras cosas, encargarse del proceso (sí, ya se lo que pone en el Manifiesto Ágil, pero no se me ocurre otra manera de expresarlo!!) El equipo debe "hacer" algo (un producto, un proyecto...) utilizando eso proceso y el ScrumMaster debe encargarse de observar cómo lo hacen, ver como el equipo avanza, e intentar ayudarles a mejorar. Sería algo así cómo si el equipo fuera dando pequeños saltos hacia un punto mientras el ScrumMaster observa cada uno de esos saltos e intenta que el equipo aprenda a saltar mejor cada vez. Pero para que esta observación sea efectiva, es necesaria cierta neutralidad.Se debe poder mirar el proceso con un poco de perspectiva para poder obtener información objetiva sobre el mismo. Si el ScrumMaster es parte del equipo, puede perder la perspectiva, su visión puede quedar sesgada ya que su foco se está centrando también en producir (multitasking?)  y la mejora continua necesaria en todo equipo Scrum es probable que sea menor.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Esto seria lo ideal, pero, cómo hemos leído en la definición de Jeff Sutherland, es posible que en equipos o organizaciones demasiado pequeñas un ScrumMaster no tenga suficiente volumen de trabajo para ejercer ese trabajo full-time. Además, muchas organizaciones dedicadas al desarrollo de software seguramente no estén aún preparadas para tener a una persona "que no produce" (nótese la ironía) a tiempo completo.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;¿Entonces que hacemos? Scrum es una metodología de inspección y adaptación. Empecemos con lo que tenemos, y mantengamos la visión ideal del ScrumMaster full-time en el horizonte y, aunque es posible que nunca se llegue a completar, intentemos trabajar en esa dirección. ¿Cómo? Que varios equipos compartan SM, haciendo que el ScrumMaster sea una persona de otro equipo... o con otras opciones mucho mas creativas que las que se me ocurren ahora mismo a mi.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Como nota final, apuntar que aún más importante que decidir si el ScrumMaster es full-time o no, es escoger al candidato correcto. ¿Y quien es el candidato correcto? Pues sencillamente aquel que tiene los skills necesarios! Os remito a un interesante artículo de Xavier Albaladejo sobre el tema: &lt;a href="http://www.proyectosagiles.org/buen-gestor-equipo-agil-scrummaster"&gt;"El buen gestor de un equipo ágil"&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;¿Que opináis? ¿Debería ser el ScrumMaster un rol full-time?¿O mejor un miembro del equipo?¿Puede llegar a trabajar sin ScrumMaster un equipo?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Espero vuestras opiniones! Un saludo!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-3986541232067965835?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/3986541232067965835/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=3986541232067965835' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3986541232067965835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3986541232067965835'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/11/scrummaster-parte-o-no-del-equipo.html' title='ScrumMaster: ¿Parte o no del equipo?'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-8122590443474642273</id><published>2010-11-14T22:00:00.001+01:00</published><updated>2010-11-14T22:04:51.460+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='aos2010'/><category scheme='http://www.blogger.com/atom/ns#' term='agilidad'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='open space'/><title type='text'>Se acabó el AOS 2010!</title><content type='html'>Ha finalizado el &lt;a href="http://www.aos2010.agile-spain.com/"&gt;Agile Open Spain 2010&lt;/a&gt;. Ha sido mi primera asistencia a un evento en formato &lt;a href="http://en.wikipedia.org/wiki/Open-space_meeting"&gt;Open Space&lt;/a&gt; y las sensaciones han sido inmejorables. Mas allá de la calidad de las sesiones a las que he asistido (que difícil ha sido elegir entre las numerosas propuestas de los asistentes), con lo que me quedo es con las ganas y la energía que que han mostrado todos los asistentes que han hecho el esfuerzo de acercarse a Barcelona desde diferentes lugares de España, Europa e incluso algunos del otro lado del charco,  para compartir con todos sus opiniones y experiencias en esto que llamamos Agilismo. A lo largo de los casi dos días del evento, he tenido el placer de escuchar, charlar y discutir ideas y opiniones con mucha gente, algunas con verdaderos expertos en metodologías ágiles y otras con gente que se acercaban por primera vez a ellas, pero todas han sido igual de enriquecedoras.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sesiones técnicas, sesiones sobre gestión de proyectos (o Project Support cómo prefiere llamarlo &lt;a href="http://www.cyment.com/"&gt;Alan Cyment&lt;/a&gt;...) e incluso sesiones que podríamos considerar algo así cómo teórico-filosóficas... :P de todas ellas me llevo cosas para reflexionar e intentar mejorar tanto a nivel profesional cómo personal. Más adelante intentaré concretar alguna de estas ideas en siguientes posts.&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;Espero que este evento sea un punto y seguido que ayude a la comunidad Agil Española a seguir creciendo y consolidándose, utilizando para ello, quizás, algunos de las propuestas surgidas en la Retrospectiva del evento (facilitada de manera magistral por &lt;a href="http://arielber.com/"&gt;Ariel Ber&lt;/a&gt; a quién desde aquí doy las gracias por su colaboración y ayuda durante todo el evento), cómo por ejemplo la realización de eventos Open Spaces a escala local, la realización de eventos temáticos o sobretodo la propuesta estrella de la noche: fomentar el agilismo entre las mujeres!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Cómo punto final, dar las gracias a todos los que han hecho posible este evento: los patrocinadores del evento (en especial al patrocinador oro &lt;a href="http://www.plainconcepts.com/"&gt;Plain Concepts&lt;/a&gt;), a la gente de la organización, a la&lt;a href="http://www.agile-spain.com/"&gt; asociación agile-spain&lt;/a&gt;  y sobre todo, y aquí me repito, a la gente que ha hecho el esfuerzo de acercarse al evento, ya que sin la gente no hubiera sido posible realizarlo!&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Os dejo una foto de la configuración de la agenda, totalmente autoogenerada entre todos los que asistimos al evento!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/TOBJYrUKqbI/AAAAAAAAAJU/X-9YkVmgf8g/s1600/IMAG0068.jpg"&gt;&lt;img src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/TOBJYrUKqbI/AAAAAAAAAJU/X-9YkVmgf8g/s400/IMAG0068.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5539508229958707634" style="cursor: pointer; width: 400px; height: 240px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Un saludo, y espero volver a coincidir con muchos de los que habéis estado en el AOS (no pongo nombres porque seguro que me dejo a gente) y sobretodo espero ver a mucha gente nueva en próximos eventos. Para empezar en el &lt;a href="http://www.xp2011.org/"&gt;xp2011&lt;/a&gt; en Madrid!!&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-8122590443474642273?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/8122590443474642273/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=8122590443474642273' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8122590443474642273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8122590443474642273'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/11/se-acabo-el-aos-2010.html' title='Se acabó el AOS 2010!'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_EX9ub8lGIsQ/TOBJYrUKqbI/AAAAAAAAAJU/X-9YkVmgf8g/s72-c/IMAG0068.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-4978736264855900882</id><published>2010-11-01T13:28:00.000+01:00</published><updated>2010-11-01T13:28:01.706+01:00</updated><title type='text'>VAN sobre integración contínua</title><content type='html'>Muy buenas a todos,&lt;br /&gt;&lt;br /&gt;el pasado viernes tube el placer de participar en la VAN sobre integración contínua que organizó &lt;a href="http://altnet-hispano.pbworks.com/"&gt;Altnet hispano&lt;/a&gt;. La VAN estubo muy interesante, tanto por la explicación general como por las demostraciones de las diferentes herramientas que se hicieron.&lt;br /&gt;&lt;br /&gt;Aquí os dejo el video de la VAN.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object class="embeddedObject" data="http://content.screencast.com/users/AltNetHispano/folders/VAN/media/fa318142-7c0d-4b7f-b1a8-685a152be582/flvplayer.swf" height="300" id="scPlayer" type="application/x-shockwave-flash" width="400"&gt;  &lt;param name="movie" value="http://content.screencast.com/users/AltNetHispano/folders/VAN/media/fa318142-7c0d-4b7f-b1a8-685a152be582/flvplayer.swf" /&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;param name="flashVars" value="thumb=http://content.screencast.com/users/AltNetHispano/folders/VAN/media/fa318142-7c0d-4b7f-b1a8-685a152be582/FirstFrame.jpg&amp;containerwidth=600&amp;containerheight=393&amp;content=http://content.screencast.com/users/AltNetHispano/folders/VAN/media/fa318142-7c0d-4b7f-b1a8-685a152be582/van-2010-10-29.flv&amp;blurover=false" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="scale" value="showall" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="base" value="http://content.screencast.com/users/AltNetHispano/folders/VAN/media/fa318142-7c0d-4b7f-b1a8-685a152be582/" /&gt;Unable to display content. Adobe Flash is required. &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-4978736264855900882?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/4978736264855900882/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=4978736264855900882' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/4978736264855900882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/4978736264855900882'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/11/van-sobre-integracion-continua.html' title='VAN sobre integración contínua'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-8226496873602455427</id><published>2010-10-27T22:41:00.000+02:00</published><updated>2010-10-27T22:42:13.793+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='diseño'/><category scheme='http://www.blogger.com/atom/ns#' term='refactorizar'/><category scheme='http://www.blogger.com/atom/ns#' term='tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='kata'/><title type='text'>Entrenando tu código</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Verdana, sans-serif; font-size: 12px; color: rgb(34, 34, 34); "&gt;&lt;p&gt;Kata (型 o 形) es un término Japonés utilizado, normalmente en el ámbito de la artes marciales, para describir una serie de ejercicios o movimientos preestablecidos que pueden practicarse sin rival y sirven al practicante como entrenamiento para aumentar sus capacidades. Es, de la misma manera que en otras disciplinas como la música, a través de la repetición continua y rigurosa de estos ejercicios la única manera en la que el estudiante puede llegar a dominar la técnica en su máximo nivel,  además de llegar a comprender el espíritu del arte marcial en cuestión.&lt;/p&gt;&lt;p&gt;De la misma manera que los practicantes de artes marciales, los desarrolladores también tenemos formas de  entrenar nuestras capacidades, y una de las mejores son las Katas de Código. Estas consisten en el planteamiento de diferentes problemas que tenemos que intentar resolver de la mejor manera posible. Cómo en las artes marciales, la práctica y la repetición de este tipo de ejercicios nos permiten mantener nuestras capacidades al máximo nivel. Hay que tener en cuenta que lo mas importante no es la resolución del problema, si no el proceso que lleva a la resolución del mismo.&lt;/p&gt;&lt;p&gt;Gracias a este tipo de ejercicios se persigue obtener una excelente base técnica, que nos permita enfrentarnos a problemas en proyectos reales con una alta garantía de éxito y centrándonos mayoritariamente en el dominio del problema y no en los aspectos técnicos del mismo.&lt;/p&gt;&lt;p&gt;Las katas de código pueden ser de diferentes tipos y naturaleza (algoritmos, matemáticas, modelado, centradas en tecnologías, de refactorización...) y de diferentes niveles de dificultad. &lt;/p&gt;&lt;p&gt;Algunos sitios web donde se pueden encontrar Katas son:&lt;/p&gt;&lt;p&gt;http://codingkata.org/&lt;/p&gt;&lt;p&gt;http://codekata.pragprog.com/&lt;/p&gt;&lt;p&gt;&lt;a href="http://codingdojo.org/cgi-bin/wiki.pl?KataCatalogue" _cke_saved_href="http://codingdojo.org/cgi-bin/wiki.pl?KataCatalogue" target="_blank" style="color: rgb(28, 81, 168); "&gt;http://codingdojo.org/cgi-bin/&lt;wbr&gt;wiki.pl?KataCatalogue&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;wbr&gt;&lt;/p&gt;&lt;p&gt;&lt;wbr&gt;&lt;/p&gt;&lt;wbr&gt;&lt;p&gt;&lt;wbr&gt;&lt;/p&gt;&lt;wbr&gt;&lt;p&gt;&lt;wbr&gt;&lt;/p&gt;&lt;wbr&gt;&lt;p&gt;&lt;wbr&gt;&lt;/p&gt;&lt;wbr&gt;&lt;p&gt;&lt;wbr&gt;&lt;wbr&gt;&lt;/p&gt;&lt;wbr&gt;&lt;wbr&gt;&lt;p&gt;Ya podéis empezar a entrenar vuestro código!!&lt;/p&gt;&lt;p&gt;Un saludo!!&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-8226496873602455427?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/8226496873602455427/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=8226496873602455427' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8226496873602455427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8226496873602455427'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/10/entrenando-tu-codigo.html' title='Entrenando tu código'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-8069572992271123597</id><published>2010-09-26T10:40:00.008+02:00</published><updated>2010-09-26T13:32:33.395+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='re-estimating'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='user stories'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Reestimando historias</title><content type='html'>Suele pasar en ocasiones que finalizar alguna historia de usuario nos lleva mucho mas tiempo del que a priori podíamos esperar. Esta situación suele llevar a la pregunta de si se debe reestimar o no la estimación hecha para esa historia de usuario. En este post vamos a tratar de explicar en qué situaciones se debe reestimar y en cuales no, basándonos en lo explicado por Mike Cohn en su libro &lt;a href="http://www.amazon.com/Agile-Estimating-Planning-Mike-Cohn/dp/0131479415"&gt;Agile Estimating And Planning&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para ello vamos a ayudarnos de un ejemplo. Imaginemos que tenemos las siguientes historias de usuario en el backlog:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="border-collapse: collapse; font-size:medium;"&gt;&lt;span class="Apple-style-span" style="border-collapse: separate;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: auto;"&gt;&lt;span class="Apple-style-span"  style="border-collapse: collapse; font-size:medium;"&gt;&lt;table frame="VOID" cellspacing="0" cols="3" rules="NONE" border="0" style="text-align: left; "&gt;&lt;colgroup&gt;&lt;col width="33"&gt;&lt;col width="91"&gt;&lt;col width="100"&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td width="33" height="18" align="LEFT" bg="" sdnum="3082;0;@"  style="text-align: center; border-top-width: 1px; border-top-style: solid; border-top-color: rgb(0, 0, 0); border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;ID&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;td width="91" align="LEFT" bg="" sdnum="3082;0;@"  style="border-top-width: 1px; border-top-style: solid; border-top-color: rgb(0, 0, 0); color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;Historia&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;td width="100" align="LEFT" bg="" sdnum="3082;0;@"  style="border-top-width: 1px; border-top-style: solid; border-top-color: rgb(0, 0, 0); border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;Estimación&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="1" sdnum="3082;0;@"  style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;1&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia A&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="3" sdnum="3082;"  style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="2" sdnum="3082;0;@"  style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;2&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia B&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="5" sdnum="3082;"  style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="3" sdnum="3082;0;@"  style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia C&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="3" sdnum="3082;"  style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="4" sdnum="3082;0;@"  style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;4&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia D&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="3" sdnum="3082;"  style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="5" sdnum="3082;0;@"  style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia E&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="3" sdnum="3082;"  style="border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td height="18" align="RIGHT" bg="" sdval="6" sdnum="3082;0;@"  style="border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-width: 1px; border-left-style: solid; border-left-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;6&lt;/span&gt;&lt;/td&gt;&lt;td align="LEFT" bg=""  style="border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;Historia F&lt;/span&gt;&lt;/td&gt;&lt;td align="RIGHT" bg="" sdval="5" sdnum="3082;"  style="border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-right-width: 1px; border-right-style: solid; border-right-color: rgb(0, 0, 0); color:#FFFFFF;"&gt;&lt;span style="color:#000000;"&gt;5&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;   &lt;div style="text-align: left;"&gt;Supongamos que que las historias A, B y C tienen todas que ver en en cuanto a tamaño y complejidad ya que lidian con el mismo tipo de tecnología (por ejemplo una integración con un  sistema externo mediante servicios web). Revisando las historias el equipo decide incluir en cada sprint las siguientes historias:&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;table frame="VOID" cellspacing="0" cols="2" rules="NONE" border="0"&gt;  &lt;colgroup&gt;&lt;col width="91"&gt;&lt;col width="100"&gt;&lt;/colgroup&gt;  &lt;tbody&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" width="91" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 1 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" width="100" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia A&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia B&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia F&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 2 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia C&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia D&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-left: 1px solid #000000color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia E&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-right: 1px solid #000000color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt; &lt;/table&gt;   &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Al finalizar el primer sprint únicamente se ha completado la historia A y la F, es decir un total de 8 PH. El equipo sabe que la historia A es el doble de compleja que lo que habían estimado, así que tienen que decidir que hacer con las estimaciones de la propia historia y de las historias similares (B y C)&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;1. &lt;b&gt;No reestimar&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;Si deciden no reestimar ninguna de las 3 historias, para el siguiente sprint deberían, en principio seguir con las historias B y C, que son un total de 8ph. Debería ser suficiente ya que en el último sprint es exactamente la cantidad de puntos conseguidos, pero el equipo sabe que las historias B y C pueden llegar a ser el doble de complejas que lo inicialmente estimado, así que aunque el total de ph sea 8, el equipo no conseguirá terminarlas en un sprint.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Velocidad estimada: 8PH&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;table frame="VOID" cellspacing="0" cols="2" rules="NONE" border="0"&gt;  &lt;colgroup&gt;&lt;col width="100"&gt;&lt;col width="100"&gt;&lt;/colgroup&gt;  &lt;tbody&gt;   &lt;tr&gt;    &lt;td  style="border-top: 1px solid #000000; border-left: 1px solid #000000color:#000000;" width="100" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;Sprint 1 &lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" width="100" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;span class="Apple-style-span"  style="font-size:x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia A&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;3&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia F&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;5&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 2 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia B&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia C&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 3&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia D&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-left: 1px solid #000000color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia E&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-right: 1px solid #000000color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;i&gt;Probablemente no se llegue a finalizar el Sprint 2, debido a que las historias B y C pueden ser el doble de grandes.&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;i&gt;2. &lt;/i&gt;&lt;b&gt;Reestimar únicamente la historia finalizada&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Si se decide reestimar la historia finalizada, con por ejemplo el doble de puntos (6 en lugar de 3), el total de puntos del sprint queda en 11 ph. Esto seria suficiente para terminar en el sprint 2 las historias B, C y D. Sin embargo sabemos que las historias B y C pueden llegar a ser aproximadamente el doble de grandes de lo estimado inicialmente, con lo cual es muy probable que el equipo no pueda finalizar los 11ph de historia estimados para el siguiente sprint. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Velocidad estimada: 11PH&lt;/div&gt;&lt;div style="text-align: left;"&gt; &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;table frame="VOID" cellspacing="0" cols="2" rules="NONE" border="0"&gt;&lt;colgroup&gt;&lt;col width="100"&gt;&lt;col width="100"&gt;&lt;/colgroup&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td  style="border-top: 1px solid #000000; border-left: 1px solid #000000color:#000000;" width="100" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Sprint 1 &lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" width="100" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia A&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span class="Apple-style-span"  style="color:#FF0000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;6&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia F&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 2 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia B&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia C&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia D&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 3&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-left: 1px solid #000000color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia E&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-right: 1px solid #000000color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt; &lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;i&gt;Probablemente no se llegue a finalizar todo el sprint 2, debido a que las historias 2 y 3 pueden ser el doble de grandes&lt;/i&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;3. &lt;b&gt;Reestimar las historias relacionadas entre si.&lt;/b&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Si la reestimación se hace para las 3 historias relacionadas (la finalizada A, la B y la C), se consigue aumentar la velocidad del equipo hasta 11ph, pero ademas aumenta el tamaño del trabajo pendiente. En el siguiente sprint el equipo estaría preparado para abordar las historia B, que ahora vale 10ph, la C y la D en el tercer sprint (6ph + 3ph) y la E en el cuarto sprint.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;Velocidad estimada: 11PH&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;table frame="VOID" cellspacing="0" cols="2" rules="NONE" border="0"&gt;  &lt;colgroup&gt;&lt;col width="100"&gt;&lt;col width="100"&gt;&lt;/colgroup&gt;  &lt;tbody&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" width="100" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 1 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" width="100" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia A&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Historia F&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 2 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia B&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="10" sdnum="3082;"&gt;&lt;span style="color:#FF0000;"&gt;10&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 3&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-left: 1px solid #000000;color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia C&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-right: 1px solid #000000;color:#FFFFFF;" align="RIGHT" bg="" sdval="6" sdnum="3082;"&gt;&lt;span style="color:#FF0000;"&gt;6&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-left: 1px solid #000000color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia D&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-right: 1px solid #000000color:#FFFFFF;" align="RIGHT" bg="" sdval="3" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;3&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td color="#000000" style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;Sprint 4&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;    &lt;td  style="border-top: 1px solid #000000; border-right: 1px solid #000000color:#000000;" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color:#FFFFFF;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;   &lt;/tr&gt;   &lt;tr&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-left: 1px solid #000000color:#FFFFFF;" height="18" align="LEFT" bg="" sdnum="3082;0;@"&gt;&lt;span style="color:#000000;"&gt;Historia E&lt;/span&gt;&lt;/td&gt;    &lt;td  style="border-bottom: 1px solid #000000; border-right: 1px solid #000000color:#FFFFFF;" align="RIGHT" bg="" sdval="5" sdnum="3082;"&gt;&lt;span style="color:#000000;"&gt;5&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt;  &lt;/tbody&gt; &lt;/table&gt;   &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;La reestimación de todas las historias relacionadas nos permite obtener la planificación más exacta, aún a costa de ver cómo esta sobrepasa la inicialmente prevista. No reestimar o reestimar únicamente las historias finalizadas para obtener una mayor velocidad por sprint solamente consigue ocultar el retraso hasta los siguientes sprints, evitando así una de las ventajas de las metodologías ágiles : conseguir  información por adelantado que nos permita tomar decisiones de manera temprana en el tiempo. &lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;A modo de resumen:&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li style="text-align: left;"&gt;No se deben estimar las historias finalizadas con el objetivo de aumentar la velocidad por sprint.&lt;/li&gt;&lt;li style="text-align: left;"&gt;Se deben reestimar las historias cuyo tamaño y complejidad relativa hayan cambiado respecto al inicio de las estimaciones.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-8069572992271123597?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/8069572992271123597/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=8069572992271123597' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8069572992271123597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8069572992271123597'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/09/reestimando-historias.html' title='Reestimando historias'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1052648277239417801</id><published>2010-06-16T22:50:00.005+02:00</published><updated>2010-06-17T12:58:49.636+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='gestión de proyectos'/><category scheme='http://www.blogger.com/atom/ns#' term='conferencia'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Cas 2010 - Día 2</title><content type='html'>Con el cansancio acumulado del primer día pero con muchísimas ganas daba comienzo el segundo día de la conferencia.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para empezar, uno de los platos fuertes de la conferencia: una mesa redonda de expertos donde se debatiría sobre el actual estado de las metodologías ágiles en España. Con participación de representantes de la industria, de la universidad y con algunos conocidos agilistas de la comunidad  (&lt;a href="http://www.proyectalis.com/"&gt;Ángel Medinilla&lt;/a&gt;, &lt;a href="http://jmbeas.iexpertos.com/"&gt;José Manuel Beas&lt;/a&gt; y &lt;a href="http://www.xqa.com.ar/"&gt;Xavier Quesada&lt;/a&gt;), lo que pretendía ser un apasionado debate, se quedó en algo un poco más descafeinado, debido a la poca controversia y diferencia de opiniones entre los ponentes. Por otra parte,me sorprendió gratamente ver que desde la Facultad de Informática de Madrid (&lt;a href="http://www.fi.upm.es/"&gt;FIUPM&lt;/a&gt;), teniendo en cuenta que la universidad es una institución eminentemente waterfall,  se está apoyando y se está colaborando fuertemente en diferentes programas y de diferentes formas las metodologías ágiles.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En cuanto a las sesiones, igual que el primer día todas fueron de un gran nivel. En esta segunda jornada me centré más en sesiones a nivel de gestión o metodología y no tan centradas en prácticas de ingeniería, asisitiendo a Gestión de Ágil de Equipos e Itinerario de Implementación Ágil en la Empresa( Angel Medinilla) , Gestión ágil de requisitos (&lt;a href="http://geeks.ms/blogs/jlsoria/default.aspx"&gt;José Luis Soria&lt;/a&gt;), Prácticas recomendadas para la relación Cliente-Equipo... (&lt;a href="https://syst.eui.upm.es/jgarbajosa"&gt;Juan Garbajosa&lt;/a&gt; y &lt;a href="https://syst.eui.upm.es/ayague"&gt;Agustín Yague&lt;/a&gt;) y Diez maneras infalibles de asesinar Scrum (&lt;a href="http://geeks.ms/blogs/rcorral/"&gt;Rodrigo  Corral&lt;/a&gt;). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Todas ellas excelentes, aunque me quedé con ganas de asistir a la sesión de Fórmula-1 y a la de TDD, pero la imposibilidad de dividirme en 2 personas, me obligó a tener que elegir unas y descartar otras!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Para finalizar, una sesión de retrospectiva, donde los asistentes podíamos decirle a la organización aquellas cosas que considerábamos se podían mejorar, aquellas que no nos habían gustado y claro está,  las que se habían echo bien!! Una gran manera de involucrar a los asistentes a la vez que de intentar mejorar para futuras ediciones!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Como conclusión final, una gran conferencia, que ha sido todo un éxito tanto de asistencia como de contenidos (a mi juicio). Es estimulante saber que hay mucha gente que comparte las mismas inquietudes profesionales que tú, y es de esperar que eventos de este tipo ayuden a difundir el mensaje de que las metodologías ágiles pueden ayudar a las empresas que desarrollan software, no sólo, a ser más productivas y competitivas, sino a hacer del trabajo algo mas sostenible, motivador y ¿por qué no? , divertido!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo!!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1052648277239417801?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1052648277239417801/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1052648277239417801' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1052648277239417801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1052648277239417801'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/06/cas-2010-dia-2.html' title='Cas 2010 - Día 2'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-7906512079751920150</id><published>2010-06-10T23:39:00.004+02:00</published><updated>2010-06-14T13:14:23.954+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='agilidad'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='kniberg'/><title type='text'>CAS 2010 - Día 1</title><content type='html'>&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;Hace poco más de 3 horas que ha f&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;inalizado la primera jornada de la conferencia agile-spain 2010, y sin necesidad de esperar a la segunda creo que se puede afirmar que va a ser todo un éxito. La asistencia ha sido muy alta (incluso se ha tenido que quedar gente fuera de la conferencia por problemas de aforo) lo que demuestra que el movimiento ágil está empezando a irrumpir con fuerza entre todos aquellos dedicados al mundo de las tecnologías de la información.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;Resumiendo un poco este primer día, el plato estrella del día ha sido la KeyNote a cargo de Henrik Kniberg, sin duda una de las personas más relevantes del mundo en la divulgación de las metodologías ágiles, cosa que se puede entender viendo la soltura con la que se ha movido en el anfiteatro donde se llevaba a cabo la presentación. Henrik se ha metido al público en el bolsillo desde el minuto 0, y no lo ha dejado ir hasta el final, mientras iba explicando, de forma muy amena, conceptos de Scrum, Kanban o Xtreme Programming (a nivel introductor eso si). Sin duda alguna un gran inicio para la conferencia.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;Después de la KeyNote han empezado los talleres y sesiones de la conferencia. La selección ha sido dura, pero finalmente he presenciado aquellas sesiones que creo que más me pueden ayudar en mi trabajo diario. Entre ellas ha habido sesiones relacionadas con prácticas técnicas, BDD o Diseño guiado por comportamiento,  como montar un entorno completo de Integración Continua o una sesión (de nivel muy básico eso si) sobre buenas prácticas de desarrollo. Por otro lado he presenciado una sesión sobre como enfocar la implantación de Scrum en empresas grandes, y otra muy interesante sobre métricas y control de proyecto con metodologías ágiles.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;Todas las sesiones han sido de un gran nivel y todos los ponentes lo han hecho estupendamente.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;También la organización ha realizado un gran trabajo, e incluso haciendo honor al lema de que los cambios son bienvenidos en la agilidad, se ha solventado un problema de aforo en una sala (que era demasiado pequeña la verdad) realizando en poco minutos un traslado a otra sala mucho mas grande. Chapeau!!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span"  style="font-size:85%;"&gt;&lt;span class="Apple-style-span"&gt;Para resumir, algunas de las &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;ideas con las que me quedo, para intentar mejorar en la implantación de Scrum de mi empresa:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(48, 48, 48);font-family:'Trebuchet MS',Verdana,Futura,Arial,Helvetica,sans-serif;font-size:14px;"  &gt;&lt;div&gt;&lt;div&gt;&lt;ul style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Tener un Product Owner que haga bien su trabajo es condición, casi indispensable para que una metodología ágil funcione.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Las estimaciones de tareas a desarrollar mejoran, a medida que el número de personas implicadas en la misma aumenta.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Las estimaciones NO SON CONTRATOS!! Son inciertas y hay que aprender a vivir con ello.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Haz las cosas simples (KISS, Don't repeat yourself, YAGNI...). Que sea simple no quiere decir que sea fácil.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0); line-height: 19px;font-size:85%;" &gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Necesitamos métricas explícitas para controlar los proyectos. Las métricas cuestan dinero. Minimiza el trabajo para conseguir las métricas que necesites.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Hay muchas más cosas, pero son demasiadas ideas para plasmarlas aquí, y además mañana continuamos con otro buen montón de sesiones, que a buen seguro van a se interesantísimas!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="color: rgb(0, 0, 0); font-family: arial;"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-size:85%;" &gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span"&gt;Esperemos que este tipo de eventos ayuden a difundir la cultura del agilismo en nuestro país, y que la gente involucrada de una manera u otra se den cuenta de que hay una manera mucho más sostenible, rentable, lógica e incluso divertida de llevar a cabo los proyectos tecnológicos.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-family:'times new roman',Verdana,Futura,Arial,Helvetica,sans-serif;" &gt;&lt;span class="Apple-style-span" style="line-height: 19px;font-size:medium;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-family:'times new roman',Verdana,Futura,Arial,Helvetica,sans-serif;" &gt;&lt;span class="Apple-style-span" style="line-height: 19px;font-size:medium;" &gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 0, 0);font-family:sans-serif,Verdana,Futura,Arial,Helvetica,sans-serif;font-size:100%;"  &gt;&lt;span class="Apple-style-span" style="line-height: 19px;font-size:13px;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-7906512079751920150?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/7906512079751920150/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=7906512079751920150' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7906512079751920150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7906512079751920150'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/06/cas-2010-dia-1.html' title='CAS 2010 - Día 1'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-6370436920622223823</id><published>2010-05-06T18:04:00.009+02:00</published><updated>2010-05-10T09:37:36.036+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cas2010'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='conferencia'/><category scheme='http://www.blogger.com/atom/ns#' term='albaldejo'/><category scheme='http://www.blogger.com/atom/ns#' term='agile-spain'/><category scheme='http://www.blogger.com/atom/ns#' term='quesada'/><category scheme='http://www.blogger.com/atom/ns#' term='corral'/><category scheme='http://www.blogger.com/atom/ns#' term='kniberg'/><category scheme='http://www.blogger.com/atom/ns#' term='medinilla'/><title type='text'>Programa CAS2010</title><content type='html'>Como ya anunció mi amigo  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Vicenç&lt;/span&gt; en &lt;a href="http://devnettips.blogspot.com/2010/03/haciendo-realidad-la-agilidad.html"&gt;Haciendo realidad la agilidad&lt;/a&gt;,  los días 10 y 11 de Junio se celebra en Madrid &lt;a href="http://conferencia2010.agile-spain.com/"&gt;la primera conferencia sobre métodos ágiles en España&lt;/a&gt;, con el reclamo de &lt;a href="http://www.crisp.se/henrik.kniberg"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Henrik&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Kniberg&lt;/span&gt;&lt;/a&gt; como ponente principal del evento.&lt;br /&gt;&lt;br /&gt;Pues bien, ya se ha hecho público el &lt;a href="http://conferencia2010.agile-spain.com/?page_id=395"&gt;programa de la conferencia&lt;/a&gt;, donde además del mencionado &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Kniberg&lt;/span&gt; se van a dar cita algunas de las figuras mas importantes a nivel nacional dentro del movimiento de desarrollo y metodologías &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;Ágiles&lt;/span&gt;  cómo &lt;a href="http://www.presionblogosferica.com/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Angel&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Medinilla&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://www.xqa.com.ar/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Xavier&lt;/span&gt; Quesada&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/rcorral/"&gt;Rodrigo Corral&lt;/a&gt; o &lt;a href="http://www.proyectosagiles.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Xavier&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Albaladejo&lt;/span&gt;&lt;/a&gt; entre otros y donde podréis escoger entre sesiones y talleres de todos los gustos y colores.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Os recomiendo encarecidamente a todos los que tengáis algún tipo de interés o relación con las metodologías ágiles que no dudéis en pasaros por allí porque va a ser una gran oportunidad de aprender de la mano de los que más saben del tema, además de una gran oportunidad para intercambiar experiencias y conocimientos. Ahora el verdadero problema va a ser elegir entre tanta sesión de calidad! &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Un saludo y nos vemos en Madrid!!&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;PD&lt;/span&gt;: Viendo el alto nivel de los ponentes no es de extrañar que mi propuesta de sesión sobre integración continua no haya pasado el corte (de todas maneras lo volveré a intentar el año que viene).&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-6370436920622223823?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/6370436920622223823/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=6370436920622223823' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6370436920622223823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6370436920622223823'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/05/programa-cas2010.html' title='Programa CAS2010'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-392593822480434628</id><published>2010-03-23T22:02:00.004+01:00</published><updated>2010-03-23T22:08:11.890+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='estimación'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Tratando con Bugs en Scrum</title><content type='html'>&lt;!--StartFragment--&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;¿Se deben o no se deben estimar los BUGS usando Scrum? Nos preguntábamos hace unos días en el trabajo esta cuestión, sin llegar a tener claro cual debe ser el enfoque a utilizar para introducirlos de manera fluida en el ciclo de Scrum.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;!--StartFragment--&gt;&lt;/b&gt;&lt;/p&gt;&lt;b&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Durante mucho tiempo he defendido la idea de que los Bugs debían ser tratados cómo si fueran nuevas historias de usuario, , añadiendolos al backlog y realizando su correspondiente priorización y estimación en Puntos Historia. Esto funciona razonablemente bien si los Bugs detectados no son los suficientemente críticos cómo para poder esperar al siguiente Sprint para corregirlos, pero no es un buen método cuando los Bugs tienen que ser arreglados ya. &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Además este enfoque presentaba algunos problemas teóricos relacionados con la metodología, a saber:&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoListParagraphCxSpFirst" style="text-indent:-18.0pt;mso-list:l0 level1 lfo1"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;     Estimación de un bug, implica contabilizar dos veces el mismo trabajo (uno cuando se estima la historia, y otro cuando se estima el trabajo para arreglar lo que se ha hecho mal en la historia)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;span class="Apple-style-span" style="font-weight: 900; white-space: pre;"&gt;     E&lt;/span&gt;stimación en Scrum se utiliza para contabilizar el valor (relativo) que cada funcionalidad aporta al cliente, cómo los Bugs no aportan valor (más allà de solucionar un error cometido por nosotros mismos) no deberian estimarse.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;o:p&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;En cambio, creo que el enfoque correcto (o el que a mi me gusta más) es el de tratar los Bugs como “tareas adicionales” dentro de la historia donde se ha generado. &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;o:p&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;Usando este enfoque, la estimación de la historia no varía, pero si que variará el tiempo dedicado a finalizarla, poniendo de relieve el impacto de los mismos en aquellas historias donde se producen y consiguiendo que la velocidad del equipo no sea un dato falseado (hacer muchos puntos en cada Sprint, pero teniendo que arreglar muchas de las historias en el/las siguiente/s iteraciones).   Cómo consecuencia de esto, al tener más consciencia sobre el  impacto de los Bugs en las historias implementadas, se puede lograr una disminución importante en los defectos de futuras iteraciones.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;o:p&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;¿Cuál os parece a vosotros el enfoque mas adecuado? ¿Qué otro tipo de enfoque utilizáis para tratar los defectos ? Espero vuestros comentarios y aportes.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="Apple-style-span"  style="font-family:arial;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;  &lt;!--EndFragment--&gt;   &lt;/b&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;  &lt;!--EndFragment--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-392593822480434628?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/392593822480434628/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=392593822480434628' title='8 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/392593822480434628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/392593822480434628'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/03/tratando-con-bugs-en-scrum.html' title='Tratando con Bugs en Scrum'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-2870636759238318354</id><published>2010-03-19T18:31:00.002+01:00</published><updated>2010-03-19T18:34:26.850+01:00</updated><title type='text'>Haciendo realidad la agilidad</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://1.bp.blogspot.com/_ZaNkQuiMjcA/S6O0I_wUEyI/AAAAAAAACqs/M3rH9HyiJF0/s1600-h/agile.v.230.largo_.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="47" src="http://1.bp.blogspot.com/_ZaNkQuiMjcA/S6O0I_wUEyI/AAAAAAAACqs/M3rH9HyiJF0/s320/agile.v.230.largo_.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Ya tenemos a la vuelta de la esquina la primera conferencia sobre métodos ágiles en España. Tendrá lugar el 10 y 11 de Junio en el Campus de la E.U. Informática de la U.P.M en Madrid. Podéis obtener toda la información que necesitéis en la &lt;a href="http://conferencia2010.agile-spain.com/"&gt;web&lt;/a&gt; de la conferencia.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;No seáis tímidos y proponed cosas! Podéis proponer &lt;/span&gt;&lt;a href="http://conferencia2010.agile-spain.com/?page_id=41"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;sesiones&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;, &lt;/span&gt;&lt;a href="http://conferencia2010.agile-spain.com/?page_id=58"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;contribuciones&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;y &lt;/span&gt;&lt;a href="http://conferencia2010.agile-spain.com/?page_id=141"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;talleres&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;. Vendrá &lt;a href="http://www.crisp.se/henrik.kniberg"&gt;Henrik Kniberg&lt;/a&gt; como orador, así no que no os podéis perder la oportunidad de compartir cartel con el.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Y por supuesto, si queréis &lt;/span&gt;&lt;a href="http://conferencia2010.agile-spain.com/?page_id=45"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;patrocinar&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; la conferencia lo podéis hacer.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Nos vemos el 10 de junio en Madrid!&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-2870636759238318354?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/2870636759238318354/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=2870636759238318354' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2870636759238318354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2870636759238318354'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/03/haciendo-realidad-la-agilidad.html' title='Haciendo realidad la agilidad'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ZaNkQuiMjcA/S6O0I_wUEyI/AAAAAAAACqs/M3rH9HyiJF0/s72-c/agile.v.230.largo_.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-200044648833170327</id><published>2010-02-26T11:21:00.000+01:00</published><updated>2010-02-26T11:21:23.346+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testeo unitario'/><category scheme='http://www.blogger.com/atom/ns#' term='Hudson'/><category scheme='http://www.blogger.com/atom/ns#' term='integración continua'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='.Net'/><title type='text'>Integración continua con Hudson</title><content type='html'>Espero que a estas alturas de la película ya estemos todos convencidos de la necesidad de tener un mecanismo de integración continua en nuestro sistema de desarrollo. Hay un montón de herramientas que nos pueden ayudar como&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/teamsystem/default.aspx"&gt;Team Foundation Server&lt;/a&gt;,&amp;nbsp;&lt;a href="http://cruisecontrol.sourceforge.net/"&gt;Cruise Control&lt;/a&gt;&amp;nbsp;o, el que empezaremos a ver hoy,&amp;nbsp;&lt;a href="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Hoy empezaremos a ver como configurar &lt;a href="http://hudson-ci.org/"&gt;Hudson &lt;/a&gt;para tener una tarea que se descargue un proyecto de &lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt;, lo compile y pase los tests. Obviaremos la instalación tanto de &lt;a href="http://subversion.tigris.org/"&gt;Subversion &lt;/a&gt;como de &lt;a href="http://hudson-ci.org/"&gt;Hudson&amp;nbsp;&lt;/a&gt;por ser muy sencilla y poderse encontrar en muchos sitios.&lt;br /&gt;&lt;br /&gt;Lo primero que tenemos que hacer una vez instalado &lt;a href="http://hudson-ci.org/"&gt;Hudson&amp;nbsp;&lt;/a&gt;tenemos que instalar los plugins que vamos a necesitar. En nuestro caso estos son: Hudson Subversion Plugin, Hudson MSBuild Plugin, Hudson MSTest Plugin y el imprescindible Chuck Norris Plugin :-). Para instalarlos tenemos que ir al menú Gestionar Hudson -&amp;gt; Gestionar Plugins, seleccionarlos de la pestaña Todos los plugins, seleccionar dichos plugins y clicar sobre el botón instalar.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4RWOWh-a3I/AAAAAAAACoY/cgPAD7jKWTw/s1600-h/plugin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="165" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4RWOWh-a3I/AAAAAAAACoY/cgPAD7jKWTw/s320/plugin.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Ahora vamos a configurar un poco Hudson antes de ponernos con las tareas. Nos vamos al menú de Gestionar Hudson -&amp;gt; Configurar Sistema y cambiamos la ruta del directorio raiz si lo consideramos conveniente.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_ZaNkQuiMjcA/S4RX4ozcXRI/AAAAAAAACog/XIhuwGMbigY/s1600-h/system+config+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="60" src="http://1.bp.blogspot.com/_ZaNkQuiMjcA/S4RX4ozcXRI/AAAAAAAACog/XIhuwGMbigY/s320/system+config+1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;También le tenemos que configurar la ruta del MSBuild para poder llamarlo en nuestra tarea&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_ZaNkQuiMjcA/S4RYhOPxBqI/AAAAAAAACoo/fLB3E5xU9pw/s1600-h/system+config+2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="94" src="http://4.bp.blogspot.com/_ZaNkQuiMjcA/S4RYhOPxBqI/AAAAAAAACoo/fLB3E5xU9pw/s320/system+config+2.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Y finalmente le vamos a configurar el servidor de correo a utilizar. Tenemos que configurar la dirección del administrador, la dirección del servidor de Hudson para que funcionen los links que se nos envian, el sufijo por defecto si queremos que se extraigan las direcciones de correo de los usuarios de subversion y la configuración de nuestro servidor de correo saliente, en nuestro caso gmail.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4RZsFa_-rI/AAAAAAAACow/3C74KKW_m0E/s1600-h/system+config+3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="124" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4RZsFa_-rI/AAAAAAAACow/3C74KKW_m0E/s320/system+config+3.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Ahora ya podemos empezar a configurar la tarea. Para ello hacemos click sobre el link Nueva Tarea y nos aparecerá una ventana con varias opciones. En nuestro caso escogemos "Crear un proyecto de estilo libre".&lt;br /&gt;Lo primero es configurar es configurar un par de cosas básicas como la descripción de la tarea y el directorio personalizado del proyecto en caso de no querer el directorio por defecto de Hudson.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4eaAfKLVrI/AAAAAAAACpY/-Vj2k2LbFTc/s1600-h/task1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="116" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4eaAfKLVrI/AAAAAAAACpY/-Vj2k2LbFTc/s320/task1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;A continuación configuraremos el repositorio de subversion al que nos queremos conectar y la periodización de dicha conexión. En este caso nos conectaremos al repositorio para bajarnos el código a los cinco minutos de cada hora.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_ZaNkQuiMjcA/S4ebMOpOhsI/AAAAAAAACpg/PpMOl4uZYLw/s1600-h/task2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="182" src="http://4.bp.blogspot.com/_ZaNkQuiMjcA/S4ebMOpOhsI/AAAAAAAACpg/PpMOl4uZYLw/s320/task2.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;Ahora vamos a añadir un par de tareas para realizar tareas especificas de .Net. En este caso será realizar una compilación con MSBuild y lanzar los tests con MSTest. Para la tarea de MSBuild añadiremos la tarea llamada "Build a Visual Studio project or solution using MSBuild", escogemos la versión de MSBuild adecuada para nuestro proyecto, la solución a compilar y los parámetros de dicha compilación.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/S4ecz5HOzVI/AAAAAAAACpo/ggZVLo1yflw/s1600-h/task3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="45" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/S4ecz5HOzVI/AAAAAAAACpo/ggZVLo1yflw/s320/task3.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Seguidamente añadiremos un nuevo paso del tipo "ejecutar línea de comandos (shell)" para ejecutar los tests. Tenemos que introducir manualmente el comando para ejecutar MSTest desde línea de comandos generando un archivo .trx con los resultados de los tests para que Hudson los pueda interpretar.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4eeEpd27XI/AAAAAAAACpw/GOD0QXQejQk/s1600-h/task4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="38" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4eeEpd27XI/AAAAAAAACpw/GOD0QXQejQk/s320/task4.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Finalmente sólo nos falta configurar las opciones que nos interesen de las que ofrece Hudson al final de la página de configuración. En nuestro caso será necesario activar la opción "Publish MSTest result report" (especificando el archivo .trx que hemos generado anteriormente), "Notificación por correo" y, claro está, "Activate Chuck Norris" :-). Ahora ya podemos clicar sobre el link "Construir ahora". En caso que algún paso no esté bien configurado o el programa dé algún error, se nos enviará un mail con el error y en la página web de Hudson nos aparecerá la tarea al lado de un circulo rojo indicando que hay algún error. Si todo está bien, el circulo será azul y sólo se nos enviará un mail en caso que anteriormente hubiera habido una ejecución incorrecta, informándonos así que la build vuelve a estar bien.&lt;br /&gt;&lt;br /&gt;Espero que con este tutorial podáis empezar a trabajar con Hudson. Es un gran programa con un montón de opciones que iremos comentando a medida que nos parezcan interesantes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-200044648833170327?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/200044648833170327/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=200044648833170327' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/200044648833170327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/200044648833170327'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/02/integracion-continua-con-hudson.html' title='Integración continua con Hudson'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ZaNkQuiMjcA/S4RWOWh-a3I/AAAAAAAACoY/cgPAD7jKWTw/s72-c/plugin.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-321419986394943158</id><published>2010-01-30T13:13:00.002+01:00</published><updated>2010-02-03T11:12:35.383+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programación asíncrona .net multihilo eventos'/><title type='text'>Programación asíncrona</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Hoy vamos a hacer un post un poco más técnico, que ya hace tiempo que no hacemos ninguno. Vamos a hablar, en la línea de este otro &lt;a href="http://devnettips.blogspot.com/2008/04/excepciones-en-entorno-asncrono.html"&gt;post&lt;/a&gt;, de la programación asíncrona.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Quién no se ha encontrado alguna vez con la necesidad de hacer una tarea que consume mucho tiempo ( acceso a ficheros, cálculos complejos, acceso a la red, etc ) y no quiere que su interfície de usuario se vea afectado por ello? No veo ninguna mano alzada, así que supondremos que es algo recurrente.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Este tipo de programación se ha llevado a cabo históricamente mediante hilos. Aunque .Net ha facilitado mucho la programación con ellos, hacer un uso de los &lt;a href="http://msdn.microsoft.com/es-es/library/system.threading%28VS.80%29.aspx"&gt;mismos&lt;/a&gt;&amp;nbsp;no deja de ser añadir complejidad al programa y es una fuente típica de errores. Es por esto que existen otras alternativas a la programación asíncrona sin tener que utilizar explícitamente hilos. Estas alternativas son las siguientes:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Llamadas asíncronas a delegados.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Llamadas asíncronas utilizando la interfaz IAsyncResult.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;El componente BackgroundWorker.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Llamadas asíncronas basadas en eventos.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;En este artículo nos centraremos en esta última aproximación ya que es la más completa y la más recomendada.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Este patrón se apoya en la utilización de dos clases de ayuda proporcionadas por .Net: la clase &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperationmanager.aspx"&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;AsyncOperationManager&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt; que utilizaremos para crear instancias de la otra clase de ayuda, la &lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.aspx"&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;AsyncOperation&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;  que utilizaremos para efectuar el seguimiento del progreso de la tarea asíncrona e informar del mismo. Una de las ventajas que tiene es que los eventos de progreso y cancelación se hace en el hilo adecuado, con lo que podemos actualizar la interfíce de usuario directamente, sin tener que recurrir a &lt;a href="http://msdn.microsoft.com/es-es/library/system.windows.forms.control.invokerequired%28VS.80%29.aspx"&gt;Invoke&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Vamos a ver paso a paso como crear una clase que implemente este patrón y como crear una clase cliente que la instancie y utilice.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Lo primero que tenemos que hacer es, obviamente, crear nuestra clase que queremos que se pueda llamar de manera asíncrona. En nuestro caso creamos una clase llamada LazyClass.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Seguidamente vamos a declarar los delegados y los eventos públicos que necesitamos para informar al cliente del progreso y terminación de la tarea asíncrona.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public delegate void&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskProgressChangedEventHandler&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;(&lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskProgressChangedEventArgs &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pArgs);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public delegate void&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskCompletedEventHandler&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;(&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;object &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pSender, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskCompletedEventArgs &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pArgs);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Esto nos obliga a definir los argumentos LazyTaskCompletedEventArgs y LazyTaskProgressChangedEventArgs. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;La clase LazyTaskCompletedEventArgs tendrá la definición de las cosas que queremos que se informen al exterior cuando se haya terminado la tarea asíncrona. Esta clase puede ser tan compleja como queramos, aunque nosotros, por el bien del entendimiento del ejemplo, la hemos reducido lo máximo posible.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public class &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskCompletedEventArgs &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;: &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;AsyncCompletedEventArgs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;    {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;private int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; m_iNumIterations = &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;.MinValue;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;private int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; m_iTotalTime = &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;.MinValue;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// Constructor&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;LazyTaskCompletedEventArgs&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;(&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;int &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pNumIterations, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;int&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pTotalTime, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Exception &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pException, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;bool &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pCancelled, &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;object &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pState) : &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;base &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;(pException, pCancelled, pState )&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_iNumIterations = pNumIterations;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_iTotalTime = pTotalTime;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// Número de iteraciones&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; NumIterations&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; RaiseExceptionIfNecessary();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;return &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;m_iNumIterations;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// Tiempo transcurrido&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;/// &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;public int&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; TotalTime&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;get&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;RaiseExceptionIfNecessary();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;return &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;m_iTotalTime;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Como se puede ver, en cada una de las propiedades antes de devolver el valor se llama a una función ( del espacio de nombres &lt;a href="http://msdn.microsoft.com/es-es/library/system.componentmodel%28VS.80%29.aspx"&gt;System.ComponentModel&lt;/a&gt; ) llamada &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asynccompletedeventargs.raiseexceptionifnecessary.aspx"&gt;RaiseExceptionIfNecessary&lt;/a&gt;. Esta función se utiliza para evitar que alguien acceda a los valores de la clase si se ha producido algún error o se ha cancelado la invocación asíncrona. En tal caso, al acceder a cualquiera de las propiedades de la clase recibiremos una excepción del tipo &lt;a href="http://msdn.microsoft.com/es-es/library/system.invalidoperationexception%28VS.80%29.aspx"&gt;InvalidOperationException&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;La clase LazyTaskProgressChangedEventArgs derivará de la clase ProgressChangedEventArgs del espacio de nombres System.ComponentModel. En nuestro caso no le añadimos nada ( con el porcentaje tenemos suficiente ) pero se le podría añadir todo lo necesario para nuestra tarea en concreto.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Classe que define los argumentos del progreso de la tarea&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;public class &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs &lt;/span&gt;: &lt;span class="Apple-style-span" style="color: cyan;"&gt;ProgressChangedEventArgs&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs&lt;/span&gt;(&lt;span class="Apple-style-span" style="color: blue;"&gt;int &lt;/span&gt;pPercentatge, &lt;span class="Apple-style-span" style="color: blue;"&gt;object &lt;/span&gt;pState)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;: &lt;span class="Apple-style-span" style="color: blue;"&gt;base&lt;/span&gt;(pPercentatge, pState)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{            &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: verdana;"&gt;Lo siguiente es implementar los delegados privados que utilizaremos como puente para informar al cliente del progreso de la tarea. Estos delegados tendrán una firma del tipo &lt;a href="http://msdn.microsoft.com/es-es/library/system.threading.sendorpostcallback.aspx"&gt;SendOrPostCallback&lt;/a&gt;, definida también en el espacio de nombres System.ComponentModel.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback &lt;/span&gt;onProgressDelegate;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback &lt;/span&gt;onCompletedDelegate;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Y los inicializamos en el constructor de la clase:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;onProgressDelegate = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback&lt;/span&gt;(LazyTaskProgress);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;onCompletedDelegate = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback&lt;/span&gt;(LazyTaskCompleted);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;A continuación vamos a declarar el delegado encargado de realizar el trabajo que queramos hacer en nuestra clase. Este delegado tendrá que recibir un parámetro del tipo &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.aspx"&gt;AsyncOperation &lt;/a&gt;que se utilizará para hacer el seguimiento del progreso de la tarea asíncrona y un delegado de tipo &lt;a href="http://msdn.microsoft.com/es-es/library/system.threading.sendorpostcallback.aspx"&gt;SendOrPostCallback &lt;/a&gt;que se utilizará para notificar del fin de la operación. También puede recibir cualquier otro parámetro que necesitemos para la ejecución de la tarea.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private delegate void&lt;/span&gt; WorkerEventHandler ( &lt;span class="Apple-style-span" style="color: cyan;"&gt;AsyncOperation &lt;/span&gt;pOperation, &lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback &lt;/span&gt;pCompletionMethod );&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Después declararemos una colección para administrar las diferentes operaciones asíncronas que se produzcan en nuestra clase. Podemos utilizar un &lt;a href="http://msdn.microsoft.com/en-us/library/xfhwa508.aspx"&gt;Dictionary&lt;/a&gt;, un &lt;a href="http://msdn.microsoft.com/en-us/library/system.collections.specialized.hybriddictionary.aspx"&gt;HibrydDictionary &lt;/a&gt;o lo que más nos convenga.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;ListDictionary &lt;/span&gt;m_ldTasks = new &lt;span class="Apple-style-span" style="color: blue;"&gt;ListDictionary&lt;/span&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;A continuación pasamos a implementar los eventos públicos que utilizaremos para informar al cliente del progreso y terminación de la tarea asíncrona.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Implementación del delegado del progreso&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void &lt;/span&gt;LazyTaskProgress(&lt;span class="Apple-style-span" style="color: blue;"&gt;object &lt;/span&gt;pSate)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;ProgressChangedEventArgs&lt;/span&gt; e = pSate &lt;span class="Apple-style-span" style="color: blue;"&gt;as &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;FireOnLazyTaskProgressChanged(e);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Implementación del delegado de tarea completada&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void&lt;/span&gt; LazyTaskCompleted(&lt;span class="Apple-style-span" style="color: blue;"&gt;object &lt;/span&gt;pSate)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskCompletedEventArgs &lt;/span&gt;args = pSate &lt;span class="Apple-style-span" style="color: blue;"&gt;as &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskCompletedEventArgs&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;FireOnLazyTaskCompleted(args);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Lanza el evento de tarea completada&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void &lt;/span&gt;FireOnLazyTaskCompleted(&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskCompletedEventArgs &lt;/span&gt;pArgs)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (OnLazyTaskCompleted != &lt;span class="Apple-style-span" style="color: blue;"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OnLazyTaskCompleted(&lt;span class="Apple-style-span" style="color: blue;"&gt;this&lt;/span&gt;, pArgs);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Lanza el evento de progreso en la tarea&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void&lt;/span&gt; FireOnLazyTaskProgressChanged(&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs &lt;/span&gt;e)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;if (OnLazyTaskProgressChanged != &lt;span class="Apple-style-span" style="color: blue;"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;OnLazyTaskProgressChanged(e);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Y para acabar con la implementación de delegados tan sólo nos falta implementar el delegado de finalización de la tarea. Este delegado se llamará &amp;nbsp;cuando se haya terminado la ejecución de nuestra tarea. En este método es donde se elimina el identificador de la tarea de la colección y donde se da por terminada la tarea asíncrona llamando al método &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.postoperationcompleted.aspx"&gt;PostOperationCompleted&lt;/a&gt;. Una vez llamado este método, cualquier intento de utilización de la AsyncOperation a la que se refiere nos dará una excepción.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;/// Método que se llamará cuando la ejecución de la tarea de forma asíncrona haya acabado&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void&lt;/span&gt; LazyTaskCompletionMethod(&lt;span class="Apple-style-span" style="color: blue;"&gt;object &lt;/span&gt;pLazyTaskState)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskState &lt;/span&gt;taskState = pLazyTaskState &lt;span class="Apple-style-span" style="color: blue;"&gt;as &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskState&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;AsyncOperation &lt;/span&gt;operation = taskState.Operation;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;int &lt;/span&gt;iNumIterations = taskState.NumIterations;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;int &lt;/span&gt;iTotalTime = taskState.TotalTime;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;bool &lt;/span&gt;bCancelled = false;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Exception &lt;/span&gt;eException = taskState.TaskException;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskCompletedEventArgs &lt;/span&gt;args = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskCompletedEventArgs&lt;/span&gt;(iNumIterations, iTotalTime, eException, bCancelled, operation.UserSuppliedState);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;lock &lt;/span&gt;(m_ldTasks.SyncRoot)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (m_ldTasks.Contains(operation.UserSuppliedState))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_ldTasks.Remove(operation.UserSuppliedState);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;operation.PostOperationCompleted(onCompletedDelegate, args);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Ahora ya podemos pasar a implementar la función que hará el trabajo real de nuestra clase. En nuestro caso será algo tan trivial como un for con un sleep dentro para simular una tarea pesada. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Realiza la operación que queremos&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;private void&lt;/span&gt; DoTask(&lt;span class="Apple-style-span" style="color: cyan;"&gt;AsyncOperation &lt;/span&gt;pOperation, &lt;span class="Apple-style-span" style="color: cyan;"&gt;SendOrPostCallback &lt;/span&gt;pCompletionMethod)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;Exception &lt;/span&gt;ex = null;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;try&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;for &lt;/span&gt;(&lt;span class="Apple-style-span" style="color: blue;"&gt;int &lt;/span&gt;i = 0; i &amp;lt; 100; i++)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;if &lt;/span&gt;(!TaskCanceled(pOperation.UserSuppliedState))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System.Threading.&lt;span class="Apple-style-span" style="color: cyan;"&gt;Thread&lt;/span&gt;.Sleep(100);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs &lt;/span&gt;pChangedEventArgs = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskProgressChangedEventArgs&lt;/span&gt;(i + 1, pOperation.UserSuppliedState);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pOperation.Post(&lt;span class="Apple-style-span" style="color: blue;"&gt;this&lt;/span&gt;.onProgressDelegate, pChangedEventArgs);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;catch &lt;/span&gt;( &lt;span class="Apple-style-span" style="color: blue;"&gt;Exception&lt;/span&gt; e )&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ex = e;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;if &lt;/span&gt;(!TaskCanceled(pOperation.UserSuppliedState))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskState &lt;/span&gt;state = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;LazyTaskState&lt;/span&gt;(100, 10000, pOperation, ex);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;pCompletionMethod(state);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;En este código podemos ver tres cosas. La primera es que nos apoyamos en una función llamada TaskCancelled. Esta función, que la debemos implementar nosotros, simplemente mira en la colección si está el identificador de tarea que le pasamos como parámetro. Por otra parte podemos ver que cada vez que queremos informar de un cambio en el progreso de la tarea llamamos a la función &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.post.aspx"&gt;Post &lt;/a&gt;de la &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.asyncoperation.aspx"&gt;AsyncOperation &lt;/a&gt;que recibimos como parámetro. Y finalmente vemos que cuando acabamos la realización de la tarea llamamos al delegado del completionMethod.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Y ya nos vamos acercando al final. Ahora tan sólo nos queda implementar los métodos para iniciar y cancelar el trabajo. En el método para iniciar la tarea nos tendremos que asegurar que el identificador de tarea que nos pasan cómo parámetro es único mirando si está en la colección. En el método para cancelar, tan sólo tendremos que quitar la tarea de la colección. El framework hará el resto.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Realiza la tarea asíncronamente&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;///&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;public virtual void&lt;/span&gt; DoLazyTaskAsync(&lt;span class="Apple-style-span" style="color: blue;"&gt;object &lt;/span&gt;pTaskID)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;AsyncOperation &lt;/span&gt;operation = AsyncOperationManager.CreateOperation(pTaskID);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;lock &lt;/span&gt;(m_ldTasks.SyncRoot)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (m_ldTasks.Contains(pTaskID))&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;throw new &lt;/span&gt;ArgumentException("Ya existe una tarea con este identificador", "taskID");&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;m_ldTasks[pTaskID] = operation;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;doTaskDelegate = &lt;span class="Apple-style-span" style="color: blue;"&gt;new &lt;/span&gt;&lt;span class="Apple-style-span" style="color: cyan;"&gt;WorkerEventHandler&lt;/span&gt;(DoTask);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;doTaskDelegate.BeginInvoke(operation, completionMethodDelgate, &lt;span class="Apple-style-span" style="color: blue;"&gt;null&lt;/span&gt;, &lt;span class="Apple-style-span" style="color: blue;"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt; &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// Cancela la ejecución de una tarea asíncrona&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #38761d;"&gt;/// &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace; font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;public void&lt;/span&gt; CancelLazyTaskAsync(&lt;span class="Apple-style-span" style="color: blue;"&gt;object&lt;/span&gt; pTaskId)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;lock &lt;/span&gt;(m_ldTasks.SyncRoot)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: blue;"&gt;if &lt;/span&gt;( m_ldTasks.Contains(pTaskId ) )&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: cyan;"&gt;AsyncOperation &lt;/span&gt;operation = (&lt;span class="Apple-style-span" style="color: cyan;"&gt;AsyncOperation&lt;/span&gt;)m_ldTasks[pTaskId];&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (operation != &lt;span class="Apple-style-span" style="color: blue;"&gt;null&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; m_ldTasks.Remove(pTaskId);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Ya tenemos nuestra clase con una llamada a un método asíncrono preparada para ser utilizada por un cliente. Para completar su funcionalidad deberíamos tener también un método para que podamos llamarla de forma síncrona por si nos interesa.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;La implementación del cliente es muy sencilla. Simplemente nos tenemos que subscribir a los eventos de progreso y finalización y llamar a los métodos de inicio y cancelación cuando nos interese. Podéis ver el código completo en el adjunto.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana,sans-serif;"&gt;Espero que este pequeño ejemplo os haya servido de ayuda. Podéis descargaros el ejemplo de &lt;a href="http://www.megaupload.com/?d=HFV2N1JE"&gt;aquí&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-321419986394943158?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/321419986394943158/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=321419986394943158' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/321419986394943158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/321419986394943158'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/01/programacion-asincrona.html' title='Programación asíncrona'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-3848375256417182508</id><published>2010-01-17T22:03:00.002+01:00</published><updated>2010-01-17T22:32:21.622+01:00</updated><title type='text'>Programación en pareja</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/S1N7UjU3hgI/AAAAAAAACmk/u_Ij3Uc-Rok/s1600-h/susto.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 226px; height: 320px;" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/S1N7UjU3hgI/AAAAAAAACmk/u_Ij3Uc-Rok/s320/susto.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5427817568921945602" /&gt;&lt;/a&gt;Esta es más o menos la cara que se le queda a un gestor de proyectos tradicional cuando le comentas que quieres implantar que el equipo trabaje en parejas. Sin embargo es una de las mejores decisiones que hemos tomado para mejorar la calidad de nuestro código. Que ventajas le vemos? Pues las siguientes serian las principales:&lt;div&gt;&lt;ul&gt;&lt;li&gt;Calidad del análisis previo: no sólo programamos en pareja, sino que también hacemos el análisis técnico de la solución en pareja. Esto hace que el diseño sea mucho mejor ya que el error que uno sólo no detectaría, con la ayuda del otro si que lo hace.&lt;/li&gt;&lt;li&gt;Calidad del código: el código que sale de la programación en parejas es de mucha más calidad que el hecho por uno sólo. La idea que no tiene uno, la tiene el otro. El comentario que a uno le da pereza añadir, el otro se lo recuerda. El test que uno no cree necesario hacer, el otro le obliga a hacerlo. Y así una larga lista.&lt;/li&gt;&lt;li&gt;Concentración: si uno trabaja sólo y tiene ciertos problemas de concentración es posible que no dedique todo el tiempo que seria deseable a programar. Messenger, mail, charlas con el compañero son pequeñas cosas que, si no se gestionan correctamente, pueden hacer perder mucho tiempo a un programador. Trabajando en pareja esto se minimiza muchísimo. Nadie se atreve a charlar por el messenger si está con el compañero trabajando. El focus se aumenta muchísimo.&lt;/li&gt;&lt;li&gt;Aprendizaje: siempre se aprenden cosas de los compañeros, a no ser que haya demasiada diferencia entre las capacidades de ambos, con lo cual sólo aprendería uno. Pero si la pareja está bien montada ambos aprenden el uno del otro.&lt;/li&gt;&lt;li&gt;Propiedad colectiva del código: al ir cambiando de pareja y de tarea el conocimiento de las características del código va fluyendo entre los integrantes del equipo, haciendo mucho más fácil que alguien se incorpore al equipo.&lt;/li&gt;&lt;li&gt;Ánimo del equipo: en general a la gente le gusta más trabajar en equipo que no sólo y el hacerlo le anima a seguir trabajando y cohesiona al grupo.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Así que espero que a partir de ahora os animéis a probar la programación en pareja!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-3848375256417182508?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/3848375256417182508/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=3848375256417182508' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3848375256417182508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3848375256417182508'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/01/programacion-en-pareja.html' title='Programación en pareja'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ZaNkQuiMjcA/S1N7UjU3hgI/AAAAAAAACmk/u_Ij3Uc-Rok/s72-c/susto.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1401526878239800154</id><published>2010-01-11T22:01:00.010+01:00</published><updated>2010-01-12T10:23:05.936+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='planning poker'/><category scheme='http://www.blogger.com/atom/ns#' term='entregas'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='planificación'/><title type='text'>Planificando entregas con Scrum (I)</title><content type='html'>&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;En el post que nos ocupa vamos a ver los pasos para realizar la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;planificación&lt;/span&gt;&lt;/span&gt; de las diferentes entregas o &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;releases&lt;/span&gt;&lt;/span&gt; de un proyecto, utilizando &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Scrum&lt;/span&gt;&lt;/span&gt; (aunque este  proceso podría fácilmente aplicarse a cualquier metodología iterativa). &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Lo que se quiere conseguir es crear una &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;planificación&lt;/span&gt;&lt;/span&gt; a mas largo plazo, de mas duración que una iteración y que abarque las diferentes entregas del proyecto (que pueden ser varias si se realiza por fases o puede ser una única entrega), y que permita definir una previsión de que &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;funcionalidades&lt;/span&gt;&lt;/span&gt; se podrán tener finalizadas en una determinada fecha.&lt;br /&gt;&lt;br /&gt;En su estado más básico, una &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;planificación&lt;/span&gt; de entrega o de proyecto debería contar con como mínimo la siguiente información:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Una lista de historias de usuario, a ser posible estimadas y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;priorizadas&lt;/span&gt; (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;product&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;backlog&lt;/span&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Los miembros del equipo que participan en el proyecto (desarrolladores, analistas, administradores de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;bbdd&lt;/span&gt;...)&lt;/li&gt;&lt;li&gt;Fecha de inicio de la primera iteración y fecha de fin de la última iteración.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;Es importante indicar que este nivel de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;planificación&lt;/span&gt;&lt;/span&gt; no se debe caer en el error de intentar entrar en el detalle de que personas van a realizar que tareas, en que secuencia se van a realizar las mismas etc... Estos detalles deben dejarse para la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;planificación&lt;/span&gt; de cada iteración, momento en el que las historias de usuario se dividen en tareas a nivel técnico.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Los pasos   generales para realizar la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;planificación&lt;/span&gt;&lt;/span&gt; de las entregas son los siguientes:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Determinar los criterios mas relevantes para el éxito del proyecto, &lt;/span&gt;&lt;span class="Apple-style-span"&gt;por ejemplo entregar antes de una fecha determinada, tener un conjunto mínimo de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;funcionalidades&lt;/span&gt; pero una fecha flexible, una combinación de ambas...&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;ul&gt;&lt;li&gt;Realizar la estimación de las historias de usuario, &lt;span style="font-weight: normal;font-size:100%;" &gt;concretamente de aquellas que tienen una alta &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;probabilidad&lt;/span&gt; de formar parte de la siguiente entrega. Este proceso se realiza entre el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Product&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Owner&lt;/span&gt; y los miembros del equipo (¡¡Solo hace estimaciones el equipo!!) y se estima en puntos de historia o &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_17"&gt;días&lt;/span&gt; ideales (y usando alguna técnica estilo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Planning&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Poker&lt;/span&gt;)&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;ul&gt;&lt;li&gt;Seleccionar la duración de las iteraciones, &lt;span style="font-weight: normal;font-size:100%;" &gt;en base a la duración del proyecto. Lo normal es de 2 a 4 semanas, pero en proyectos de larga duración se pueden realizar iteraciones mas largas (aunque yo no lo recomiendo) o en proyectos muy cortos se pueden llegar a hacer iteraciones de una única semana.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;ul&gt;&lt;li&gt;Realizar una estimación de la velocidad, &lt;span style="font-weight: normal;font-size:100%;" &gt;en puntos de historia (o días ideales) del equipo. Si este ya ha trabajado junto se puede utilizar la velocidad media en anteriores iteraciones, si no lo mejor es hacer una estimación con alguna de las técnicas existentes para ello y ir ajustándola a medida que avance el proyecto.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;ul&gt;&lt;li&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Priorizar&lt;/span&gt;&lt;/span&gt; las historias de usuario, &lt;span style="font-weight: normal;font-size:100%;" &gt;de manera que siempre esté claro cual es la siguiente a desarrollar. Una buena  manera de asegurar esto es utilizando el enfoque de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Henrik&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;Kniberg&lt;/span&gt; en su muy recomendable &lt;a href="http://www.crisp.se/henrik.kniberg/ScrumAndXpFromTheTrenches.pdf"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;Scrum&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;and&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;XP&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;For&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;The&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;Trenches&lt;/span&gt;&lt;/a&gt;, donde utiliza el atributo importancia, en lugar de prioridad. La &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;priorización&lt;/span&gt; la decide el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Product&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;Owner&lt;/span&gt;, pero es aconsejable que escuche la opinión de los miembros del equipo, sobre todo en cuestiones relativa a la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;secuenciación&lt;/span&gt; de las historias de usuario.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;ul&gt;&lt;li&gt;Seleccionar las historias y la fecha de entrega, &lt;span style="font-weight: normal;font-size:100%;" &gt;en base a la velocidad y a la estimación realizada. Si el factor mas importante en el proyecto es la fecha de entrega, lo que se hará será calcular el conjunto de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;funcionalidades&lt;/span&gt; que se &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;preveen&lt;/span&gt; tener listas para esa fecha, si por el contrario, el factor importante son las &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;funcionalidades&lt;/span&gt; mínimas, se deduce la fecha estimada de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;finalización&lt;/span&gt;.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Comprobar que se cumplen los criterios de éxito del proyecto&lt;/span&gt;. Si no es así se debe volver a los procesos de estimación y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;priorización&lt;/span&gt;, haciendo los cambios necesarios (subdividir historias en otras mas pequeñas, cambiando la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;priorización&lt;/span&gt;...) hasta conseguir dar con un grupo de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;funcionalidades&lt;/span&gt; para la entrega que cumpla con los criterios de éxito.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Otras cosa a tener en cuenta durante el proceso es la decisión de determinar por adelantado que &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;funcionalidades&lt;/span&gt; se desarrollarán en cada iteración, o por el contrario sólo se deciden las &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;funcionalidades&lt;/span&gt; a entregar en la iteración más próxima (de entre todas las planeadas para la entrega)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;Cómo punto final, remarcar que es importantísimo que la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;planificación&lt;/span&gt; no sea un "papel colgado en la pared", &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;sinó&lt;/span&gt; que hay que ir &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;actualizándola&lt;/span&gt; y revisándola con cierta frecuencia,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;de manera que se pueda conocer &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_45"&gt;rápidamente&lt;/span&gt; las desviaciones o los cambios que ocurren. Una buena opción es &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;replanificar&lt;/span&gt; al inicio de cada iteración , justo antes de la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;planificación&lt;/span&gt; de la misma.&lt;br /&gt;&lt;br /&gt;Aprovecho para hacer referencia al post anterior &lt;a href="http://devnettips.blogspot.com/2009/12/calendario-de-sprint.html"&gt;Calendario de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;Sprint&lt;/span&gt; &lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;relacionando&lt;/span&gt; el concepto aquí explicado, con una de las reuniones propuestas en el mismo. Concretamente, la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;planificación&lt;/span&gt; de entregas seria lo que en el calendario &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;llamabamos&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;Planning&lt;/span&gt; (aunque en algunas &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;organizaciones&lt;/span&gt; &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_55"&gt;podría&lt;/span&gt; ser una fusión de las dos primeras reuniones explicadas, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;Review&lt;/span&gt; y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_58"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;Planning&lt;/span&gt;)&lt;br /&gt;&lt;br /&gt;En el siguiente Post, mostraré un ejemplo práctico de cómo realizar la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;Planificación&lt;/span&gt; de Entregas  de un proyecto sencillo.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1401526878239800154?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1401526878239800154/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1401526878239800154' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1401526878239800154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1401526878239800154'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2010/01/planificando-entregas-con-scrum-i.html' title='Planificando entregas con Scrum (I)'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-389908730007228928</id><published>2009-12-26T11:35:00.002+01:00</published><updated>2010-01-08T12:29:19.767+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calendario'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Calendario de Sprint</title><content type='html'>&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Uno de los mayores problemas que se pueden dar en una implantación de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Scrum&lt;/span&gt; es el empezar con la idea &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;preconcebida&lt;/span&gt; de que es una metodología que no requiere "mucho esfuerzo". Esto le sucede a mucha gente que ha oído hablar de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Scrum&lt;/span&gt; o metodologías ágiles en general y que únicamente se han quedado con la idea de que &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Scrum&lt;/span&gt; es "no documentar" o barbaridades similares.  Pero la realidad es que implantar &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Scrum&lt;/span&gt; en una empresa o departamento requiere de mucho esfuerzo y  ganas por parte de todos los implicados. En este post voy a tratar de explicar una manera de enfocar &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Scrum&lt;/span&gt; que creo que puede ser muy útil, sobretodo al inicio de una implantación. Para ello lo único que se necesita es crear un Calendario de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Sprint&lt;/span&gt;.&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Aunque parezca algo trivial, hacer un calendario nos puede ayudar sobretodo en las primeras etapas de la implementación de la metodología, cuando aún no están claras las diferentes prácticas y artefactos que intervienen en &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Scrum&lt;/span&gt;. El calendario de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Sprint&lt;/span&gt; que os propongo está basado mas o menos en cómo  funcionamos en nuestra empresa  (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Sprints&lt;/span&gt; de dos semanas y de miércoles a miércoles) pero obviamente se puede adaptar a lo que mas convenga a cada equipo y/o empresa.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;El calendario propuesto es el siguiente:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;img src="file:///C:/Users/JSOSA%7E1.AIF/AppData/Local/Temp/moz-screenshot-4.png" alt="" /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_EX9ub8lGIsQ/S0cW_ueGiAI/AAAAAAAAAIc/wxwDIiH9XwA/s1600-h/Dibujo.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 190px;" src="http://2.bp.blogspot.com/_EX9ub8lGIsQ/S0cW_ueGiAI/AAAAAAAAAIc/wxwDIiH9XwA/s400/Dibujo.jpg" alt="" id="BLOGGER_PHOTO_ID_5424329560252909570" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;img src="file:///C:/Users/JSOSA%7E1.AIF/AppData/Local/Temp/moz-screenshot-1.png" alt="" /&gt;&lt;img src="file:///C:/Users/JSOSA%7E1.AIF/AppData/Local/Temp/moz-screenshot-2.png" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Ahora vamos a detallar que significa cada uno de los diferentes puntos del calendario:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Review&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Revisión&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; del estado de los proyectos. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;Comunicación&lt;/span&gt; de cambios de requisitos, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;modificaciones&lt;/span&gt;,&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; problemas, &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;riesgos,&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;impedimentos&lt;/span&gt;, etc...&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;1h&lt;/span&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;Asistentes:&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Responsables de proyectos&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;y personas implicadas (clientes, gestores, gerentes, etc.)&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Documentación&lt;/span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Acta de reunión &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;documentando&lt;/span&gt; todos los cambios y las decisiones tomadas.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Planning&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción: &lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Adición&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; eliminación&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; o división de historias de usuario de cada proyecto (en base a lo detectado en la reunión de &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;Review&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;). &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Priorización&lt;/span&gt; y estimación de las nuevas historias de usuario y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;preselección&lt;/span&gt; de aquellas a desarrollar en el nuevo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;Sprint&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;1h &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes: &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Responsables de proyectos&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;/span&gt; y miembros del equipo de desarrollo (no tienen porque ser todos)&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;Documentación&lt;/span&gt;: &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;ProductBacklog&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; y documentos de diseño si son necesarios.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;Sprint&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;Planning&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;: Decidir los puntos a hacer durante el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;Sprint&lt;/span&gt; (basado en los &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_29"&gt;días&lt;/span&gt; laborables, recursos disponibles y proyectos en curso). División en tareas de las historias&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; escogidas y estimación (en horas ideales o puntos de historia). Escoger nuevas historias si caben en el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;Sprint&lt;/span&gt;. Preparación del &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;Task&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;Board&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;2h &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_33"&gt;Equipo&lt;/span&gt; de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;desarrollo&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;Documentación&lt;/span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;SprintBacklog&lt;/span&gt; y toda&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span style="font-weight: bold;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;la información adicional necesaria(&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_37"&gt;decisiones&lt;/span&gt; de &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_38"&gt;diseño&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;dudas&lt;/span&gt;, &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_40"&gt;comentarios&lt;/span&gt;...).&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;div&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;Daily&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;Scrum&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;Descripció&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;n: &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_44"&gt;Sincronización&lt;/span&gt; de las&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; tareas diarias hechas y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;actualización&lt;/span&gt; del &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;Task&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;Board&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;10 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;mins&lt;/span&gt;. &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_49"&gt;Equipo&lt;/span&gt; de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;desarrollo.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;Documentación&lt;/span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;Actualización&lt;/span&gt; del estado del &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;Sprint&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;Backlog&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_55"&gt;Sprint&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_56"&gt;Review&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;: Demostración funcional de las historias desarrolladas durante el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_57"&gt;Sprint&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;1h &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_58"&gt;Equipo&lt;/span&gt; de desarrollo, cualquier persona interesada en el &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_59"&gt;proyecto&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_60"&gt;Documentación&lt;/span&gt;:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Acta de la reunión con el &lt;/span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_61"&gt;feedback&lt;/span&gt; proporcionado, y con posibles errores y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_62"&gt;bugs&lt;/span&gt; encontrados durante la &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_63"&gt;demo&lt;/span&gt; (Esta información se utilizará en la siguiente reunión de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_64"&gt;Project&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_65"&gt;Review&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_66"&gt;Sprint&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_67"&gt;Retrospective&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;: Valoración del sprint (objetivos, gestión,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; resolución de impedimentos, etc.)&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;1h &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes:&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; Equipo de desarrollo&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Documentación:&lt;/span&gt;&lt;span&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Acta de la reunión con las conclusiones y los objetivos para el siguiente sprint.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Lab&lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;u&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Descripción&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;: Tiempo dedicado a investigación/pruebas &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;sobre temas interesantes para cada persona&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Duración: &lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: normal; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;1h &lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span style="font-weight: bold; vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Asistentes: &lt;/span&gt;&lt;/span&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;color:black;"  &gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Equipo de desarrollo&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="vertical-align: baseline;font-family:Calibri;font-size:11pt;color:black;"   &gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span class="Apple-style-span"  style="font-family:Calibri,serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span class="Apple-style-span"  style="font-family:Calibri,serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;Cómo se puede ver el calendario es simplemente una guía o base para seguir durante los Sprints, y no se tienen en cuenta todos los aspectos que pueden ir apareciendo durante el mismo (reuniones con clientes, sesiones de diseño, etc...), pero a pesar de todo creo que puede ser una buena práctica para aquellos equipos u organizaciones que están empezando con la implantación de Scrum.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span class="Apple-style-span"  style="font-family:Calibri,serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-top: 0pt; margin-bottom: 0pt; margin-left: 0in; text-indent: 0in;"&gt;&lt;span class="Apple-style-span"  style="font-family:Calibri,serif;"&gt;&lt;span class="Apple-style-span"  style="font-size:small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-389908730007228928?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/389908730007228928/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=389908730007228928' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/389908730007228928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/389908730007228928'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/12/calendario-de-sprint.html' title='Calendario de Sprint'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_EX9ub8lGIsQ/S0cW_ueGiAI/AAAAAAAAAIc/wxwDIiH9XwA/s72-c/Dibujo.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-7199250553503725291</id><published>2009-11-05T12:31:00.000+01:00</published><updated>2009-11-05T12:41:15.590+01:00</updated><title type='text'>Scrum y la motivación</title><content type='html'>Uno de los handicaps mas importantes de cualquier proyecto de software suele ser la motivación de los integrantes del equipo. Es muy dificil llevar a buen puerto un proyecto si el equipo no está lo suficientemente motivado e identificado con el mismo, por eso mismo creo que uno de los objetivos y de las prioridades de cualquier jefe o responsable de proyecto debería ser siempre intentar mantener un alto grado de motivación y compromiso por parte del equipo.&lt;br /&gt;Sin entrar a juzgar los diferentes tipos de "técnicas" o estrategias de motivación que suelen usar en la mayoria de proyectos de software los gerentes, gestores o responsables de proyecto que corren por el mundo, voy a intentar mostrar cómo Scrum puede ayudarnos un poco a la hora de mejorar la motivación y el compromiso buscados. Para ello vamos a repasar algunos de los conceptos y de puntos que forman o que persigue la metodología y ver cómo nos pueden ayudar:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Reunión planificación de proyecto/sprint: Estas reuniones aumentan la visibilidad del equipo respecto a los diferentes proyectos en los que tienen que participar,y además, al participar plenamente en la toma de decisiones (a nivel de diseño, arquitectura, desarrollo...) los miembros del equipo suelen considerar el proyecto cómo algo propio, aumentado de esta manera la motivación, y probablemente con ello la velocidad y calidad de los desarrollos. &lt;/li&gt;&lt;li&gt;Seguimiento diario: Con las reuniones de seguimiento diario se consigue que las personas mantengan un grado de concentración mayor, y una responsabilidad para con los otros miembros del equipo (al tener que responder de los avances delante de ellos) con lo que de nuevo aumenta la motivación de cara al proyecto.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Demostraciones: Las demostraciones al final de la iteración consiguen que el equipo observe su trabajo, lo muestre y vea las reacciones de otra gente de la compañia. Es cómo un reconocimiento (siempre que la demo vaya bien ;) ) al trabajo hecho, cosa que ayuda de nuevo a que el equipo siga motivado para la siguiente iteración.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Retrospectivas: El hacer que el equipo pueda opinar sobre como ha ido la iteración fomenta de nuevo el sentimiento de equipo y de propiedad de los proyectos, que cómo pasa en los puntos anteriores ayudan a que las personas sigan motivadas.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Con los puntos vistos anteriormente, vemos que aplicando Scrum , de manera implicita, se fomenta la motivación del equipo, sin necesidad de técnicas de presión, amenazas, etc. a las que tanto se recurre habitualmente.&lt;br /&gt;&lt;br /&gt;Un saludo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-7199250553503725291?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/7199250553503725291/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=7199250553503725291' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7199250553503725291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7199250553503725291'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/10/scrum-y-la-motivacion.html' title='Scrum y la motivación'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-6347748879569025483</id><published>2009-08-21T16:11:00.003+02:00</published><updated>2009-08-24T12:45:34.489+02:00</updated><title type='text'>Primeros pasos debugando de verdad</title><content type='html'>El otro dia nos encontramos con un problema en el trabajo. Teniamos una aplicación que cascaba aleatoriamente y no sabíamos por que. Teníamos que encontrar el problema y solucionarlo de manera urgente o algún cliente estaria muy pero que muy enfadado.&lt;br /&gt;&lt;br /&gt;Como profanos en la materia empezamos nuestro estudio con nuestro amigo el Administrador de Tareas de windows. Un vistazo a la memória del proceso y al máximo de memória nos hacía pensar que alguna acción de nuestra aplicación hacia que la memória tubiera picos que después se recuperaban. En uno de estos picos, la aplicación acababa diciendo basta y empezaba a funcionar muy mal, llegando a cerrarse. Como primer paso no estaba mal, pero no teniamos ni idea de cómo solucionarlo.&lt;br /&gt;&lt;br /&gt;Después de un rato navegando por internet buscando información sobre profilers nos decidimos a probar el &lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;windbg&lt;/a&gt;. Algunos artículos de los grandes &lt;a href="http://geeks.ms/blogs/rcorral/archive/2008/04/28/c-243-mo-cazar-una-fuga-de-memoria-en-net-i.aspx"&gt;Rodrigo Corral&lt;/a&gt;, &lt;a href="http://geeks.ms/blogs/palvarez/archive/2008/01/03/teaser-descubriendo-windbg.aspx"&gt;Pablo Doval&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/dsalgado/archive/2008/04/24/reto-i-de-rodrigo-corral-d.aspx"&gt;David Salgado&lt;/a&gt; nos ayudaron a hacer nuestros primeros pinitos con la herramienta, pero todavía no eramos lo suficientemente hombres cómo para utilizarla correctamente, así que buscamos alguna otra manera de hacerlo.&lt;br /&gt;&lt;br /&gt;Llegamos a este artículo de &lt;a href="http://geeks.ms/blogs/rcorral/archive/2008/04/28/c-243-mo-cazar-una-fuga-de-memoria-en-net-i.aspx"&gt;Ro&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ZaNkQuiMjcA/SpJu8UxuKCI/AAAAAAAACkc/kXzfl_p_oDY/s1600-h/memoria.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 256px;" src="http://4.bp.blogspot.com/_ZaNkQuiMjcA/SpJu8UxuKCI/AAAAAAAACkc/kXzfl_p_oDY/s320/memoria.png" alt="" id="BLOGGER_PHOTO_ID_5373479288054884386" border="0" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/blogs/rcorral/archive/2008/04/28/c-243-mo-cazar-una-fuga-de-memoria-en-net-i.aspx"&gt;drig&lt;/a&gt;&lt;a href="http://geeks.ms/blogs/rcorral/archive/2008/04/28/c-243-mo-cazar-una-fuga-de-memoria-en-net-i.aspx"&gt;o&lt;/a&gt; donde se comenta cómo determinar que tipo de problema de memoria tiene una aplicación. Pusimos los tres contadores en la máquina de preproducción ( bytes privados del proceso, bytes en todos los montones y colecciones de generación 2 ) y lo que parecía indicar el gráfico resultate ( ver imágen ) es que no teniamos una fuga de memoria ( o por lo menos no era nuestro mayor problema ) sinó que teniamos un incremento escandaloso de memoria manejada. Esto nos llevó directos a la &lt;a href="http://geeks.ms/blogs/rcorral/archive/2008/05/06/c-243-mo-cazar-una-fuga-de-memoria-en-net-y-ii.aspx"&gt;segunda parte&lt;/a&gt; del artículo de Rodrigo, donde se habla de la herramienta CLRProfiler. Con esta herramienta pudimos ver que función era la que creaba el problema.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lo que hacía la función era cargar un archivo en memoria para calcularle un MD5. Cómo esta operación se podia realizar a la vez en unos 50 ficheros que podian llegar a los 5MB, el incremento de memoria que tenia el sistema era preocupante. Modificamos esta función para no cargar todo el archivo y hacerla más liviana y el problema se vió reducido a la nada.&lt;br /&gt;&lt;br /&gt;Esto es sólo el principio de lo que esperamos sea un aprendizaje de todas estas herramientas y de las entrañas del CLR. Intentaremos ir posteando nuestras experiéncias y las cosas que vayamos aprendiendo.&lt;br /&gt;&lt;br /&gt;Saludos!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-6347748879569025483?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/6347748879569025483/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=6347748879569025483' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6347748879569025483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/6347748879569025483'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/08/primeros-pasos-debugando-de-verdad.html' title='Primeros pasos debugando de verdad'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ZaNkQuiMjcA/SpJu8UxuKCI/AAAAAAAACkc/kXzfl_p_oDY/s72-c/memoria.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1000045954706508390</id><published>2009-05-11T23:16:00.000+02:00</published><updated>2009-05-11T23:09:39.694+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agil'/><category scheme='http://www.blogger.com/atom/ns#' term='gestión de proyectos'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='TaskBoard'/><title type='text'>El tablón como herramienta de gestión</title><content type='html'>Uno de las prácticas de más importancia cuando se habla de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Scrum&lt;/span&gt;&lt;/span&gt; son las reuniones diarias delante del tablón.  A pesar de ello son pocos los equipos que utilizan un tablón cómo herramienta de gestión (&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;al menos&lt;/span&gt;  que yo  conozca), o si lo utilizan normalmente no se le extrae todo el provecho posible ¿Que ventajas puede aportar el utilizar un  tablón donde se registran las tareas, su estado, el trabajo que nos queda...? ¿No es posible realizar esto mismo con una herramienta informática evitando así perder un tiempo &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;valiosísimo&lt;/span&gt;&lt;/span&gt; cada día delante del tablón?&lt;br /&gt;&lt;br /&gt;Desde mi punto de vista, y basándome en mi (todavía poca) experiencia, la utilización correcta del tablón de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Scrum&lt;/span&gt;&lt;/span&gt; en las reuniones diarias es una de las prácticas indispensables de la metodología, y aunque cada organización que implante &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Scrum&lt;/span&gt;&lt;/span&gt; puede y debe adaptarla a sus necesidades, estas reuniones no &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_6"&gt;deberían&lt;/span&gt; faltar, ya que &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;muchas&lt;/span&gt; de las ventajas que aporta la metodología se consigue a través de esta práctica (comunicación, colaboración...)&lt;br /&gt;&lt;br /&gt;Obviamente es básica la utilización de alguna herramienta de software adicional (por ejemplo Hojas &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Excel&lt;/span&gt;&lt;/span&gt;, Jira, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Trac&lt;/span&gt;&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;Team&lt;/span&gt;&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Foundation&lt;/span&gt;&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Server&lt;/span&gt;&lt;/span&gt; o cualquier otra que se adecue a nuestras necesidades)  ya sea para tener  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;trazabilidad&lt;/span&gt;&lt;/span&gt; e información del estado de las diferentes tareas de un proyecto, por temas legales (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;auditorías&lt;/span&gt;&lt;/span&gt;, certificados de calidad, ...) o por cualquier otra &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_14"&gt;necesidad&lt;/span&gt;, pero &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;combinándolo&lt;/span&gt; con la gestión &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_16"&gt;día&lt;/span&gt; a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_17"&gt;día&lt;/span&gt; delante del tablón es cuando vamos a conseguir explotar mucho mas las ventajas de &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;Scrum&lt;/span&gt; (algunas explícitas otras más &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_18"&gt;implícitas&lt;/span&gt;):&lt;br /&gt;&lt;br /&gt;-Sensación real y inmediata de progreso (o de no progreso)&lt;br /&gt;-Visibilidad a terceros del estado del proyecto&lt;br /&gt;-Mayor sensación de equipo&lt;br /&gt;-Mayor motivación entre los miembros del equipo&lt;br /&gt;-Identificación con los proyectos y responsabilidad para con ellos&lt;br /&gt;&lt;br /&gt;Sin la utilización de un tablón  los programadores y otros componentes del equipo  no van a tener una visión global y &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;fácilmente&lt;/span&gt; accesible del avance del proyecto, ni tampoco otros roles interesados en el estado (comerciales, directivos, analistas de negocio...), lo que puede generar en desconfianzas, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;desmotivaciones&lt;/span&gt;&lt;/span&gt;, etc...&lt;br /&gt;&lt;br /&gt;Si por el contrario mantenemos el tablón actualizado y bien visible vamos a conseguir que, además de las ventajas listadas antes , los roles  interesados en el avance del proyecto conozcan la velocidad y la capacidad de generar software de cada equipo, lo que debería desembocar en un mayor entendimiento entre los diferentes departamentos de la organización implicados o interesados en el desarrollo de una determinada pieza de software evitando en la medida de lo posible las interferencias en medio de iteraciones, etc.&lt;br /&gt;&lt;br /&gt;¿Que &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_21"&gt;opináis&lt;/span&gt; vosotros sobre la gestión con el tablón? ¿Que ventajas o inconvenientes &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_22"&gt;encontráis&lt;/span&gt;?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1000045954706508390?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1000045954706508390/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1000045954706508390' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1000045954706508390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1000045954706508390'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/05/el-tablon-como-herramienta-de-gestion.html' title='El tablón como herramienta de gestión'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-7276976674786233097</id><published>2009-03-26T16:49:00.005+01:00</published><updated>2009-03-26T16:57:27.187+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='refactorizar'/><category scheme='http://www.blogger.com/atom/ns#' term='legibilidad'/><category scheme='http://www.blogger.com/atom/ns#' term='código'/><category scheme='http://www.blogger.com/atom/ns#' term='estandarizar'/><category scheme='http://www.blogger.com/atom/ns#' term='estilo'/><title type='text'>Programando con estilo</title><content type='html'>&lt;span style="font-weight: bold;font-size:100%;" &gt;Antecedentes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Tradicionalmente el desarrollo de software ha sido una actividad individual. Muchos proyectos se llevaban a cabo con la participación de un único programador, o dos a lo sumo, que se encargaban de todas y cada una de las fases del proyecto. A medida que las necesidades de los usuarios han ido aumentado y la tecnología avanzando, el ámbito de los proyectos ha crecido, y con ello la necesidad de añadir más participantes (no sólo programadores sino también otros roles) al proceso de desarrollo de software. Este cambio, el paso de trabajar individualmente a trabajar en equipo, requiere un esfuerzo por parte de las personas involucradas, pero es especialmente importante el impacto que tiene en los programadores (se pasa de un programador que controla todas y cada una de las partes del código a un mismo código que puede ser modificado por varios individuos a la vez) Para solucionar este problema se empezaron a utilizar herramientas cómo el control de versiones, pero no basta con esto. Problemas cómo la poca documentación en el código, la poca estructuración, nomenclaturas extrañas... dificultan la legibilidad del código cuando un programador tiene que modificar código realizado por otro (o incluso cuando se tiene que tocar código realizado por uno mismo tiempo atrás)  Esto acaba repercutiendo en una menor productividad de los desarrolladores hace los códigos poco reusables,escalables, etc.&lt;br /&gt;Para solucionar esto se necesita organización y disciplina por parte de los implicados y es aquí donde puede entrar en juego la Guía de estilo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;¿Qué es?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Una guía de estilo no es mas que la definición de una serie de pautas que han de seguir los programadores cuando estén creando o modificando código. Una guia de estilo hace incidencia en cómo debe presentarse el código, o sea en la forma y no en el fondo del mismo. Pero cómo ahora veremos, esto tiene un importante impacto en cómo va a funcionar el mismo.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Las pautas que puede dictar una guía de estilo son muchas, desde cómo debe indentarse el código, a cómo se deben nombrar las variables, funciones, métodos, clases u objetos que aparecen en el código. También son muy importantes los comentarios realizados en él, y más si estamos trabajando en el ámbito de una metodología ágil donde el código se considera parte esencial de la documentación del proyecto.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;¿Que nos aporta?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;A priori se puede pensar que aplicar una guia de estilo al código de nuestros proyectos es simplemente una herramienta de “burocratización” que lo único que hará será más lenta y tediosa la tarea de programar (muchos programadores son reacios a ello, sobretodo los que estan acostumbrados a trabajar de manera individual), pero la realidad es bien distinta. La principal aportación de “estandarizar” el código es el incremento de la legibilidad por parte de todos los desarrolladores,  haciendo que disminuya el tiempo que una persona necesita para entender el código, ganando tiempo al codificar (al asimilar las reglas de nombrado de clases, variables, etc, se pierde menos tiempo), facilitando la refactorización, lo que puede llevar a incrementar la escalabilidad del código, la reusabilidad, la modularidad, la facilidad para la generación de testos unitarios,etc. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Toda esta serie de mejoras que se pueden conseguir acaban impactando en dos factores clave para cualquier proyecto de software:&lt;br /&gt; ● La calidad del código&lt;br /&gt; ● La productividad de los programadores &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ejemplos&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Algunos ejemplos de Guias de Estilo que podems encontrar en Internet pueden ser los siguientes:&lt;br /&gt;&lt;br /&gt;Guia de estilo para el diseño de aplicaciones .NET  - http://msdn.microsoft.com/es-es/library/czefa0ke(VS.71).aspx&lt;br /&gt;Guía de estilo Philips Medical Systems(C#) -http://www.tiobe.com/content/paperinfo/gemrcsharpcs.pdf&lt;br /&gt;Guía de estilo programación en  Java - http://java.sun.com/docs/codeconv/&lt;br /&gt;Guía de estilo Mono: http://www.mono-project.com/Coding_Guidelines&lt;br /&gt;Guía de estilo para el nucleo de Linux: http://lxr.linux.no/linux/Documentation/CodingStyle&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Para empezar no se debe intentar implantar una guia de las dimensiones y el alcanze de las aquí mostradas. Es mucho mejor empezar con pocas reglas y irla adaptando y ampliando a medida que sea posible y/o necesario.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusiones&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Cómo se puede ver una guia de estilo es una excelente manera de “estandarizar” el código de los proyectos de desarrollo de software, estandarización que puede impactar muy positivamente en la  productividad y la calidad de los desarrollos siempre y cuando realmente se aplique a la hora de las implementaciones.&lt;br /&gt;La poca predisposición por parte de muchos desarrolladores a que “les digan” cómo deben hacer su código, y la dificultad para realizar un control de manera eficiente (puede ser peor el remedio que la enfermedad) hacen que la implantación de una guia de estilo de manera que tenga un impacto real sea dificil. Si por el contrario los desarrolladores ponen de su parte y se puede llevar a cabo un control que imponga burocracia 0 (hay herramientas que permiten este control de manera sencilla) para hacer que el código cumpla con la guía los beneficios que aportará al proyecto serán muchos e importantes &lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-7276976674786233097?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/7276976674786233097/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=7276976674786233097' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7276976674786233097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/7276976674786233097'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/03/programando-con-estilo.html' title='Programando con estilo'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-3755338583316338357</id><published>2009-03-15T19:38:00.010+01:00</published><updated>2009-03-16T12:24:36.634+01:00</updated><title type='text'>Agile Open Buenos Aires</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1MT3X8eoI/AAAAAAAABvM/InTKcAEwywQ/s1600-h/agile-1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 211px; height: 282px;" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1MT3X8eoI/AAAAAAAABvM/InTKcAEwywQ/s320/agile-1.jpg" alt="" id="BLOGGER_PHOTO_ID_5313487039532661378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;El pasado 6 y 7 de Marzo tuve el placer de asistir al &lt;a href="http://www.agiles.org/agile-open-buenos-aires-2009"&gt;Agile Open Buenos Aires&lt;/a&gt;. Este evento, organizado por la &lt;a href="http://www.agiles.org/"&gt;comunidad latinoamericana de metodologías ágiles&lt;/a&gt;, se desarrolló en formato &lt;a href="http://www.agiles.org/agile-open-buenos-aires-2009/open-space"&gt;Open Space&lt;/a&gt; y fue sumamente interesante.&lt;br /&gt;&lt;br /&gt;El evento se dividió en dos sesiones. El primer día se dedicó a planear los temas de las charlas y el horario de las mismas y el segundo se dedicó a las charlas en sí.&lt;br /&gt;&lt;br /&gt;Lo primero que me gustaría destacar es la afluencia de público a estas sesiones. Debíamos ser unas cien personas hablando de metodologías ágiles! Sinceramente, a día de hoy no me imagino un evento de esta magnitud aquí en España. Espero que muy pronto, con el impulso que le estamos dando desde la &lt;a href="http://www.agile-spain.com/agilev2/"&gt;comunidad española&lt;/a&gt;, esto sea posible.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1OjIQb_8I/AAAAAAAABvU/Ix7J89EsRvk/s1600-h/agile-2.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 282px; height: 211px;" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1OjIQb_8I/AAAAAAAABvU/Ix7J89EsRvk/s320/agile-2.jpg" alt="" id="BLOGGER_PHOTO_ID_5313489500785868738" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Así pues nos encontramos cien personas el viernes por la tarde para hablar sobre metodologías ágiles. Nuestro facilitador fue &lt;a href="http://www.scrumalliance.org/profiles/4602-alan-e-cyment"&gt;Alan Cyment&lt;/a&gt;, ayudado en todo momento de su inseparable campana.&lt;br /&gt;&lt;br /&gt;Lo primero que hicimos fue proponer el tema de las charlas. Cada persona que quería que al día siguiente se hablara sobre algún tema, se levantaba, se ponía en el centro de la sala y exponía brevemente el tema. A mi, un poco acongojado por el nivelazo de la gente, me costó un poco decidirme, pero al final decidí alzarme y proponer la &lt;a href="http://www.codinghorror.com/blog/archives/001230.html"&gt;deuda tecnológica&lt;/a&gt; como tema a debatir. Es importante recalcar que la persona que propone la charla no tiene que ser un experto en el tema, simplemente tiene que tener ganas de debatir con otras personas sobre el mismo. Es más, hubo gente que propuso temas sobre los que no tenía ninguna idea ni experiencia y que querían hablar de ellos precisamente por esto, para empezar a conocerlos.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/Sb1QKLj-ndI/AAAAAAAABvc/sUyzp4T7Nqk/s1600-h/agile-3.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 282px; height: 211px;" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/Sb1QKLj-ndI/AAAAAAAABvc/sUyzp4T7Nqk/s320/agile-3.jpg" alt="" id="BLOGGER_PHOTO_ID_5313491271199661522" border="0" /&gt;&lt;/a&gt;Una vez hubimos propuesto todos los temas que consideramos interesantes empezamos con las votaciones. Cada uno de nosotros tenia cinco votos a repartir entre las propuestas que quisiera, pudiendo repetir votos si lo consideraba necesario. Mi propuesta tubo unos muy honrosos cinco votos :D&lt;br /&gt;&lt;br /&gt;Después de votar armamos la grilla ( como decían por Argentina ), es decir, establecimos el horario de cada una de las charlas. Es importante recalcar que todo esto lo hicimos los participantes, en ningún momento Alan o cualquier otro miembro de la organización participó activamente en esta organización. Así pues el resultado fue el que el público consideró más oportuno, tanto en temas a tratar, como en horarios. Se puede ser más ágil?&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1R982Qo-I/AAAAAAAABvs/GIwIxHLqcWE/s1600-h/agile-4.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1R982Qo-I/AAAAAAAABvs/GIwIxHLqcWE/s320/agile-4.jpg" alt="" id="BLOGGER_PHOTO_ID_5313493260114633698" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Cómo podéis ver mi charla quedó emplazada para las 9 de la mañana del día siguiente.&lt;br /&gt;&lt;br /&gt;Y al día siguiente, después de un buen desayuno, empezaron las charlas. La charla empezaba con una breve intervención de la persona que la había propuesto explicando las razones por las cuales lo había hecho. Y después empezaba un diálogo entre todos los asistentes donde cada uno daba su punto de vista, explicaba su experiencia, donde estaba fallando, donde lo hacía bien, etc. Aquí os pongo un breve resumen de las charlas a las que yo fui.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Deuda Tecnológica&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En esta charla discutimos por lo que entendíamos por deuda tecnológica. Llegamos a la conclusión que deuda tecnológica eran aquella deuda que se contrae cuando se decide hacer las cosas rápido para, por ejemplo, llegar a una entrega y que no cumplen con los estándares de calidad de nuestra organización, siendo susceptibles de impedir el futuro desarrollo de nuestro software. Ante esto se llegó a la conclusión de atacarla por distintos frentes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Intentar evitarla.&lt;/li&gt;&lt;li&gt;Reportar al cliente cuando se contrae la deuda para que esté informado que algún día se tendrá que arreglar el estropicio.&lt;/li&gt;&lt;li&gt;Se hizo incapié en que ser ágil es un ejercicio de honestidad.&lt;/li&gt;&lt;li&gt;Capacitar al equipo para minimizar la deuda que se contrae por culpa de malas implementaciones.&lt;/li&gt;&lt;li&gt;Mostrar al cliente el valor de no tener deuda técnica.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Cómo evangelizar a mi equipo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Esta charla fue propuesta por Nico para tratar el tema de aquellos miembros del equipo que no quieren seguir algún paso de la metodología porque no lo consideran oportuno. Aquí cada uno explicó sus batallitas sobre el tema y propuso algunas soluciones, o acciones que quizá pudieran servir. Aquí van algunas:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Que el Scrum Master haga aquello que estos miembros no quieren hacer para que se den cuenta que es importante.&lt;/li&gt;&lt;li&gt;Cuando se detecta alguna &lt;a href="http://www.wordreference.com/definicion/chanchada"&gt;barbaridad &lt;/a&gt;en el código, enviar un screenshot a todo el equipo.&lt;/li&gt;&lt;li&gt;Rotar los roles para que la gente vea que cuando no hace una cosa está molestando a un compañero.&lt;/li&gt;&lt;li&gt;Implementar un sistema de premios para cuando el equipo trabaja correctamente.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Trabajo ágil en entornos no ágiles&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En esta charla se habló de cómo trabajar de una manera ágil en empresas que no lo son, ya sea porque tienen una forma caótica de trabajar o porque tienen una forma demasiado rígida de hacerlo. Ante esta dificultad se propusieron diferentes soluciones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Internamente trabajar de forma ágil para cumplir los requerimientos no ágiles.&lt;/li&gt;&lt;li&gt;Adaptar el rol de Product Owner para que sea una especie de proxy entre la parte no ágil de la empresa y nuestro grupo de desarrollo.&lt;/li&gt;&lt;li&gt;Hablar con la gente no ágil con vocabulario no ágil ( fases, hitos, reunión de avance semanal, etc ).&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Product Backlog&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En esta charla hablamos de la creación y mantenimiento del Product Backlog. Aquí cada uno explicó cómo lo hacia él y qué problemas le surgían. Había desde la gente que hacía una mezcla de Scrum con &lt;a href="http://en.wikipedia.org/wiki/Lean_software_development"&gt;Lean &lt;/a&gt;o con &lt;a href="http://www.dosideas.com/metodologias/184-kanban-y-scrum.html"&gt;Kanban&lt;/a&gt;,  a la que no mantenía un burndown chart ni estimaba las tareas, etc. Esta charla fue interesante porque tubo la participación de &lt;a href="http://www.xqa.com.ar/visualmanagement/"&gt;Xavier Quesada&lt;/a&gt; que aprovechó la ocasión para introducir temas de otra charla sobre visual management que al final no pudo dar.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scrum distribuido&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Y para finalizar estuvo esta charla, en que la gente que tenia experiencia implantando Scrum en grupos distribuidos nos contó sus experiencias. Aquí la tecnología tiene un papel importante a la hora de guardar y mostrar la información del avance del proyecto. Desde softwares comerciales, a hojas de excel compartidas, videoconferencias, llamadas telefónicas a altas horas de la madrugada, etc.&lt;br /&gt;&lt;br /&gt;En definitiva fue una experiencia muy interesante. Cómo se comentó en la retrospectiva del evento, si alguna mente privilegiada del agilismo se hubiera puesto a pensar temas para una conferencia, seguramente no hubiera llegado al nivel que se llegó en este evento.&lt;br /&gt;&lt;br /&gt;Una vez más, agradecer a la comunidad argentina el buen trato recibido y aprovecho para mandar un saludo a todos ellos. Un placer!&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1RhjRN1gI/AAAAAAAABvk/eV033wMKfWE/s1600-h/agile-4.jpg"&gt;&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-3755338583316338357?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/3755338583316338357/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=3755338583316338357' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3755338583316338357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/3755338583316338357'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/03/agile-open-buenos-aires.html' title='Agile Open Buenos Aires'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ZaNkQuiMjcA/Sb1MT3X8eoI/AAAAAAAABvM/InTKcAEwywQ/s72-c/agile-1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-2385096663027244717</id><published>2009-03-10T09:42:00.035+01:00</published><updated>2009-03-12T13:27:33.961+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='product backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='user stories'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Definiendo historias de usuario en Scrum</title><content type='html'>Uno de los puntos que más interrogantes provocan en la gente que se acerca a Scrum es cómo dividir el desarrollo de un proyecto en historias de usuario, es decir en tareas lo más pequeñas posibles que aporten valor funcional al cliente.&lt;br /&gt;&lt;br /&gt;En este artículo voy a tratar de explicar el enfoque que yo adopto cuando trato de describir un requisito funcional cómo historia de usuario. Obviamente no es la única opción, ni la mejor, de echo es probable que esté pasando un montón de cosas por alto y que muchos se lleven las manos a la cabeza, pero creo que puede ser útil cómo primera aproximación para aquellas personas que no tengan del todo claro un procedimiento a seguir.&lt;br /&gt;&lt;br /&gt;Vamos a tomar cómo ejemplo un problema de la asignatura de Especificación de Software de la Facultad de Informática de Barcelona (&lt;a href="http://bibliotecnica.upc.es/edupc/locate4.asp?codi=IN019XXX"&gt;Enginyeria del Software: Especificació. Especificació de sistemes orientats a objectes amb la notació UML. EDICIONS UPC&lt;/a&gt;), que presenta el siguiente enunciado:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Se quiere desarrollar un sistema sencillo de control de préstamos en un a biblioteca. El sistema debe admitir el alta y la baja de socios y de libros. Los socios pueden pedir libros en préstamo, pero no se pueden tener más de tres libros en préstamo en un momento determinado. Los libros se han de devolver antes de un mes de la fecha del préstamo. Cada vez que un socio devuelve un libro después de la fecha de la devolución, se penaliza reduciendo en una unidad el número de libros que puede tener simultáneamente. Cuando llega a cero el socio se de de baja automáticamente.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ahora supongamos que este problema nos lo ha planteado nuestro cliente, que quiere que le construyamos exactamente el sistema descrito en el enunciado ¿Cómo llegamos desde el mismo, a la lista de tareas del backlog? Por el momento vamos a obviar aquellas tareas que a simple vista no aportan valor al cliente pero que son del todo necesarias para el proyecto (definir e implementar la arquitectura del sistema por ejemplo) y vamos a centrarnos únicamente en los objetivos funcionales.&lt;br /&gt;&lt;br /&gt;Lo que vamos a hacer va a ser un “clásico” análisis de requerimientos, intentando extraer del texto (lo que nos dice el cliente) las diferentes funcionalidades que debe tener el sistema. Para ello analizamos los párrafos del texto. A simple vista podemos extraer las siguientes funcionalidades:&lt;br /&gt;&lt;br /&gt;De la siguiente frase: &lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;El sistema debe admitir el alta y la baja de socios y de libros&lt;/span&gt;&lt;/span&gt; extraemos las siguientes posibles historias de usuario:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Alta Libro&lt;/li&gt;&lt;li&gt;Baja Libro&lt;/li&gt;&lt;li&gt;Alta Socio&lt;/li&gt;&lt;li&gt;Baja Socio&lt;/li&gt;&lt;/ul&gt;Del párrafo siguiente: &lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Los socios pueden pedir libros en préstamo, pero no se pueden tener mas de tres libros en préstamo en un momento determinado&lt;/span&gt;&lt;/span&gt; obtenemos una única funcionalidad o historia&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Préstamo libro&lt;/li&gt;&lt;/ul&gt;En este párrafo: &lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;Los libros se han de devolver antes de un mes de la fecha del préstamo. Cada vez que un socio devuelve un libro después de la fecha de la devolución, se penaliza reduciendo en una unidad el número de libros que puede tener simultáneamente&lt;/span&gt;&lt;/span&gt; creo que podrían identificarse dos historias (es mi opinión, quizás otra gente opine que sólo hay una posible historia)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Devolver libro&lt;/li&gt;&lt;li&gt;    Penalizar socio&lt;/li&gt;&lt;/ul&gt;En el último párrafo obtenemos otra posible historia: &lt;span style="font-style: italic;font-size:85%;" &gt;Cuando llega a cero el socio se de de baja automáticamente&lt;/span&gt;. Aunque pueda parecer que es una historia repetida, yo considero que a nivel de valor al cliente es una funcionalidad diferente.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Baja automática de socio&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Aparte de las historias que aparecen más o menos explícitas en el código, quizás podrían deducirse otras historias cómo:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Iniciar sesión en el sistema&lt;/li&gt;&lt;li&gt;    Cerrar sesión&lt;/li&gt;&lt;li&gt;    Alta usuario&lt;/li&gt;&lt;li&gt;    Baja usuario&lt;/li&gt;&lt;/ul&gt;La lista completa de historias que tendríamos sería la siguiente:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;    Alta libro&lt;/li&gt;&lt;li&gt;    Baja libro&lt;/li&gt;&lt;li&gt;    Alta socio&lt;/li&gt;&lt;li&gt;    Baja socio&lt;/li&gt;&lt;li&gt;    Préstamo de libro&lt;/li&gt;&lt;li&gt;    Devolver libro&lt;/li&gt;&lt;li&gt;    Penalizar socio&lt;/li&gt;&lt;li&gt;    Baja automática de socio&lt;/li&gt;&lt;li&gt;    Iniciar sesión en el sistema&lt;/li&gt;&lt;li&gt;    Cerrar sesión&lt;/li&gt;&lt;li&gt;    Alta usuario&lt;/li&gt;&lt;li&gt;    Baja usuario&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Si estuviéramos en una metodología clásica de desarrollo, en este punto deberíamos hacer los casos de uso para los requerimientos identificados, sus diagramas de secuencia, etc. En una metodología cómo Scrum, por definición, no es necesaria esta documentación (queda a elección de cada uno decidir que documentación necesita su proyecto) y lo que nos quedaría por hacer es definir e introducir las historias en el backlog. ¿Y cómo se define una funcionalidad en forma de historia de usuario? Pues la idea es expresarla desde el punto de vista del cliente, o del usuario que va a usar el sistema, con un lenguaje que pueda ser entendido perfectamente por ellos (nada de UML, OCL o demás lenguajes de especificación) y que no cree ambigüedades. Por ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Historia&lt;/span&gt;: Préstamo de libro&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ID&lt;/span&gt;: 5&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Descripción&lt;/span&gt;: Cómo cliente quiero que los socios puedan pedir prestado un libro, indicando su número de socio y la referencia del libro, siempre y cuando no tengan ya tres libros en préstamo en ese momento.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Importancia&lt;/span&gt;: 300&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cómo probarlo&lt;/span&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Introducir un número de socio incorrecto y comprobar que se indica error&lt;/li&gt;&lt;li&gt;Introducir un socio que ya tiene 3 libros en préstamo y comprobar que se indica error&lt;/li&gt;&lt;li&gt;Introducir un libro del que no hay ejemplares y comprobar que se indica un error&lt;/li&gt;&lt;li&gt;Introducir todos los datos correctos y comprobar que el número de ejemplares disponibles del libro disminuye y el número de préstamos del socio aumenta en uno.&lt;/li&gt;&lt;/ul&gt;Cómo vemos, en Scrum se detalla de manera poco explícita la funcionalidad, únicamente se explica a nivel de cliente. La ventaja es que no se fijan los detalles de la implementación hasta el momento en que se va a realizar (en la descomposición en tareas) con lo que se puede reaccionar más ágilmente ante los cambios de los requisitos o de las necesidades del cliente.&lt;br /&gt;&lt;br /&gt;Haciendo lo mismo con las demás funcionalidades, nos quedaría un product backlog similar al siguiente (se ha obviado la parte de test de las historias):&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:worddocument&gt;   &lt;w:view&gt;Normal&lt;/w:View&gt;   &lt;w:zoom&gt;0&lt;/w:Zoom&gt;   &lt;w:hyphenationzone&gt;21&lt;/w:HyphenationZone&gt;   &lt;w:punctuationkerning/&gt;   &lt;w:validateagainstschemas/&gt;   &lt;w:saveifxmlinvalid&gt;false&lt;/w:SaveIfXMLInvalid&gt;   &lt;w:ignoremixedcontent&gt;false&lt;/w:IgnoreMixedContent&gt;   &lt;w:alwaysshowplaceholdertext&gt;false&lt;/w:AlwaysShowPlaceholderText&gt;   &lt;w:compatibility&gt;    &lt;w:breakwrappedtables/&gt;    &lt;w:snaptogridincell/&gt;    &lt;w:wraptextwithpunct/&gt;    &lt;w:useasianbreakrules/&gt;    &lt;w:dontgrowautofit/&gt;   &lt;/w:Compatibility&gt;   &lt;w:browserlevel&gt;MicrosoftInternetExplorer4&lt;/w:BrowserLevel&gt;  &lt;/w:WordDocument&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;  &lt;w:latentstyles deflockedstate="false" latentstylecount="156"&gt;  &lt;/w:LatentStyles&gt; &lt;/xml&gt;&lt;![endif]--&gt;&lt;style&gt; &lt;!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal  {mso-style-parent:"";  margin:0cm;  margin-bottom:.0001pt;  mso-pagination:widow-orphan;  font-size:12.0pt;  mso-bidi-font-size:10.0pt;  font-family:"Times New Roman";  mso-fareast-font-family:"Times New Roman";  mso-ansi-language:EN-US;} @page Section1  {size:612.0pt 792.0pt;  margin:70.85pt 3.0cm 70.85pt 3.0cm;  mso-header-margin:36.0pt;  mso-footer-margin:36.0pt;  mso-paper-source:0;} div.Section1  {page:Section1;} --&gt; &lt;/style&gt;&lt;!--[if gte mso 10]&gt; &lt;style&gt;  /* Style Definitions */  table.MsoNormalTable  {mso-style-name:"Tabla normal";  mso-tstyle-rowband-size:0;  mso-tstyle-colband-size:0;  mso-style-noshow:yes;  mso-style-parent:"";  mso-padding-alt:0cm 5.4pt 0cm 5.4pt;  mso-para-margin:0cm;  mso-para-margin-bottom:.0001pt;  mso-pagination:widow-orphan;  font-size:10.0pt;  font-family:"Times New Roman";  mso-ansi-language:#0400;  mso-fareast-language:#0400;  mso-bidi-language:#0400;} &lt;/style&gt; &lt;![endif]--&gt;  &lt;table class="MsoNormalTable" style="border: medium none ; margin-left: 4.05pt; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0"&gt;  &lt;tbody&gt;&lt;tr style=""&gt;   &lt;td style="border: 1pt solid black; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Historia&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Importancia&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: solid solid solid none; border-color: black black black -moz-use-text-color; border-width: 1pt 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Descripción&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Alta libros&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;600&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de alta un   libro en el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Baja libros&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;250&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de baja un   libro del sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Alta socio&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;500&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de alta un   socio en el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Baja socio&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;300&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de baja un   socio del sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Pedir libro&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;350&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Pedir prestado un   libro&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Devolver libro&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;340&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Devolver un libro&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Penalización socio&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;330&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Penalizar al socio   por retrasarse en la devolución&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Baja automática&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;320&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de baja   automáticamente de socio&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Iniciar sesión en   el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;550&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Iniciar una sesión   de usuario en el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Cerrar sesión&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;500&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Terminar sesión con   el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Alta usuario&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;450&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de alta un   nuevo usuario en el sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt;  &lt;tr style=""&gt;   &lt;td style="border-style: none solid solid; border-color: -moz-use-text-color black black; border-width: medium 1pt 1pt; padding: 0cm 3.5pt; width: 106.5pt;" valign="top" width="142"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Baja usuario&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 65pt;" valign="top" width="87"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;400&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;   &lt;td style="border-style: none solid solid none; border-color: -moz-use-text-color black black -moz-use-text-color; border-width: medium 1pt 1pt medium; padding: 0cm 3.5pt; width: 260.7pt;" valign="top" width="348"&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style="font-size: 10pt; color: black;"&gt;Dar de baja un   usuario del sistema&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;   &lt;/td&gt;  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt;  &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;En este punto tenemos identificadas todas las tareas funcionales del proyecto, y se ha descrito cada una de ellas cómo una historia de usuario.&lt;br /&gt;&lt;br /&gt;Aunque ya tenemos completa la lista de funcionalidades, es obvio que el product backlog tal y como está no es suficiente para poder avanzar en el proyecto, ya que no aparecen todas aquellas tareas que no son funcionales (historias técnicas, requisitos no funcionales o como se le quieran llamar) pero que son necesarias para el desarrollo del proyecto. Pero la mayoría de estas tareas no aportan valor al cliente, entonces ¿Se deben incluir estas tareas en el backlog? ¿Y de que manera? No vamos a discutir en este artículo el tema, ya que daría para muchos posts, pero a modo de apunte se podría gestionar de la siguiente forma:&lt;br /&gt;&lt;br /&gt;En proyectos que se están iniciando, es fácilmente justificable introducir tareas técnicas o no funcionales, ya que sin ellas el proyecto no existe. Así bajo la forma de Epics (o super historias de usuario) se podrían englobar tareas tales cómo Implementar la capa de datos, implementar la capa de comunicaciones, etc. Estas tareas se llevarían a cabo en las primeras iteraciones, o incluso en una primera iteración mayor que las otras.&lt;br /&gt;&lt;br /&gt;En fases más avanzadas del proyecto, es difícil justificar tareas no funcionales, cómo la refactorización de módulos, instalación de servidores de pruebas, etc. Ya que el cliente querrá priorizar aquellas historias que le aporten valor. En este caso lo ideal es intentar que el cliente comprenda la importancia de las tareas a realizar, o si eso no es posible utilizar otras técnicas, cómo introducirlas dentro de alguna de las historias de usuario, o mantener una lista separada de historias técnicas con un porcentaje de tiempo no negociable con el dueño de producto.&lt;br /&gt;&lt;br /&gt;Cómo hemos visto el proceso de definir historias de usuario es tan simple (o tan complicado) cómo realizar un análisis de requerimientos, proceso para el cual no hay ningún truco infalible y dependerá en gran medida de la experiencia y pericia del analista o analistas que se encarguen de él, y expresar las funcionalidades resultantes del análisis en un lenguaje que pueda ser fácilmente entendido por el cliente de nuestro proyecto.&lt;br /&gt;&lt;br /&gt;Por si queréis ampliar información os dejo algunos links interesantes sobre Historias de Usuario i Scrum (o Agile en general). Esperamos vuestros comentarios!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/User_story"&gt;http://en.wikipedia.org/wiki/User_story&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.userstories.com/"&gt;http://www.userstories.com/&lt;/a&gt;&lt;br /&gt;http://www.joelonsoftware.com/articles/fog0000000036.html&lt;br /&gt;&lt;a href="http://ezinearticles.com/?Scrum-User-Stories&amp;amp;id=1605892"&gt;http://ezinearticles.com/?Scrum-User-Stories&amp;amp;id=1605892&lt;/a&gt;&lt;br /&gt;&lt;a href="http://scrummethodology.com/scrum-user-stories/"&gt;http://scrummethodology.com/scrum-user-stories/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://kanemar.com/2006/09/09/writing-user-stories/"&gt;http://kanemar.com/2006/09/09/writing-user-stories/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-2385096663027244717?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/2385096663027244717/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=2385096663027244717' title='9 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2385096663027244717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/2385096663027244717'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/03/definiendo-historias-de-usuario-en.html' title='Definiendo historias de usuario en Scrum'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-1791979408213828347</id><published>2009-02-12T12:30:00.004+01:00</published><updated>2009-02-12T12:40:20.848+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='experiencias'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><title type='text'>Experiéncias implantando SCRUM</title><content type='html'>&lt;div style="text-align: justify;"&gt;En este artículo vamos a tratar de explicar nuestra experiéncia implantando Scrum y prácticas ágiles en general en nuestro proceso de desarrollo de software. Hemos divido el artículo en diferentes capítulos que explican cada una de las fases por las que hemos pasado. Esperemos que nuestra experiéncia os ayude de alguna manera. Nos gustaría remarcar que hablamos en nombre de todo el grupo de trabajo, que ha sido el que, trabajando todos unidos en una misma dirección, ha tirado adelante esta história.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ANÁLISIS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Después de un par de años trabajando en nuestra empresa, vimos que necesitábamos una manera mejor de trabajar. El equipo era demasiado especializado, cada persona tenía conocimiento sobre áreas muy concretas del sistema y esto penalizaba mucho las ausencias de algunas personas. Además a pesar de que al principio  se trabajaba de manera relativamente tranquila poco a poco, a medida que los clientes aumentaban, la dinámica fue degenerando hasta convertir el trabajo diario en un “apaga fuegos”, solucionando bugs de anteriores versiones, dando asistencia, y intentado desarrollar nuevas funcionalidades en tiempo récord. Además existía una paralelización excesiva de las tareas (se empezaban muchas de golpe y pocas se acababan en un tiempo razonable ), los requisitos cambiaban con facilidad al igual que las prioridades y había poca comunicación entre el equipo, tanto de las tareas que realizaba cada uno cómo del conocimiento. Algo que si que teníamos era un seguimiento del trabajo exhaustivo por parte de nuestra responsable, que también estaba preocupada por mejorar nuestra manera de trabajar.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DESCUBRIMIENTO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Una vez que vimos que teníamos que buscar otra manera de trabajar, fuimos investigando por foros de internet, páginas web, experiéncias de conocidos hasta encontrar un documento que cambió completamente nuestra visión del desarrollo. El documento es el conocido &lt;a href="http://www.proyectalis.com/2008/02/26/scrum-y-xp-desde-las-trincheras/"&gt;“Scrum y XP desde las trincheras”&lt;/a&gt; y en él descubrimos conceptos tan importántes como Scrum, Integración Contínua o testeo unitário. Algunos de estos conceptos era nuevos para nosotros, otros ya los conocíamos pero no eramos conscientes del impacto que podían tener en nuestro día a día. El echo de conocer la experiéncia de gente que trabajaba en proyectos grandes e importantes y que consideraban esto vital, nos dio el empujón definitivo para emprender esta aventura.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PRIMEROS PASOS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cuando tuvimos claro por donde tirar empezamos ha hacer una prueba piloto con un grupo reducido de personal, en concreto tres personas. Lo primero que hicimos fue montar un repositorio de código (con Subversion) y empezar a utilizar Scrum para nuestra organización interna, todo esto a espaldas de nuestros jefes. Antes de llenarle la cabeza con ideas “extrañas y novedosas” que pudieran provocar su rechazo creímos conveniente experimentar por nuestra cuenta un tiempo, para intentar mostrarles algo sólido, con técnicas ya probadas y con resultados que respaldaran nuestra idea.&lt;br /&gt;&lt;br /&gt;Nuestros primeros pasos con Scrum consisitieron básicamente en aglutinar una serie de tareas (o historias) que teniamos en cola (¿product backlog?) , priorizarlas , realizar la división en subtareas , hacer una estimación (utilizando planning poker) y la realización de las reuniones diarias.&lt;br /&gt;&lt;br /&gt;Aunque era todo muy “precario”, nuestra primera impresión con Scrum fue muy positiva. De tener a un equipo al que tan sólo se le controlaba la faena a intervalos relativamente grandes de tiempo, con la consiguiente tardanza en aplicar cambios de diseño o requerimientos y la lentitud en detectar errores, pasamos a tener un equipo que cada día compartía la información del trabajo realizado y al que era muy fácil orientar a resultados. Por otra parte, la utilización de un repositorio de código hacía que se eliminaran las tediosas sesiones de juntar versiones de diferentes programadores, ejercicio que era un generador de bugs terrible.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;EXPANDIENDO LA SEMILLA&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Una vez vimos que ibamos por la senda correcta, y que Scrum podia ayudarnos a mejorar nuestro trabajo, nos dispusimos a introducir el gusanillo de las metodologías ágiles al resto del grupo de desarrolladores, todavía a espaldas de nuestros responsables. No queríamos decirles nada hasta ver que esta técnica era válida para un grupo grande de personas, aunque nuestra responsable directa ya supiera algo de todo esto, pués es complicado esconder ciertas cosas. Cómo queríamos que el grupo se sintiera implicado en la toma de la decisión y no queríamos imponer nada, hicimos una presentación al grupo mostrándoles la manera de trabajar que teníamos ahora con nuestros diferentes gestores y a la vez explicando cómo contrapunto la gestión que se podría llevar a cabo con una metodología ágil (en concreto Scrum). Una vez acabada la presentación les preguntamos si creían que la manera actual de trabajar era una buena manera y, obviamente, la respuesta fue negativa; todo el mundo creía que se podían hacer las cosas mejor, que nuestra gestión del tiempo era deficitária y que el hecho que la toma de decisiones se centrara en nuestra responsable, que por su parte tenía un exceso de trabajo, hacía que el desarrollo se viera penalizado. Por suerte nuestra, esto coincidió con la decisión de nuestra responsable de delegar todo el trabajo que tenía que ver con desarrollo en nuestras manos, decisión que vino apoyada por el hecho que viera que teníamos capacidad para autoorganizarnos. Así que decidimos proponer al grupo un cambio en la manera de trabajar, básicamente centrandonos en dos aspectos:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Desarrollo: Les propusimos empezar a utilizar buenas prácticas de programación de manera conjunta y coordinada -&gt; Instauranado el repositorio de código y enseñando cómo utilizarlo, creando una guía de estilo para homegenizar el código de todo el departamento, instaurando el testeo unitario, configurando un servidor de integración contínua, etc.&lt;/li&gt;&lt;li&gt;Gestión: Les propusimos instaurar Scrum como nuestra metodología de trabajo.&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;De esta manera empezamos nuestros primeros sprints. Al principio nos centramos en las reuniones de inicio de sprint, en los seguimientos diários y en pequeñas retrospectivas muy básicas. La reacción del grupo fue muy positiva y poco a poco empezamos con las demostraciones internas, aunque esto todavía tenemos que mejorarlo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IMPULSO DEFINITIVO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;El impulso definitivo ha sido la participación de nuestra jefa en todo el proceso de Scrum, principalmente en la reunión de inicio de sprint y en las demostraciones y retrospectivas. Esto ha sido muy importante para poder definir de manera más detallada las tareas a realizar, para la decisión de que entra y que no entra en cada sprint y, sobretodo, en que viera que somos un grupo que trabaja unido para obtener resultados. Ha sido también vital hacerle ver que la parelización de tareas es contraproducente y tan sólo lleva a tener muchas tareas sin acabar al final del sprint ( que es lo que nos pasaba en los primeros sprints ). Ahora todo el equipo se centra en una historia de usuario ( a lo sumo dos ) y a final de sprint siempre podemos mostrar un producto con incremento de valor sobre la iteración anterior.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;IMPEDIMENTOS&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Son muchos los impedimentos que nos hemos ido encontrado a lo largo de nuestra aventura, y seguramente nos encontraremos muchos más. Vamos a intentar exponer en forma de lista los que consideramos más importantes:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Dificultad a la hora de estimar: Aunque cada dia afinamos más, todavía nos falta un buen trecho para llegar a hacer buenas estimaciones de las histórias de usuario. Esto normalmente se vé reflejado en que conseguimos realizar menos histórias de las previstas. Afortunadamente, el hecho de que ultimamente el equipo se centre en menos histórias a la vez ha hecho que se minimice el impacto de este impedimento.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;El equipo no sólo se dedica a programar. Nuestro equipo no es un equipo de desarrollo al 100%. También hace testeo, instalación en el cliente, resolución de incidencias, etc. Esto hace que nuestras estimaciones se vean penalizadas por una carga de trabajo no previsto que retrasa el desarrollo.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Incompresión por parte de otros gestores. La respuesta de nuestra jefa a nuestra propuesta ha sido espléndida, nos apoya al 100% e intenta colaborar en todo lo posible, pero no sólo trabajamos con ella. El hecho que haya en nuestra empresa gente con mentalidad tradicional respecto al desarrollo de software (o incluso sin ninguna mentalidad), hace que a veces choquemos frontalmente con su forma de dirigir los proyectos y que sea complicado realizar nuestro proceso productivo tal cómo nos gustaría.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Respeto a las iteraciones: En ocasiones no hemos podido llevar a cabo sprints completos, debido a “grandes marrones” que llevaban tiempo aparcados y que de golpe se deben solucionar, cambiando de un día para otro (a veces justo al dia siguiente de la reunión de inicio) todas las tareas programadas.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Grandes aprendizajes. Todos nosotros somos nuevos en el mundo de la gestión de proyectos informáticos y, aunque intentamos aplicar todas las técnicas de manera razonable y a pasos pequeños, hay muchas cosas que aprender, tanto técnicas ( a configurar un servidor de integración continua, a programar con testeo unitario, a relizar testeo funcional, etc ) como metodológicas. Por suerte, cada vez tenemos más experiéncia y vamos dando pasos más grandes y seguros.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Reticencia de algunos desarrolladores. Algunos desarrolladores veían algunas de estas técnicas como algo que disminuía su velocidad de trabajo, cosa que se veía reforzada por el hecho de trabajar con los gestores tradicionales que antes comentábamos. Aquí nuestra tarea “evangelizadora” ha sido importante, haciendo charlas, propiendo lecturas, analizando artículos, etc. Al final, hemos podido convencer a todo el mundo y esto se ha notado en el dia a dia.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Dificultad para realizar algunas prácticas: Aunque parezca increíble, practicas básicas de Scrum cómo poder estar sentado todo el equipo junto, o tener una sala con el panel de scrum donde poder realizar las reuniones diarias son “difíciles” de llevar  a cabo en algunas empresas. &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;EL FUTURO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Creemos que el futuro que nos espera va a ser mucho mejor. Todavía tenemos muchas cosas que mejorar: demostraciones, retrospectivas, reuniones de incio…  La preparación de las demostraciones nos llevan mucho tiempo (ganar experiéncia con nuestra herramienta de ALM nos ayudará mucho ) y tenemos poco tiempo para hacer buenas retrospectivas.&lt;br /&gt;&lt;br /&gt;Esperamos también aumentar la visibilidad de nuestro proceso y hacerlo extensivo a toda nuestra sección, hacer más públicas nuestras demostraciones ( por ahora internas ), dar permiso a todo el mundo para que vean el avance de nuestro proyecto via web con los diferentes reportes ( tablero de scrum, burndown, tasa de resolución de bugs, etc ) e intentar impregnar al resto del departamento o incluso de la empresa de nuestra filosofía de trabajo.&lt;br /&gt;&lt;br /&gt;También esperamos que nuestros desarrollos sean cada vez más estables gracias a la incorporación masiva del testeo unitario, la integración contínua, mejora en los procesos de testeo, etc. Esto hará que las interrupciones en el desarrollo por la irrupción de bugs también sea menor. El hecho de tener  sistemas más estable también hará que podamos delegar trabajo de instalación y mantenimiento a otras secciones de nuestra empresa, ganando así tiempo para desarrollar más y mejor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;CONCLUSIONES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cómo conclusión podemos decir que nuestra experiencia con las metodologías ágiles en general y con Scrum en particular está siendo muy positiva, tanto en el ámbito personal cómo en el profesional (mejora en el trabajo diario al disminuir los impedimentos, alineación con el cliente para alcanzar objetivos, focalización en incremento de valor…). También es importante tener claro que Scrum y las metodologías ágiles en general no son una bala de plata. Son metodologías que requieren de un esfuerzo “extra” a corto plazo por parte de todos los roles implicados en el desarrollo del proyecto (esfuerzo que es posible que algunas personas no estén dispuestas a pagar) y que requieren de un contexto apropiado para su buen funcionamiento (hay tipos de proyectos que difícilmente encajarían en Scrum). Cómo dice Rodrigo Corral en este &lt;a href="http://geeks.ms/blogs/rcorral/archive/2007/06/06/nadie-dijo-que-no-exigiese-un-esfuerzo.aspx"&gt;artículo &lt;/a&gt; “nadie dijo que no exigiera un esfuerzo”.&lt;br /&gt;&lt;br /&gt;Por nuestra parte os animamos de manera entusiasta a que hagáis el esfuerzo de conocer Scrum porque el esfuerzo vale realmente la pena.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-1791979408213828347?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/1791979408213828347/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=1791979408213828347' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1791979408213828347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/1791979408213828347'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2009/02/en-este-articulo-vamos-tratar-de.html' title='Experiéncias implantando SCRUM'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-5824510941637542087</id><published>2008-12-09T15:29:00.008+01:00</published><updated>2009-02-03T16:18:41.914+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='gestión de proyectos'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum master'/><category scheme='http://www.blogger.com/atom/ns#' term='product backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint'/><category scheme='http://www.blogger.com/atom/ns#' term='tablero scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='burndown chart'/><title type='text'>Cómo interpretar un burndown chart</title><content type='html'>En el art&lt;/span&gt;&lt;span style="font-family:Calibri;"&gt;í&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;culo de hoy veremos cómo po&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;demos interpretar los diferentes tipos de &lt;a href="http://devnettips.blogspot.com/2008/11/scrum-ii.html"&gt;Burndown Charts&lt;/a&gt; que nos podemos encontrar en nuestro dia a dia. Como ya hemos visto en &lt;a href="http://devnettips.blogspot.com/2008/11/scrum-ii.html"&gt;artículos anteriores&lt;/a&gt; el &lt;a href="http://devnettips.blogspot.com/2008/11/scrum-ii.html"&gt;Sprint Burndown Chart&lt;/a&gt; es una herramienta muy útil para saber cómo va la evolución de nuestro proyecto de un solo vistazo. Así pués, es importante saber interpretar la información que nos dá para poder a&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;ctuar en consecuencia.&lt;/span&gt; &lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;&lt;?xml:namespace prefix = o /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;?xml:namespace prefix = v /&gt;&lt;v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" preferrelative="t" spt="75" coordsize="21600,21600"&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;v:f eqn="sum @10 21600 0"&gt;&lt;/v:f&gt;&lt;v:path connecttype="rect" gradientshapeok="t" extrusionok="f"&gt;&lt;o:lock aspectratio="t" ext="edit"&gt;&lt;/v:shapetype&gt;&lt;v:shape id="_x0000_s1026" type="#_x0000_t75"&gt;&lt;v:imagedata title="sbc-ideal" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image001.gif"&gt;&lt;w:wrap type="square"&gt;&lt;/v:shape&gt;&lt;/p&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;/o:lock&gt;&lt;/v:path&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;/v:stroke&gt;&lt;p class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_ZaNkQuiMjcA/ST6BGjMrwkI/AAAAAAAABtg/3Wj6OGNs-hY/s1600-h/sbc-ideal.png"&gt;&lt;img style="MARGIN: 0pt 10px 10px 0pt; WIDTH: 300px; FLOAT: left; HEIGHT: 300px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5277797762852438594" border="0" alt="" src="http://2.bp.blogspot.com/_ZaNkQuiMjcA/ST6BGjMrwkI/AAAAAAAABtg/3Wj6OGNs-hY/s320/sbc-ideal.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;Este es u&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;n burndow&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;n cha&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;rt i&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;deal. Sinceramente, nunca &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;he visto uno así en la realidad : ). Es a lo que tendria que tender el equipo. Este BC indica que las estimaciones de tiempo se hicieron bien, que el equi&lt;/span&gt; &lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;po ha podido trabajar y avanzar cada dia a la velocidad esperada y que&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt; a final de sprint se han conseguido realizar todos los puntos de historia planeados. Esto no quiere decir que el equipo no haya tenido impe&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;dimentos, pero si &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;que indican que estos havian estado previ&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;stos en la estimación inicial, y que estos no han parado a todo el equipo, ya que cada dia se ha vi&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;sto&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt; un avance. También indica que la separación en tareas ha sido buena, pudiendo definir tareas cortas que han significado un avance diario. Esto es lo que nos gustaria llegar a todos y por lo que tenemos que luchar.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;v:imagedata title="sbc-sobreestimado" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image002.gif"&gt;&lt;w:wrap type="square"&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;&lt;br /&gt;&lt;/span&gt; &lt;/p&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;p class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_ZaNkQuiMjcA/ST6BYDq6KvI/AAAAAAAABto/VqXUsycNQQU/s1600-h/sbc-sobreestimado.PNG"&gt;&lt;img style="MARGIN: 0pt 10px 10px 0pt; WIDTH: 300px; FLOAT: left; HEIGHT: 300px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5277798063626922738" border="0" alt="" src="http://3.bp.blogspot.com/_ZaNkQuiMjcA/ST6BYDq6KvI/AAAAAAAABto/VqXUsycNQQU/s320/sbc-sobreestimado.PNG" /&gt;&lt;/a&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;Este BC lo que indica es &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;que no se ha podido rea&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;lizar toda la faena planificada, ni se ha modificado el sprint backlog para intentarlo&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;. Este es un caso extremo ( se realiza un 10% de la faena ) pero es un tipo de BC que se suele dar. Las causas de este tipo de BC pueden ser varias: una mala estimación del sprint ( sobreestimación ), muchos impedimentos a lo largo del sprint, disminución del trabajo del equipo por enfermedad o similar, etc. Lo preocupante de este BC es que nadie ha hecho nada para intentar mejorarlo. Ni se han quitado los i&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;mpedimentos, ni se ha reducido la carga de trabajo, ni se ha augmentado el equipo de trabajo. Un BC de este tipo tendria que hacer reflexionar tanto al grupo de trabajo ( ¿Qué les pasa a nuestras estimaciones? ) como al Scrum &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;Master y al product owner ( ¿Porqué no he reaccionado a tiempo? ). Claramente es un BC a evitar.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;v:imagedata title="sbc-sobreestimado-con-intervencion" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image003.gif"&gt;&lt;w:wrap type="square"&gt; &lt;/p&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;p class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_ZaNkQuiMjcA/ST6Bl31pYUI/AAAAAAAABtw/PAry5SArkNk/s1600-h/sbc-sobreestimado-con-intervencion.PNG"&gt;&lt;img style="MARGIN: 0pt 10px 10px 0pt; WIDTH: 300px; FLOAT: left; HEIGHT: 300px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5277798300968902978" border="0" alt="" src="http://1.bp.blogspot.com/_ZaNkQuiMjcA/ST6Bl31pYUI/AAAAAAAABtw/PAry5SArkNk/s320/sbc-sobreestimado-con-intervencion.PNG" /&gt;&lt;/a&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;Este BC &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;ya nos gusta un poco más. El inicio del sprint es igual de malo que el anterior, pero a mitad de sprint el equipo ha visto que iba por mal camino. El descenso abrupto a mitad de&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt; sprint suele indicar que el product owner ha decidido sacar alguna história del sprint para intentar llegar a final de sprint de la mejor manera posible. También indica que se han eliminado impedimentos, ya que en la segunda parte del sprint el equipo avanza a una mayor velocidad. Es importante este tipo de modificaciones porque un escenario como el anterior deprime al equipo y este se pasa la mitad del sprint sabiendo que &lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;no se llegará al objetivo del sprint, cosa que puede hacer que su velocidad decaiga todavía más. Ayudando al equipo a poder cump&lt;/span&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;lir con el objetivo del sprint, lo que ha hecho el &lt;a href="http://devnettips.blogspot.com/2008/10/scrum-i.html"&gt;product owner&lt;/a&gt; ( seguramente orientado por el &lt;a href="http://devnettips.blogspot.com/2008/10/scrum-i.html"&gt;scrum master&lt;/a&gt; ) ha sido mantener el equipo involucrado al 100% en conseguir el objetivo del sprint.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;v:imagedata title="sbc-infraestimado-con-intervencion" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image004.gif"&gt;&lt;w:wrap type="square"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_ZaNkQuiMjcA/ST6CDnGp7RI/AAAAAAAABt4/VxLg723dbuI/s1600-h/sbc-infraestimado-con-intervencion.PNG"&gt;&lt;img style="MARGIN: 0pt 10px 10px 0pt; WIDTH: 300px; FLOAT: left; HEIGHT: 300px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5277798811872914706" border="0" alt="" src="http://4.bp.blogspot.com/_ZaNkQuiMjcA/ST6CDnGp7RI/AAAAAAAABt4/VxLg723dbuI/s320/sbc-infraestimado-con-intervencion.PNG" /&gt;&lt;/a&gt;&lt;span lang="ES-TRAD"  style="font-family:Calibri;"&gt;Este BC puede llegar a dar información tan negativa cómo el segundo que hemos visto. Si vemos un BC cómo este no tenemos porque pensar que somos los mejores desarrolladores del mundo, lo que tenemos que pensar es que es que también hemos estimado mal, y es prácticamente tan malo sobreestimar como infraestimar. Es importante que el equipo pueda hacer estimaciones realistas y que se cumplan los objetivos del sprint. De todas maneras, ni que sea por la imagen exterior que se dá, siempre es mejor este tipo de escenario que no un escenario de sobreestimación, ya que este último dá mala imagen del equipo. En el caso que el equipo consiguiera el mismo incremento de valor tanto en el escenario de sobreestimación como en este, la imagen del equipo es mucho mejor en este. Como se puede ver al final el equipo ha decidido añadir tareas de las no planificadas al sprint actual.&lt;/span&gt;&lt;/p&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;br /&gt;&lt;v:stroke joinstyle="miter"&gt;&lt;v:formulas&gt;&lt;v:f eqn="if lineDrawn pixelLineWidth 0"&gt;&lt;v:f eqn="sum @0 1 0"&gt;&lt;v:f eqn="sum 0 0 @1"&gt;&lt;v:f eqn="prod @2 1 2"&gt;&lt;v:f eqn="prod @3 21600 pixelWidth"&gt;&lt;v:f eqn="prod @3 21600 pixelHeight"&gt;&lt;v:f eqn="sum @0 0 1"&gt;&lt;v:f eqn="prod @6 1 2"&gt;&lt;v:f eqn="prod @7 21600 pixelWidth"&gt;&lt;v:f eqn="sum @8 21600 0"&gt;&lt;v:f eqn="prod @7 21600 pixelHeight"&gt;&lt;v:path connecttype="rect" gradientshapeok="t" extrusionok="f"&gt;&lt;o:lock aspectratio="t" ext="edit"&gt;&lt;v:imagedata title="sbc-ideal" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image001.gif"&gt;&lt;?xml:namespace prefix = w /&gt;&lt;w:wrap type="square"&gt;&lt;v:imagedata title="sbc-sobreestimado" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image002.gif"&gt;&lt;w:wrap type="square"&gt;&lt;v:imagedata title="sbc-sobreestimado-con-intervencion" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image003.gif"&gt;&lt;w:wrap type="square"&gt;&lt;v:imagedata title="sbc-infraestimado-con-intervencion" src="file:///C:\DOCUME~1\vgaltes\CONFIG~1\Temp\msohtml1\01\clip_image004.gif"&gt;&lt;w:wrap type="square"&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;/w:wrap&gt;&lt;/v:imagedata&gt;&lt;/o:lock&gt;&lt;/v:path&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:f&gt;&lt;/v:formulas&gt;&lt;/v:stroke&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-5824510941637542087?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/5824510941637542087/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=5824510941637542087' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5824510941637542087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/5824510941637542087'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2008/12/cmo-interpretar-un-burndown-chart.html' title='Cómo interpretar un burndown chart'/><author><name>vgaltes</name><uri>http://www.blogger.com/profile/15422687064529833096</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_ZaNkQuiMjcA/ST6BGjMrwkI/AAAAAAAABtg/3Wj6OGNs-hY/s72-c/sbc-ideal.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-8770417851468489314</id><published>2008-11-24T08:00:00.000+01:00</published><updated>2008-11-24T12:30:48.380+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='WinForms'/><category scheme='http://www.blogger.com/atom/ns#' term='desarrollo'/><category scheme='http://www.blogger.com/atom/ns#' term='DataGridView'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Insertando una ProgressBar en un DataGridView</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Después de unos cuantos posts orientados hacia el terreno de la  metodologías y la gestión de proyectos, con este artículo vamos a volver al campo del desarrollo puro y duro.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;El objetivo de este post es mostrar cómo poder insertar un control de tipo ProgressBar en una columna del control DataGridView. Este problema, a priori complicado de solucionar ya que el DataGridView no permite la inserción directa de controles en sus columnas, es relativamente sencillo de abordar si se comprende el &lt;a href="http://msdn.microsoft.com/es-es/library/dkdz8z4e%28VS.80%29.aspx"&gt;modelo de objetos&lt;/a&gt; que utiliza el control DataGridView de .Net.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;No vamos a entrar en detalle sobre el citado modelo de objetos, únicamente explicaremos que para poder crear nuevas columnas (cómo la nuestra de ProgressBar) necesitamos crear una nueva clase que represente el tipo de columna, y una nueva que represente el tipo de celdas que pertenecen a dicha columna. Para ello basta con crear clases que deriven de DataGridViewColumn (o una de sus clases hijas) y DataGridViewCell (o una de sus clases hijas)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Para crear una columna que permita añadir objetos ProgressBar vamos a crear una clase que derive de DataGridViewImageColumn (después veremos porque concretamente de esta y no de la clase base o de alguna de las otras subclases)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;br /&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;span style="color: rgb(51, 51, 255);"&gt;    &lt;span style="color: rgb(0, 0, 153);"&gt;public class DataGridViewProgressColumn : DataGridViewImageColumn&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;    {&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;          public DataGridViewProgressColumn()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;          {&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;CellTemplate = new DataGridViewProgressCell();&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;En esta clase vemos que en el constructor se asigna una propiedad llamada CellTemplate. Esta propiedad se encarga de definir el tipo de celda que corresponde a la columna, de manera que cuando se tengan que crear nuevas celdas el DataGridView sepa cómo crearla. Cómo podemos ver se esta asignado a la propiedad una nueva instancia del tipo DataGridViewProgressCell, que es una clase que también tenemos que crear. Ahora vamos a ver cómo construir la clase que representará a nuestro nuevo tipo de celda:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;class DataGridViewProgressCell : DataGridViewImageCell&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;{&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;Lo primero es derivar del tipo de celda correspondiente (DataGridViewImageCell, que es el tipo de celda que corresponde a la columna de la que habíamos derivado nuestra ProgressColumn)&lt;br /&gt;&lt;br /&gt;Ahora vamos a explicar como funcionará esta clase para poder entender todo el código que va a ir dentro de ella:&lt;br /&gt;&lt;br /&gt;La celda mostrará una barra de progreso (en el ejemplo la estándar de Windows, pero ya veréis que será muy fácil modificarla al gusto de cada uno) , que irá actualizándose en base al valor que nosotros le pasemos a la celda. Es decir nosotros asignaremos valores enteros entre 0 y 100 y la barra de progreso se irá actualizando. Parece lógico pero ya veréis que si no de deja claro ahora puede ser complicado entender el siguiente código:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;Añadimos los siguientes constructores a la clase:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;        static Image emptyImage;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;static DataGridViewProgressCell()&lt;br /&gt;&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;{&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;     emptyImage = new Bitmap(1, 1,    System.Drawing.Imaging.PixelFormat.Format32bppArgb);&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;}&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;public DataGridViewProgressCell()&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;{&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;              this.ValueType = typeof(int);&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;&lt;br /&gt;}&lt;/span&gt; &lt;span style="color: rgb(51, 51, 255);"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;En el constructor estático (o de clase) se inicializa una variable de tipo Image mientras que en el contructor público se indica el tipo de datos de la columna, que será un entero. Este valor será el que se utilizará para recoger el porcentaje que se debe mostrar en la barra de progreso y ahora veremos que utilidad tiene la imagen del cosntructor estático.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;El siguiente paso es sobreescribir el método GetFormattedValue. Este método sirve para transformar el valor de entrada de la celda (que en este caso es un entero) en el objeto que espera el DataGridView, que al estar derivando de DataGridViewImageCell es una imagen (Ahora se entiende el porqué de la imagen del constructor estático)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-size:85%;" id="_ctl0_MainContent_PostFlatView" &gt;&lt;span&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;protected override object GetFormattedValue(object value,&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; int rowIndex, ref DataGridViewCellStyle cellStyle,  &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;TypeConverter valueTypeConverter,&lt;/span&gt; &lt;span style="color: rgb(0, 0, 153);"&gt;TypeConverter formattedValueTypeConverter,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;                DataGridViewDataErrorContexts context)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;        return emptyImage;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="color: rgb(51, 51, 255);"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Cómo veis, en lugar de formatear el valor de entrada y devolver la imagen correspondiente que parecía la opción más lógica según lo expuesto arriba en este método devolvemos  directamente la imagen vacía, ya que en nuestro caso no se va a utilizar este método para representar el valor del ProgressBar, pero se debe devolver una imagen por consistencia con el tipo de datos de la celda madre (DataGridViewImageCell).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;Y finalmente vamos ver cómo tenemos que a sobreescribir el método Paint de la celda. En este método será donde representemos realmente el valor del progreso. Con esto completaremos la clase:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt; &lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)&lt;br /&gt;{&lt;br /&gt;int progressVal;&lt;br /&gt;           if (value != null &amp;amp;&amp;amp;  value.GetType() == typeof(Int32))&lt;br /&gt;               progressVal = (int)value;&lt;br /&gt;           else&lt;br /&gt;               progressVal = 1;&lt;br /&gt;&lt;br /&gt;           float percentage = ((float)progressVal / 100.0f);&lt;br /&gt;&lt;br /&gt;           Brush backColorBrush = new SolidBrush(cellStyle.BackColor);&lt;br /&gt;&lt;br /&gt;          Brush foreColorBrush = new SolidBrush(cellStyle.ForeColor);&lt;br /&gt;&lt;br /&gt;             base.Paint(g, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle,  advancedBorderStyle, (paintParts &amp;amp; ~DataGridViewPaintParts.ContentForeground));&lt;br /&gt;&lt;br /&gt;         const int margin = 4;&lt;br /&gt;&lt;br /&gt;         ProgressBar pb = new ProgressBar();&lt;br /&gt;         pb.Height = cellBounds.Bottom - cellBounds.Top - (margin * 2);&lt;br /&gt;         pb.Width = cellBounds.Right - cellBounds.Left - (margin * 2);&lt;br /&gt;pb.Value = progressVal;&lt;br /&gt;&lt;br /&gt;         Bitmap bmp = new Bitmap(pb.Width, pb.Height);&lt;br /&gt;&lt;br /&gt;         pb.DrawToBitmap(bmp, pb.ClientRectangle);&lt;br /&gt;&lt;br /&gt;         g.DrawImage(bmp, new Point(cellBounds.X + margin, cellBounds.Y + margin));&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Lo que estamos haciendo aquí es que cada vez que se llama al evento Paint de la celda se actualiza el estado de la variable ProgressBar interna de la misma y se "pinta" el control dentro de la celda (mediante GDI). Ahora vemos cómo a partir de un entero de entrada tenemos el control ProgressBar en pantalla. El utilizar GDI para "pintar" el control aporta mucha flexibilidad ya que permite darle la apariencia que se quiera: Por ejemplo en lugar de utilizar un control ProgressBar interno y "ver su imagen" podríamos dibujar el resultado del progreso de la manera que mejor nos pareciera, con los colores que mas nos gustasen, con efectos, con texto, etc...&lt;br /&gt;&lt;br /&gt;Ahora que ya tenemos las clases preparadas vamos a ver cómo utilizarlas  en un DataGridView de manera que podamos visualizar el control en las diferentes filas que se añadan al mismo.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;En el ejemplo vamos a suponer que creamos el DataGridView en tiempo de diseño (aunque se podría hacer en tiempo de ejecución). Lo primero es arrastrar el control DataGridView a nuestro formulario y visualizar la pantalla de propiedades del control.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center; color: rgb(0, 0, 0);"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR79m7SfEpI/AAAAAAAAAFY/gQPZ9Y09oOs/s1600-h/DataGridView.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 202px;" src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR79m7SfEpI/AAAAAAAAAFY/gQPZ9Y09oOs/s320/DataGridView.png" alt="" id="BLOGGER_PHOTO_ID_5268927459262141074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Arrastramos el DataGridView al formulario&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_EX9ub8lGIsQ/SR7-ADTHD8I/AAAAAAAAAFg/lCCjmWKBNDY/s1600-h/Properties.png"&gt;&lt;img style="cursor: pointer; width: 273px; height: 320px;" src="http://4.bp.blogspot.com/_EX9ub8lGIsQ/SR7-ADTHD8I/AAAAAAAAAFg/lCCjmWKBNDY/s320/Properties.png" alt="" id="BLOGGER_PHOTO_ID_5268927890908975042" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Pantalla de propiedades&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;En esta pantalla definimos las columnas que tendrá nuestro DataGridView. Pulsando el botón Add aparece una pantalla donde se indica entre otras cosas el tipo de la columna y aquí ya podemos ver que en la lista aparece un nuevo tipo, DataGridViewProgressBarColumn, que será el que seleccionaremos para la columna que tiene que mostrar la barra de progreso (Para que el nuevo tipo de columna aparezca hay que tener acceso al espacio de nombres donde hemos definido la clase desde el formulario).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center; color: rgb(0, 0, 0);"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR7_NaRJaUI/AAAAAAAAAFo/sp3JwMcEJrs/s1600-h/AddColumn.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 305px;" src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR7_NaRJaUI/AAAAAAAAAFo/sp3JwMcEJrs/s320/AddColumn.png" alt="" id="BLOGGER_PHOTO_ID_5268929219924683074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;Añadiendo la columna de progreso&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-size:85%;"&gt;Cuando hayamos añadido las columnas necesarias (en el ejemplo añadiremos únicamente dos)  volvemos al formulario y creamos un objeto BindingSource arrastrándolo hacia el mismo. Con este objeto implementaremos el enlace entre los datos y el DataGridView.&lt;br /&gt;&lt;br /&gt;En la pantalla deberíamos tener algo parecido a esto:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;img src="file:///C:/DOCUME%7E1/jasosa/CONFIG%7E1/Temp/moz-screenshot-1.jpg" alt="" /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR7_6wkvpgI/AAAAAAAAAF4/h-fudOSvnoI/s1600-h/BindingSource.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 227px;" src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR7_6wkvpgI/AAAAAAAAAF4/h-fudOSvnoI/s320/BindingSource.png" alt="" id="BLOGGER_PHOTO_ID_5268929999006574082" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: center; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size:78%;"&gt;DataGridView con las dos columnas y el objeto BindingSource&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;El siguiente paso es crear un DataSet que será el que contenga los datos. Este DataSet podríamos extraerlo de una base de datos, de un servicio Web o de cualquier otro origen de datos, en nuestro ejemplo lo construiremos y lo llenaremos programáticamente.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);font-size:85%;" &gt;private void InitializeDataSet()&lt;br /&gt;{&lt;br /&gt;//Creamos el DataSet y definimos las columnas.&lt;br /&gt; customDataSet = new DataSet();&lt;br /&gt; customDataSet.Tables.Add(new DataTable("TablaEjemplo"));&lt;br /&gt; customDataSet.Tables["TablaEjemplo"].Columns.Add(new DataColumn("DSNombre", typeof(string)));&lt;br /&gt; customDataSet.Tables["TablaEjemplo"].Columns.Add(new DataColumn("DSProgreso", typeof(int)));&lt;br /&gt;&lt;br /&gt; DataRow row1 = customDataSet.Tables[0].NewRow();&lt;br /&gt; row1["DSNombre"] = "Fila 1";&lt;br /&gt; row1["DSProgreso"] = 25;&lt;br /&gt; customDataSet.Tables[0].Rows.Add(row1);&lt;br /&gt;&lt;br /&gt; DataRow row2 = customDataSet.Tables[0].NewRow();&lt;br /&gt; row2["DSNombre"] = "Fila 2";&lt;br /&gt; row2["DSProgreso"] = 35;&lt;br /&gt; customDataSet.Tables[0].Rows.Add(row2);&lt;br /&gt;&lt;br /&gt; //Ponemos a false el valor AutoGenerateColumns para utilizar las columnas definidas en vista de diseño&lt;br /&gt; dataGridView1.AutoGenerateColumns = false;&lt;br /&gt;&lt;br /&gt; //Enlazamos el Dataset con el DataGrid&lt;br /&gt; bindingSource1.DataSource = customDataSet.Tables[0];&lt;br /&gt; dataGridView1.DataSource = bindingSource1.DataSource;&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Volvemos a la vista de diseño del Grid e indicamos la relación entre las columnas del DataGrid y las del DataSet (opción Columnas de las propiedades del control)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;a style="color: rgb(0, 0, 0);" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR8CpF5lbeI/AAAAAAAAAGQ/Jqr-T8Tzf1A/s1600-h/dsNombre.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 210px;" src="http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR8CpF5lbeI/AAAAAAAAAGQ/Jqr-T8Tzf1A/s320/dsNombre.png" alt="" id="BLOGGER_PHOTO_ID_5268932994028367330" border="0" /&gt;&lt;/a&gt;&lt;a style="color: rgb(0, 0, 0);" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_EX9ub8lGIsQ/SR8CxQM-EHI/AAAAAAAAAGg/xE47BjumIVs/s1600-h/dsProgreso.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 214px;" src="http://1.bp.blogspot.com/_EX9ub8lGIsQ/SR8CxQM-EHI/AAAAAAAAAGg/xE47BjumIVs/s320/dsProgreso.png" alt="" id="BLOGGER_PHOTO_ID_5268933134232981618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style="font-size:78%;"&gt;En la opción DataPropertyName de cada columna ponemos el nombre de la columna del DataSet que enlazaremos. Fijaros que son las columnas definidas en customDataSet&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Si ahora ejecutamos el proyecto vemos que aparecen las dos filas creadas y que la barra de progreso de cada una corresponde a los valores dados a las columnas del DataSet. Si quisíeramos modificar ese valor sólo tendríamos que ir cambiando el valor de la celda DSProgreso del DataSet y automáticamente se vería reflejado en el Grid y en la barra de progreso.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: center; color: rgb(0, 0, 0);"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_EX9ub8lGIsQ/SR8Fk6DpL7I/AAAAAAAAAGo/uCMDCArwL1U/s1600-h/Run.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 194px;" src="http://2.bp.blogspot.com/_EX9ub8lGIsQ/SR8Fk6DpL7I/AAAAAAAAAGo/uCMDCArwL1U/s320/Run.png" alt="" id="BLOGGER_PHOTO_ID_5268936220664737714" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="color: rgb(0, 0, 0);" id="_ctl0_MainContent_PostFlatView"&gt;&lt;span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Gracias al potente modelo de objetos que .Net define para el DataGridView podemos de manera similar al ejemplo mostrado definir columnas para hospedar casi cualquier tipo de control que necesitemos. En ocasiones habrá que derivar de la columna DataGridViewImageCell cómo en el ejemplo, pero podemos cualquiera de las otras  clases base según la funcionalidad que necesitemos insertar en nuestra nueva columna.&lt;br /&gt;&lt;br /&gt;Os esperamos con vuestras opiniones, sugerencias sobre el tema o críticas al artículo en los comentarios!&lt;br /&gt;&lt;br /&gt;Un saludo!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:Verdana,Geneva,Arial,Sans-serif;font-size:85%;"  &gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6322324553987609211-8770417851468489314?l=devnettips.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devnettips.blogspot.com/feeds/8770417851468489314/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6322324553987609211&amp;postID=8770417851468489314' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8770417851468489314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6322324553987609211/posts/default/8770417851468489314'/><link rel='alternate' type='text/html' href='http://devnettips.blogspot.com/2008/11/insertando-una-progressbar-en-un.html' title='Insertando una ProgressBar en un DataGridView'/><author><name>JASOSA</name><uri>http://www.blogger.com/profile/04983255487301962625</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://2.bp.blogspot.com/_EX9ub8lGIsQ/TBn8Aup4WTI/AAAAAAAAAIs/BJWhYd9OvfU/S220/Juanan_2.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_EX9ub8lGIsQ/SR79m7SfEpI/AAAAAAAAAFY/gQPZ9Y09oOs/s72-c/DataGridView.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6322324553987609211.post-7971077282540209994</id><published>2008-11-13T21:44:00.001+01:00</published><updated>2009-02-03T16:19:02.201+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='product owner'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='reuniones'/><category scheme='http://www.blogger.com/atom/ns#' term='product backlog'/><category scheme='http://www.blogger.com/atom/ns#' term='scrum'/><category scheme='http://www.blogger.com/atom/ns#' term='equipo'/><title type='text'>SCRUM ( III )</title><content type='html'>En el artículo de hoy veremos las diferentes reuniones que se realizan a lo largo de cada uno de los sprints.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Reunión de inicio de sprint&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Esta es la reunión de la que nos acordaremos más en el transcurso del sprint sinó la hacemos correctamente. Se realiza al principio de cada sprint, a poder ser un lunes por la mañana, cuando la gente está bien despierta y sin los agobios de toda la semana de trabajo. A ella acuden el dueño del producto, el scrum master y el equipo de desarrollo. La faena del dueño del producto ( como ya hemos visto en anteriores artículos ) es llegar a la reunión con el product backlog priorizado y detallado en sus histórias más prioritarias. En la reunión ( que acostuma a durar toda la mañana ) el dueño del producto explica al equipo cada una de las histórias que cree que van a entrar en el sprint y el entre todos se dedican a dividir la história en las diferentes tareas que la van a componer. Este diálogo es importantísimo ya que ayuda mucho a detallar exactamente lo que se va a implementar en el sprint y evita que al final del mismo haya malentendidos entre el dueño del producto y el equipo de desarrollo. De la misma forma, ayuda a detallar la história tal y cómo la entiende el dueño del producto, ya que el equipo puede creer que para implementar una tarea tiene que hacer un acceso a datos complicadísimo y en cambio el dueño del producto no lo cree necesario. Sin este diálogo, el equipo de desarrollo implementaria este acceso a datos, tardando un montón y haciendo código innecesario ya que el cliente no lo cree necesario.&lt;br /&gt;En esta reunión, una vez detalladas las tareas, el equipo las debe estimar. Hay várias maneras de estimar una tarea, de las quales ya hablaremos algún dia. La estimación también ayuda mucho a refinar las tareas. En la estimación puede quedar reflejado que el equipo de desarrollo cree que para una tarea se debe hacer un algoritmo muy complicado y en cambio el dueño del producto quiere algo más simple. La estimación del equipo saldría con un valor muy alto, valor que sorprendería mucho al dueño del producto y se iniciaria otro diálogo para delimitar el alcance de la tarea.&lt;br /&gt;&lt;br /&gt;Cómo podemos ver, aquí queda de manifiesto una de las cosas más importantes de las metodologías ágiles: la comunicación. Es muy importante la comunicación entre los miembros del equipo, desde el dueño del producto hasta los desarrolladores.&lt;br /&gt;&lt;br /&gt;La reunión de planificación debe terminar decidiendo entre el equipo y el dueño de producto qué histórias entran en el sprint. Esto lo podemos hacer también de varias maneras ( que también veremos en otro artículo ) pero básicamente de lo que se trata es de estimar la velocidad del equipo en el sprint ( la cantidad de puntos de história que puede hacer el equipo ) y mirar qué histórias de usuario entran en el sprint. Si todavía no conocemos la velocidad del equipo la podemos intentar deducir. Primero asumiremos que un punto de história es el trabajo que puede hacer un desarrollador en un dia de trabajo ( no en un dia ideal, sinó en un dia "normal" ). Esta definición no es importante. Podeis utilizar la definición que queráis. Lo que es importante es que la definición la mantengáis constante a lo largo de la vida del proyecto. No puede ser que un dia utilicemos dias ideales y otro dia dias "normales".&lt;br /&gt;&lt;br /&gt;Una vez aclarado esto, sumamos los puntos de história que puede hacer el equipo. Por ejemplo, si somos un equipo de cinco personas, tres de las quales estan a tiempo completo y dos a mitad de jornada, tendremos que en tres semanas el equipo puede asumir 60 puntos de história. A este valor, nosotros le aplicamos otro modificador, para intentar estimar los posibles impedimentos que podamos tener. Un valor normal puede ser un 70%. Por lo tanto, diremos que nuestro equipo es capaz de asumir 42 puntos de historia en un sprint. Teniendo ordenadas las histórias por prioridad, podremos ir viendo qué histórias nos entrarán en el sprint. Por ejemplo, si nuestras histórias hemos estimado que nos ocuparán 6, 10, 8, 12, 4, 8 y 12 puntos de história, decidiremos que haremos las primeras 5 histórias.&lt;br /&gt;&lt;br /&gt;Hay dos cosas más importantes que deben decidirse en esta reunión:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;El objetivo del sprint.&lt;/em&gt; Puede parecer superfluo pero és importante definir un objetivo del sprint para que el equipo sepa porqué está trabajando.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Definición de acabado.&lt;/em&gt; Cómo vimos en el artículo anterior, es vital tener una definición común de acabado entre el dueño del producto y el equipo de desarrollo.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Sprint diário&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;El sprint diário es la herramienta que nos proporciona scrum para que el equipo pueda compartir conocimiento y se comunique a diário. En esta reunión ( de unos 15 minutos en general cómo máximo ) cada miembro del equipo debe contestar tres preguntas:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Qué hice ayer.&lt;/li&gt;&lt;li&gt;Qué haré hoy.&lt;/li&gt;&lt;li&gt;Qué inpedimentos tengo para realizar mi trabajo.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Esta reunión es muy importante por la visibilidad que dá del proyecto y del trabajo de cada uno. Haciendo asistir a todo el equipo a la reunión evitamos que haya alguien que no haga nada durante un dia. El hecho de tener que decir delante de todo el mundo que no se ha avanzado en nada, hace que la gente trabaje cada día. &lt;/p&gt;&lt;p&gt;Esta reunión también nos sirve para tener el control del avance del proyecto. Gracias al sprint diario podemos actualizar nuestro tablero de scrum ( real o virtual ) y ver cómo avanzan las histórias, ver si tenemos demasiadas histórias en paralelo, demasiadas en testeo, etc. Lo otro que podemos actualizar gracias a la esta reunión es el gráfico de burndown, que nos dá una información muy visual del estado del proyecto y, sobretodo, de la velocidad del equipo, pudiendo ver de un solo vistazo si se llegará a final de sprint con todas las tareas realizadas o no.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Demostración&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;La penúltima reunión del sprint es la demostración. En la demostración el equipo de desarrollo debe mostrar a todo el mundo los avances realizados en este sprint, es decir, el incremento de valor que han dado al producto. Esto es muy importante porque el equipo se obliga a tener un producto que se pueda ensenyar, en un entorno de preproducción lo más fiable posible. También es importante porque el dueño del producto puede ver si lo que se ha implementado es lo que el pedía, si ha habido algún malentendido, si todo va a la velocidad requerida, etc. A esta reunión también puede asistir otra gente de la empresa, cuya opinión puede ser tenida en cuenta por el dueño del producto para planificar las próximas histórias a realizar. El equipo nunc
