mercredi 5 décembre 2018

Como Sabotear Scrum: User Stories

La mayor cantidad de empresas que he visto fracasar sus procesos usando Scrum tienen un común denominador: "un mal" Product Owner. Listo, ya sabes cómo sabotear Scrum :)

Ahora bien, si lo que deseas es entender cómo reducir la posibilidad de fallar con Scrum, necesitamos entrar más a detalle con cómo un "mal" Product Owner funciona (o mejor dicho no funciona).

Lo irónico de este artículo es que una de las formas en las que puedes sabotear Scrum es aplicando mal una técnica que no es de Scrum, si no de XP.

¿Listo? Hablemos un poco sobre las historias de usuario.







En realidad las User Stories son bastante sencillas. Una user story es un texto pequeño de forma:

Como <Tipo de usuario> quiero <hacer algo> para <tener este beneficio>

Solo reemplaza los < > por información real y ¡Listo! ¡Tienes tu user story! Parte tus requerimientos en pequeños sub-requerimientos usando este formato . Pídele a tu Product Owner que sea muy específico agregando todas las user stories que necesite para incluir hasta el más pequeño y simple detalle. Las stories están tan bien escritas y con todos los detalles que el equipo de desarrollo logrará entender lo que estás pidiendo y ya solo tienen que desarrollarlo.

¿Correcto? Lamentablemente NO! Si estás haciendo esto es muy probable que fracase tu implementación de Scrum.

¿Qué estamos haciendo mal? Aparte de que necesitarás miles de user stories para poder describir todo lo que quieres (haciendo más difícil el mantenimiento del Product Backlog), sigues con la mentalidad waterfall, de primero escribo todo perfecto en un gran libro y después tú leyendo el libro debes entender (y asumir algunos detalles adivinando mi mente) lo que quise decir.

1. Si bien el formato que te presenté arriba es el correcto, ese texto de por si solo es 1/3 de lo que es una historia de usuario. 

Recordemos que ágil se trata de mejorar la comunicación entre personas y asegurarnos que todos entendemos la base de lo requerido e iremos descubriendo juntos nuevas cosas mientras avancemos. 

Una user story está conformada de 3 partes: 
  • Texto (Conocido como card en inglés)
    • Una noción de lo que hay que hacer sin necesidad de entrar hasta en el más mínimo detalle, escribimos a grandes rasgos qué queremos sin decir cómo hacerlo.
    • Ron Jeffries (uno de los pioneros de las user stories) dijo: el texto de la user story no es más que la promesa de una futura discusión.
  • Discusión
    • Product Owner explicará a detalle la historia de usuario y revisarán el texto.
    • El equipo de desarrollo debe de indagar en los detalles de la nueva funcionalidad requerida.
    • El Product Owner debe de asegurarse que todo el equipo de desarrollo tiene un entendimiento común de cómo el usuario final va a interactuar con la nueva característica del producto que describe la historia de usuario. 
  • Confirmación
    • Escribiremos en forma una lista los criterios de aceptación, es decir el conjunto mínimo de detalles que el Product Owner necesita que estén incluidos en el desarrollo para aceptarle al equipo la entrega de la funcionalidad requerida.

¿Qué mejoramos? Fomentamos la discusión y nos aseguramos de un buen entendimiento común de lo esperado tanto del lado del equipo de desarrollo como del Product Owner (mejor manejo de expectativas).


2. Si piensas que puedes hacer que alguien escriba un requerimiento y luego los desarrolladores deben entender lo que esta allí descrito a la perfección, comenzamos ya a violar el manifesto ágil.

Una desventaja del idioma inglés... bueno, también del español... y del francés... de hecho de todos los lenguajes excepto de la matemática, es que son lenguajes ambiguos. Es decir, cada quien puede darle diferentes interpretaciones a un mismo texto.

La única forma de asegurarte de que todos estamos en sintonía cuando hablamos de un requierimiento es utilizando la segunda y tercera parte de la historia de usuario (la discusión y la confirmación).








mardi 2 octobre 2018

¿Puedo combinar los roles en Scrum?

Algunas de las preguntas frecuentes que me han hecho en varias empresas son:

  • ¿Puede ser el Scrum Master también el Product Owner?
  • ¿Puede ser el Scrum Master también parte del equipo de desarrollo?
  • ¿Puede el Product Owner ser del equipo de desarrollo?

Comencemos por la pregunta más fácil de contestar. 

El Product Owner y Scrum Master son dos roles separados intencionalmente por Jeff Sutherland y Ken Schweber desde el principio, estos roles son complementarios pero totalmente diferentes. He visto casos en los que en equipos (sobre todo equipos nuevos) el Product Owner quiere que se hagan cosas y el Scrum Master evita que sucedan para proteger al equipo o proteger el marco de Scrum, por ejemplo:

  • Cambiar el trabajo que debe de hacerse durante el Sprint
  • Presionar al equipo y aumentar la velocidad de producción en corto plazo (aunque esto sea desastroso para la velocidad en mediano y largo plazo)

Es decir, el Scrum Master y Product Owner tendrán en algunos casos conflicto de intereses.

Antes de entrar a este tema de lleno, quisiera mostrarle la siguiente imagen:






¿Se puede imaginar cuál es la conversación entre Zizou y Ronaldo?

Que tal algo como: "Mirá pues Ronaldo, la pelota no la vayas a tocar con la mano por que te marcan falta. Lo que tenés que hacer es llevar la pelota con el pie e intentar meterla en el arco del otro equipo para que te den un punto, a eso se le llama Gol." :)

¿Será algo por el estilo? Si su respuesta es "definitivamente no, Ronaldo ya sabe jugar Futbol", entonces le tengo otra pregunta: ¿Para qué necesita entonces el Real Madrid un coach? Todos los jugadores saben jugar ya, ¿no?

¿Cuál es el objetivo de Zizou en este equipo?

Sip! Es definir la estrategia del equipo, entender cómo el Real puede ser cada día mejor y cómo enfrentarse y vencer en diferentes situaciones. 

Ahora, veamos otro tema: ¿Cuántas veces vieron que cuando el Real se acercaba a la portería del contrincante, Zizou con su traje y corbata se metiera al campo para ir a meter el gol? ¿Nunca?, ¿Por qué no? (aparte de que las reglas del juego lo prohíban :))

Si el entrenador se metiera al campo a jugar entonces durante este momento, su mirada se concentraría en la pelota y posiblemente en dos o tres jugadores. En este preciso momento el perdería la visión global de que es lo que esta pasando y le sería imposible definir estrategias efectivas para todo el equipo. 

¿Dónde debe estar Zizou? Afuera de la cancha, con una visión desde fuera, lograra ver el todo de lo que esta pasando.

Recordemos que el Scrum Master es el coach del equipo de desarrollo, si bien el equipo debe de definir sus propias estrategias, el Scrum Master necesita tener una visión desde fuera y enfocarse en ayudar a que el equipo de Scrum sea mejor. 

En cuanto un Scrum Master se vuelve parte del equipo, su mirada se volverá al problema que él como developer quiere resolver (solo verá el balón), y esto puede hacerle difícil crear una estrategia para ayudar al equipo (incluyendo la relación del Product Owner con los Stake Holders).

De la misma forma, el Product Owner es el responsable de definir e implementar las estrategias de cómo mejorar el producto y cómo hacer que se le de cada vez más valor al cliente final.


Así que mi recomendación es no meter a la cancha junto con el equipo de developers a jugar ni al Product Owner ni al Scrum Master. 






jeudi 16 janvier 2014

To all the first year PhD students

"Right now, you may feel that the conversation is one-sided, that you have to listen more than you can speak, and that in any event you have little to contribute and only one reader. That may be true for the moment. But at some point you will join a conversation that, at its best, can help you and your community free us from ignorance, prejudice and half-baked ideas that so many charlatans try to impose to us. It is no exaggeration to say that, maybe not today or tomorrow, but one day your research will improve, if not the whole world, at least your corner of it"

From: The Craft of Research By Wayne C. Booth, Gregory G. Colomb & Joseph M. Williams

mardi 22 janvier 2013

The business of PhD´s

So ... what's a Ph.D? I remember that when someone asked me this question, it was kind of challenging to explain it. Not because is rocket science, but because you need to have a clear idea and few words. The concept is so simple that if you can´t make a 5 years old kid to fully understand it, you are probably doing something wrong.

Some days ago I have found The Illustrated Guide to a Ph.D a great job done by Matt Might of Utah´s University.

I think that it is very important helping all the pre-grade students understand what is a Ph.D. The knowledge and understanding are the only tools that can be used to stop some private universities in "our poor countries" that are transforming the  Ph.D degree into something that has no research nor personal contribution to the human knowledge involved and are just a huge business.




jeudi 7 juin 2012

lundi 5 mars 2012

The importance of a Product Owner

Companies using regular Project Management methods and willing to start using the Scrum Framework usually take a lot of care when hiring the Scrum Master (SM). Of course they need to hire someone that has lots of experience managing teams and that "achieved to multiply" n times the velocity of his last team.

But not all of these companies understand that the key artifact of Scrum is the Product Backlog, and the responsible of this artifact is not the Scrum Master but the Product Owner (PO).
Having a good SM and a great development team with a bad PO is equivalent of having a hamster engine powered Mustang.



As explained on the book Enterprise-Scale Agile Software Development "In an organization with established agile skills and Scrum-based projects, with experienced developers and strong Scrum masters, a bad product owner can turn an effective team into a frustrated and ineffective mess."

The success of the sprint depend on several factors (good understanding of the stories and good complexity estimations among others), and most of them depends of the quality of the backlog stories, this means on the work done by the PO.

Basically, the success of a product depends on the PO. Here you can see some examples of bad PO practices in the post "How to create products that customers hate."


A good product owner should:

Understand the product

"If you can't explain it simply, you don't understand it well enough."
Albert Einstein
This seems to be a stupid and obvious suggestion, but I can assure you that all the product owners have tough times trying to write a set of stories to describe a feature of a product. And the only PO that achieve this are the ones that really, really.... really have a clear idea of the feature to be developed and the "why to be developed".
Typically, a bad story is the one that the developers do not understand or the one that can't be estimated in complexity points in a couple of minutes by the dev team.


Never underestimate the power of prioritizing

Being negligent with prioritising the stories while using scrum is like being negligent with the steering wheel while driving a car. The PO is the one that will trace the path for obtaining a product by giving priorities to the stories in the backlog. Giving life to the backlog is updating the priorities and adding or changing stories day after day. This is adapting the requirements depending on the context of the current market.One of the advantages of scrum is the flexibility of changing your mind at any time, and this is possible by mantaining your backlog alive.

Learn to write a good backlog story

You can have some good tips here

Be present as much as you can

Sometimes when the team starts to go technical, some of the product owners have the feeling that they are no longer needed. For example when starting to define the tasks of each story. Keep in mind that the team can have a doubt about the story at any moment, in general the team will go back and forth from technical to usege requirements. And it's not the same to ask directly the PO during the meeting when the ideas are fresh, than seeing him later to solve doubts. Not having a strong presence of the PO can harm the team's velocity.

If you are interested on becoming an excelent PO, I suggest you the book  Agile Product Management with Scrum

How to solve the org.hibernate.LazyInitializationException

If you are building real world Spring-MVC /Hibernate applications you will probably have the honor to meet the org.hibernate.LazyInitializationException. I'm assuming that in the DAO's implementation you are using the HibernateTemplate and not the entityManager (and of course a sessionFactory instead of a entityManagerFactory).

The error you might have looks like this:

GRAVE: Servlet.service() for servlet [testDispatcher] in context with path [/secondtest] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.anotated.ArtData.colors, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.anotated.ArtData.colors, no session or session was closed
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
 at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
 at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
 at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
 at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272)
 at com.test.controller.GetArtController.helloWorld(GetArtController.java:38)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

I have found a good explanation of the why on a webpage: 

"This error means that you’re trying to access a lazily-loaded property or collection, but the hibernate session is closed or not available . Lazy loading in Hibernate means that the object will not be populated (via a database query) until the property/collection is accessed in code. Hibernate accomplishes this by creating a dynamic proxy object that will hit the database only when you first use the object. In order for this to work, your object must be attached to an open Hibernate session throughout it’s lifecycle."

That is pretty nice! :)

The solution I've found in many web pages and forums is to force Hibernate  to perform an Eager fetching by using  fetch = FetchType.EAGER on the collection of the entity class. Once again, if you are building real world applications this kind of quickfix will not work.

For example, if your entity has one collection of objects (let's say a List<MyObject>), and each one of this objects has more than one collection of objects (let's say 2 or 3  List<String>); writing  fetch = FetchType.EAGER next to each collection  will probably  carry you to have the  javax.persistence.PersistenceException: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags.  Now,  instead of  trying to fix our brand new bug, lets try to fix our configuration to avoid having the first LazyInitializationException in a clean way.

How to avoid the LazyInitializationException:

All you need is to mantain the session of your sessionFactory open while the processing the request. This is possible by adding an OpenSessionInViewFilter filter in your web.xml that will bind the session to the thread of the entire processing of the request.

Here is an example of an web.xml file, we are defining the filter on lines 17-20 and doing the mapping it to all the URLs of the application on lines 22-25.
<web-app id="WebApp_ID" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>Spring Web MVC Application</display-name>
 
<!-- Listener to create the Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:META-INF/spring/spring-master.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener> 
  <filter>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>OpenSessionInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 
 <servlet>
  <servlet-name>testDispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>testDispatcher</servlet-name>
  <url-pattern>*.htm</url-pattern>
 </servlet-mapping>

</web-app>

By doing this, the filter will mantain the session opened (during the request handling) and allow the Lazy fetching.

Try this sample project:

I did this little sample spring-mvc / hibernate project (using eclipse)  if you want to see the complete configuration and test its execution.

You can download the project and all needed jars (14.3 M)
hibernate-sample.zip

or just the project with an empty \war\WEB-INF\lib directory (23 K)
hibernate-sample2.zip

To run this example you must have already a database installed and tomcat configured:


  1. Unzip the file with the project
  2. Import it to eclipse
  3. Edit the src/META-INF/spring/spring-datasource.xml to match your database (I have used Postgresql in this example)
  4. Run it whith Run on Server (if the option Run on Server don't appear read the next steps)
  5. enjoy :)

If Run on server option don't appear
  1. Rightclic on the project
  2. Choose properties
  3. Choose Project Facets
  4. Select "Dynamic Web Module" and Java and then clic on "Further Configuration" available.
  5. Set the "Content directory" as war and don't check the generate.xml option
  6. click OK
  7. Done!

Now if the project is running you can go to the URL http://localhost:8080/hibernate-sample/ and see this.