Italian Agile Day 2010

Anche l'Italian Agile Day del 2010 è stato un bellissimo evento, e vorrei darne qui il mio personalissimo resoconto.

Keynote

Paolo Perrotta ha condotto con brio ed intelligenza un bellissimo escursus su come, nel corso del tempo, sia stato affrontato il problema di ridurre i fallimenti nei progetti software.
Un primo tentativo si è basato su un mito: i progetti falliscono perché gli strumenti di programmazione sono troppo complessi, tant'è che richiedono degli specialisti come i programmatori per essere realizzati. Se solo potessimo eliminare i programmatori...:-) Si cerca così soppressione dei programmatori tramite strategie che si chiamano di volta in volta SOA, UML, CASE; persino il Cobol è nato per scrivere programmi senza avere programmatori! Tutti questi tentativi si sono però scontrati contro un medesimo scoglio: scrivere algoritmi che vengano eseguiti è qualcosa di intrinsecamente complesso.
Si è anche pensato di controllare il fallimento eliminando la componente di errore umano. Nascono quindi i metodi formali di verifica di correttezza del software, che comunque non sembrano aver avuto molto successo.
Si è quindi pensato di eliminare la variabilità dei progetti irregimentando lo sviluppo all'interno di procedure ben determinate. Ecco allora nascere metodi di lavoro come il Waterfall, che conteneva alle sue origini idee apprezzabili come la valorizzazione delle persone e l'enfasi sul test anche automatizzato del codice. Waterfall, come molte altro processi di sviluppo, si sono nel tempo "distorti" nel loro divenire strumenti di successo. Anche "Agile" subirà la stessa fine? Forse sì, ma sicuramente lascerà qualcosa di buono alle sue spalle. Il seme "Agile" consiste nell'idea non eliminare, ma di accettare la variabilità dei progetti, scomponendoli in piccole parti, ognuna delle quali attraversa tre fasi (il corsivo indica mie ipotesi)

  1. Osservazioni (user stories)
  2. Ipotesi (codice)
  3. Verifica sperimentale (test)

Questo è il cuore dei "Metodi agili", che è destinato a rimanere perché non è altro che il cuore del metodo scientifico.

Affiliamo i nostri strumenti: un test driver fatto in casa

In questa interessante sessione Jacopo Franzoi ha illustrato la sua esperienza nell'introdurre in un progetto reale i test unitari anche in quel regno dimenticato costituito dalle interfacce web.
Jacopo è infatti riuscito a creare una mini libreria per testare le pagine generate tramite FreeMarker.
Il messaggio è stato chiaro: anche in ambienti apparentemente ostili, come lo sviluppo di pagine web, è possibile crearsi strumenti che consentano di testare le nostre applicazioni. La sovrabbondanza di dettagli implementativi, che probabilmente sono sfuggiti a chi non ha mai utilizzato il particolare strumento di template in esame, è forse stato l'unico piccolo neo nella presentazione.

Code Kata Live

Una brillante presentazione di Gabriele Lana sui code Kata ha introdotto la perfomance di Giordano Scalzo e Tonino Lucca.
Tesi centrale dell'esposizione di Gabriele: il talento non è (solo) innato, bensì sgorga da un esercizio costante. Perché l'esercizio giunga a dei risultati occorre che:

  1. sia sfidante: ogni prova deve essere leggermente più difficile delle precedenti, senza però essere frustrante;
  2. sia ripetuto;
  3. abbia un riscontro da parte di altri, sia da persone più esperte, che sappiano dare suggerimenti, sia da persone meno esperte, che possano dare opinioni non convenzionali.

Ripetere incessantemente buoni esempi ci consente di passare dal codice "quick and dirty" al codice "quick and clean". Quando le nostre abilità sono limitate, il codice "dirty" ci risulta "quick" perché non sappiamo fare altro. Al crescere delle nostre competenze invece, il codice "clean" ci dovrebbe risultare più "quick", cioè più veloce e naturale da scrivere di quello "dirty".

Guelfi versus Ghibellini


"Noi tutti dobbiamo essere animati da un grande desiderio di competere fra noi per sapere cosa sia il vero e cosa il falso sull'argomento che stiamo trattando; è infatti comune interesse che ci sia chiarezza su questo punto.
Mi accingo ad esporre il mio pensiero; se a qualcuno di voi sembra che io ammetta cose non vere, costui dovrà interrompermi e confutarmi. Del resto io non dico le cose che dico forte di una verità di cui sono sicuro, ma ricerco assieme a voi; pertanto, qualora il mio oppositore mi paia avere ragione, sarò io il primo a riconoscermi d'accordo con lui."

Questo passo del Gorgia di Platone è perfetto per descrivere il messaggio che Sergio Berisso, coaudiuvato da Tonino Lucca, ha voluto indicare nella sua presentazione interattiva. Occorre affrontare le retrospettive, ed in genere tutti i momenti di riflessione e confronto dei gruppi di sviluppo, con questo spirito costruttivo, cercando di trovare i punti di sintesi comuni tra visioni discordanti.

Open space sul Kata "Sasso-forbici-carta" svolto secondo le regole "Aperto-Chiuso"

In un angolino molto defilato, io e l'amico Marco Testa dell'XP User Group di Bergamo abbiamo provato a rifare il Kata "Sasso-forbici-carta" seguendo le regole "Aperto-chiuso" suggerite da Matteo Vaccari. Il pubblico non era certo numeroso...ehm...ehm...vabbe', se vi interessa qui sono le slides e questo è il codice.

TDD per le viste

Questa è stata sicuramente la presentazione più interessante fra quelle da me seguite nella giornata: valeva la pena di partecipare all'Agile Day solo per sentire Matteo Vaccari e Carlo Bottiglieri tenere questa lectio magistralis sul TDD.
TDD spinto sino alle estreme conseguenze: Matteo ha infatti mostrato come gestire con questa tecnica anche la produzione di interfacce HTML, mentre Carlo ha dato un esempio di come costruire partendo dalle fondamenta dei test ogni singolo aspetto dell'architettura di un'applicazione, inclusa l'interfaccia Javascript e l'ambiente di esecuzione dell'application server. Geniale l'idea di Carlo di simulare in un test l'occhio dell'utente che guarda la videata! Non so se questa visione radicale del TDD sia realmente applicabile da noi comuni mortali, ma sono certo che il suo fascino mi rimarrà impresso a lungo.
Ecco il link alle slides di Matteo, mentre rimango in attesa spasmodica di quelle di Carlo.

Conclusioni

Ancora una volta l'Italian Agile Day si è dimostrato un evento eccezionale: complimenti agli organizzatori e arrivederci alla prossima edizione! (A Roma? Io, voto per un Genova-bis! Ma a Milano proprio no???)

P.S. Ricevo da Carlo il link alle sue slides. Ragazzi, non perdetevele!!!

Unit testing with the Saff Squeeze

Yesterday I read an interesting post of Kent Beck about a testing technique called Saff Squeeze. The idea is that, when you have to fix a bug in your code, first of all you need to write an "high level" test (hit the bug high) that shows the problem, then, instead of stepping in your debugger looking for the bug, you try to write a test which goes deeper and deeper in the code, in-lining method calls, until you get to the root of the problem (hit the bug low). It's like the Tai Otoshi Judo throw.


Waterfall

A real world example

As I had to find a bug in my code, I decided to try this technique.

I'm working at an ERP that exports a list of tasks to Microsoft Project. If the user chooses to create a plan scheduled from the finish date, that date has to be the maximum value of the deadlines of each task. Unfortunately there was a bug in this piece of code, so I wrote this test. (Note that, for compatibility issues, I use Java 1.4 and JUnit 3 for the project.)

 
  protected void setUp() throws Exception {
    converter = new XMLConverter();
    projectBean = new ProjectBean();
  }   
 
  public void testIfScheduleFromFinishProjectFinishDateIsTheMaximumValueOfTasksDeadlines() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    projectBean.setScheduleFromStart(false);
 
    String xml = converter.toXML(projectBean);
    TestUtils.assertContains(
		xml,
        "<FinishDate>" +
			new DateProjectConverter().toString(maxDeadline) +
        "</FinishDate>"); //Fails
  }
 

This was my "high-hit" test. As converter.toXML is a full tested method that simply creates an XML from objects via reflection, I supposed that the problem was in projectBean.setScheduleFromStart, so I wrote this new test.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    projectBean.setScheduleFromStart(false);
 
    //projectBean.finishDate is now public for testing purposes
    assertEquals(maxDeadline, projectBean.finishDate);   //Fails
  }
 

The test failed: I was right. Then I tried to modify the test in-lining the code of the failing method.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    //projectBean.scheduleFromStart is now public for testing purposes,
    //and the setScheduleFromStart method is inlined
    projectBean.scheduleFromStart = false;
    if (projectBean.scheduleFromStart) {
      projectBean.finishDate = null;
    } else {
      //projectBean.maxDeadline() is now public for testing purposes
      projectBean.finishDate = projectBean.maxDeadline();
    }
 
    //projectBean.finishDate is now public for testing purposes
    assertEquals(maxDeadline, projectBean.finishDate);   //Fails
  }
 

Then I simplified the test.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
    //projectBean.finishDate is set to private again
    assertEquals(maxDeadline, projectBean.maxDeadline());   //Fails
  }
 

So this was time to inline the projectBean.maxDeadline() method.

 
  public void testSaffSqueezeExample() {
    MyDate maxDeadline = new MyDate();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    projectBean.addTask(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    projectBean.addTask(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    projectBean.addTask(task3);   
 
	//projectBean.tasks is set to public
	ProjectTaskBean maxDeadlineTask =
      (ProjectTaskBean) Collections.max(projectBean.tasks, new DeadlineComparator());
 
    //projectBean.maxDeadline is set to private again
    assertEquals(maxDeadline, maxDeadlineTask.getDeadline());   //Fails
  }
 

Well, at this point I saw that the problem should be in the DeadlineComparator class, so I could get rid of the intermediate tests, rollback the changes to the ProjectTaskBean class and write a test against the buggy class (my "high-low" test).

 
  public void testDeadlineComparatorFindsMaxDeadline() {
    MyDate maxDeadline = new MyDate();
 
	Collection tasks = new ArrayList();
 
    ProjectTaskBean task1 = createTask(1);
    task1.setDeadline(maxDeadline.addDays(-1));
    tasks.add(task1);   
 
    ProjectTaskBean task2 = createTask(2);
    task2.setDeadline(maxDeadline);
    tasks.add(task2);   
 
    ProjectTaskBean task3 = createTask(3);
    task3.setDeadline(maxDeadline.addDays(-2));
    tasks.add(task3);   
 
	ProjectTaskBean maxDeadlineTask =
      (ProjectTaskBean) Collections.max(tasks, new DeadlineComparator());	
 
	//All fields and methods in projectBean are set to their original visibility
	assertEquals(maxDeadline, maxDeadlineTask.getDeadline());   //Fails
  }
 

So this was time to fix-up my code! ;-)

Conclusion

Kent Beck says: "Squeezing encourages good design. If inlining creates too big a mess, back up, clean up the called method, and inline again. Even if I received no other benefits from squeezing, the design improvement would be worth it."

Well, if it's definitely true that you need a good design (or, at least, a not so bad one) for squeezing, I think that it could be difficult to refactor your code when you're doing it: after all, you have a red bar.

Anyway, it seems a nice technique to explore your code without digging in the debugger too much and, this time, it worked fine. :-)

Italian Agile Day 2009


Italian Agile Day 2009

E' stata annunciata la data per lo svolgimento del sesto Italian Agile Day: si terr il 20 novembre 2009 a Bologna. Come sempre la conferenza si annuncia interessantissima: vi dar aggiornamenti nei prossimi giorni.

Implicit conversions in Scala are cool

Andy Warhol  Dollar sign

Sometimes I hear sentences like Domain Specific Languages (DSL) can be generated effectively only using dynamic languages, or This super-cool feature could not be possible in a static typed language. More and more, some people would transmit the idea that dynamic languages are agile and cool, while static ones are rigid and old. I strongly disagree! I think that in static languages lots of unit tests are generated and maintained automatically by the compiler, while in dynamic ones the programmer should create and maintain these tests. So static languages have lots more unit tests: isn't this agile programming? And what about cool features? Well, what do you think about a language in which you can write something like this?

 
(5.0 USD) + (2.0 USD) == (7.0 USD)

Cool DSL, isn't it? Sure, and I will show you that this is possible (and very easy) using a language with a strong and static type system: Scala.

As we are going to write yet another money example, we could begin with the definition of currencies.

 
abstract class Currency {
  def name: String;
  override def toString = name
}    
 
object Euro extends Currency {
  def name ="EUR"
}    
 
object Dollar extends Currency {
  def name = "USD"
}

Not very exciting. We simply define an abstract Currency class and two singleton objects that extend this class. Note that these objects are instances of anonymous subclasses of Currency. This does matter, as we'll see in a moment.

Now let's define money.

 
case class Money[C &lt;: Currency](amount: Double, currency: C) {
  def + (otherMoney: Money[C]) = {
    new Money(amount + otherMoney.amount, currency)
  }
  override def toString = amount + " " + currency
}

Our class is parametric in the type C, and we tell to the compiler that it must be a subclass of Currency. This way we have the nice consequence that the + operator can add only money of the same currency, and this test is done by the compiler before our code is running.

It's time to get to the cool feature: implicit conversion. So, in the same file Money.scala in which we defined the Money class, we create a Money object, which has the responsibility to convert doubles, let me say, "annotated" with a currency, into Money.

 
object Money {
  implicit def doubleConverter(d: Double) = new {
    def EUR = {
      new Money(d, Euro)
    }    
 
    def USD = {
      new Money(d, Dollar)
    }
  }
}

Uhm, it sounds a bit strange. How we can use it? Let's see an example.

 
import Money._    
 
object MoneyMainProgram extends Application {    
 
  val tenDollars = (4.0 USD) + (6.0 USD)     
 
  println(tenDollars)
}

Now some explanations are required.

In the first line we import the Money object. We can see it as a kind of static import, that, among other things, adds to the scope of our code all the implicit conversions defined in that object.

When we write 4.0 USD, we try to invoke the USD method on the 4.0 object, which is a double. Obviously there isn't such a method in the Double class, but the compiler, before giving up and throwing an error, tries to see if there is some way to convert the 4.0 in an object that does understand the USD method. Luckily we have imported the doubleConverter which takes a Double and transforms it in an instance of an anonymous class with a USD method: bingo! So the compiler transforms our code in something like this:

 
  doubleConverter(4.0).USD()

But what is the result of this expression? Well, it's an instance of the Money class expressed in Dollar. This class has the + method that we can use to add another Money in the same currency. Cool!

Let's take a look to our work. We needed to add some features to the Double class. In some dynamic languages we could monkey patch this class. In Scala we did it using a dynamic conversion from Double to a class with the methods we need, so we reached the same purpose in a static and safer way.

And so, an old fashioned static language could have such cool features? It seems....

Aumentare la produttivit dello sviluppo software

Nel volume che appena terminato di leggere, Lean software development di Mary e Tom Poppendieck, ho trovato una frase illumninante.

Un tipico sistema costituito per il 64% da funzionalit usate raramente o del tutto inutilizzate, il che suggerisce che il terreno pi fertile per il miglioramento della produttivit dello sviluppo software stia nel non implementare funzionalit non necessarie.

Anche due semplici, ma inutili, campetti aggiunti su una maschera di immissione dati contribuiscono ad abbassare la produttivit. Generano infatti una buona dose di spreco (Eliminare gli sprechi il principio numero uno del "Lean development"):

  • sprecano il tempo necessario per codificarli e per testarne il funzionamento;
  • sprecano il tempo necessario per il caricamento dal database, nonch per il loro salvataggio;
  • sprecano spazio sul database;
  • sprecano spazio sulla maschera video, costringendo chi la disegna a difficili compromessi per non uscire dai margini dello schermo;
  • sprecano tempo per la loro documentazione, se esiste ;-) ;
  • sprecano il tempo del personale di supporto che costretto a ricercare le ragioni, inesistenti, della loro presenza per rispondere ai quesiti del cliente;
  • sprecano la fiducia che il cliente ha nei confronti degli sviluppatori (che fiducia possiamo avere in chi spreca tanto per costruire un sistema cos inutilmente complesso?).

Programmazione agile: incomincio con le stime

A seguito del bel seminario di Simone Casciaroli "Tool for agile planning and estimation" all'Agile Day 2008, di cui ho gi parlato, il mio piccolo gruppo di sviluppatori ha deciso di sperimentare la stima agile dei progetti.
Sentendoci dei novizi, abbiamo pensato di utilizzare come unit di misura delle storie le vecchie care ore di lavoro e non gli Story points. Abbiamo anche semplificato il processo di determinazione delle stime: ogni persona deve indicare il tempo minimo e massimo che ritiene necessario per la realizzazione della storia. Vengono quindi elaborate le medie dei tempi minimi e dei tempi massimi e si utilizza come stima ufficiale l'80% dell'intervallo cos ottenuto:

(media(massimi) - media(minimi)) * 0,8 + media(minimi)

ll tutto stato elaborato tramite un banalissimo foglio di Excel.
Attendiamo di vedere i risultati :-)

Agile day 2008 - appunti di viaggio


Agile day

S, va bene, avrei voluto commentare in diretta l'Agile day 2008, ma non ci sono riuscito per merito degli organizzatori: troppe le cose interessanti da seguire per poterle riportare immediatamente!
Cercher quindi di dare il mio personalissimo riassunto a posteriori, che intende essere pi un taccuino di viaggio che un'analisi accurata dei tantissimi stimoli ricevuti nella manifestazione. I protagonisti dei vari incontri non me ne vogliano se non sono riuscito a recepire esattamente quanto volevano esprimere :-)

Agile e pragmatic: sinonimi o contrari?

La giornata iniziata discutendo su "Agile e pragmatic: sinonimi o contrari?". Stimolo per il dibattito stato un comune sentire che si sta facendo strada nell'ambiente Agile, emergente anche dagli ultimi thread della mailing list XP-it (e su cui mi sono permesso di scrivere un breve post). La sensazione che nelle pratiche agili ci sia qualcosa da rivedere, pur non essendoci accordo sul cosa. Qualcuno pone l'accento sul dogmatismo con il quale esse sono a volte presentate. Altri sul fatto che, come in tutti i fenomeni diventati di massa, ci siano state delle cattive interpretazioni. Un altro dubbio riguarda la possibilt di applicare solo in parte queste tecniche, senza che la mancata introduzione di una renda inutili tutte le altre. I pi maligni (che per non hanno preso parte all'Agile Day ;-) ) arrivano a supporre che qualcuno abbia sfruttato la moda per interesse personali. La mia modestissima opinione che effettivamente alcuni punti cardine dello Sviluppo Agile possano generare dei dubbi. In primo luogo mi chiedo se il design emergente sia in ogni situazione un valido sostituto del design preventivo, termine con cui non intendo la produzione di valanghe di documentazione e grafi UML che descrivono ogni metodo del progetto, ma una fase di analisi del "cosa fare" e "come farlo" proporzionale all'entit dell'impresa, analisi che potrebbe richiedere anche la generazione di documentazione di corredo. Mi domando inoltre se la programmazione agile sia veramente alla portata del programmatore medio, o richieda delle capacit fuori dal comune.
La maggiore prova a sostegno della bont dell'approccio agile penso comunque sia stata portata da Simone Genini. Se un imprenditore come lui, che non fonda il proprio business sulla evangelizzazione dell'agilismo, bens sulla consegna al cliente di codice funzionate, continua a scommettere da anni, pare anche con successo, su questi metodi di lavoro, allora si potrebbe financo pensare che funzionino veramente! ;-)

Refactoring di codice Legacy

La mia seconda tappa stata il bellissimo workshop di Tommaso Torti e Fabiana Romagnoli su "Refactoring di codice Legacy". Cosa ho imparato? Che anche il refactoring deve misurarsi con il tempo e le risorse a disposizione. Il codice proposto presentava infatti diversi aspetti suscettibili di miglioramento, ma un limite insuperabile era costituito dai venti minuti a disposizione. Ci si poteva concentrare sull'eliminazione di numerosi "if" tramite l'utilizzo del polimorfismo, oppure lavorare sulla chiarezza del codice cancellando duplicazioni, rinominando variabili ed assegnando correttamente le responsabilit alle classi. Il primo refactoring sarebbe stato sicuramente pi pirotecnico, ma probabilmente non avremmo avuto n il tempo, n le energie (ci siamo alzati alle cinque) per portarlo a termine. Il secondo, molto pi banale, aveva invece il vantaggio di riuscire comunque a consegnare valore al cliente (nel nostro caso Tommaso e Fabiana) nel tempo stabilito.

Tool for agile planning and estimation

Altro workshop molto interessante stato quello condotto da Simone Casciaroli. Lo strumento per la pianificazione agile proposto, chiamato ora Stuffplanner, pur essendo in versione alpha, ci sembrato molto potente. Cosa ho imparato? Tutto, dato che sono assolutamente un novizio della pianificazione agile. Ecco i miei appunti ad uso principianti.

- E' importante suddividere il progetto in "storie" quanto pi indipendenti fra loro al fine di evitare che una di esse costituisca un collo di bottiglia per lo sviluppo delle altre. Esse dovrebbero inoltre essere "verticali", ovverosia comprendere una funzionalit completa, dalla GUI al DB, per rappresentare una unit atomica di valore rilasciabile al cliente. In tal modo questi potr valutarne correttamente la priorit all'interno della fase di pianificazione ed avremo sempre dei rilasci che aggiungono valore al prodotto.

- Un formato standard per le storie : As a....I want...so that.....
As a... indica lo scenario di utilizzo che si immagina per la storia, per esempio Come utente esperto.
I want... indica il contenuto vero e proprio della storia, per esempio io voglio cercare un libro per ISBN.
Nella clausola so that.. si dovrebbe rendere esplicito il valore che la storia possiede per il cliente, al fine di aiutarlo nell'attribuzione del giusto peso durante la fase di pianificazione. Nel nostro esempio avremmo cos da poter comprare un libro in brevissimo tempo.

- Una storia non dovrebbe occupare il team per pi di due giorni, per evitare che il grafico di avanzamento lavoro (burndown chart) rimanga stabile per troppo tempo, abbassando il morale degli sviluppatori.

- La stima di una storia dovrebbe essere svolta preferibilmente in "story point", una misura di difficolt relativa. Per esempio, "se si indica con 1 la difficolt di sviluppo della storia pi semplice, allora la storia X avr peso 7". Il passaggio dagli "story points" al tempo reale dovrebbe essere realizzato analizzando lo storico delle iterazioni precedenti. Alla prima iterazione occorre solo confidare nell'esperienza dei membri del team. :-)

- La stima di una storia non un valore singolo, ma una curva di probabilit di consegna: suppongo che non ci sia alcuna probabilit di realizzare la storia in meno di x story point (valore minimo), mi aspetto che ne serviranno y (valore atteso), penso di essere certo di consegnarla dopo z story point (valore massimo). Tutti gli elementi del team esprimono queste tre valutazioni. Per determinare il peso da assegnare alla storia, che un singolo numero, si possono scegliere diverse funzioni di interpolazione di questi dati, fissando inoltre una soglia di rischio: ad esempio potrei scegliere il valore della curva di probabilit che mi garantisca una affidabilit dell'80%. Uno strumento come Stuffplanner di ausilio in questa fase.

- Se ovviamente importante non sottostimare le storie, altrettanto pericoloso sovrastimarle. Il team, infatti, vedendo che la propria velocit molto maggiore del previsto potrebbe rilassarsi troppo e perdere concentrazione.

Processo al database server relazionale

Purtroppo ho potuto assistere solo ai momenti finali di questa divertente presentazione/rappresentazione, svolta con notevole capacit teatrale. Due brevi note da innocentista.
Come prova a carico del DB relazionale stata portata una stored procedure, realmente messa in produzione, che occupava diverse pagine. A mio avviso le stored procedure non hanno un legame essenziale, oserei dire ontologico, con la struttura di un DB relazionale. Sono solo un posto, quasi sempre sbagliato, dove mettere del codice che lavora sui dati relazionali. La loro esistenza non strutturalmente legata a tale modello. Il fatto che molti programmatori poco avveduti ne abbiano abusato non sufficiente a dire che il modello relazionale sia negativo.
Un'altra critica mossa al DB quella che lo vorrebbe d'impiccio nella fase di stesura dei test. Se da un lato questo sicuramente vero, dall'altro occorre forse ristabilre una giusta proporzione tra le cose. Ricordiamo sempre che i test non sono un fine, ma solo un mezzo. Dobbiamo trovare il modo per testare meglio l'uso del DB, cercando di evitare che la parte di accesso ai dati contenga troppa logica, ma ci non pu scalfire la validit dell'approccio relazionale nella grande maggioranza dei casi.
Quando qualcuno parla male dei database, io ricordo sempre che lavoro da anni su un DB che stato alimentato, interrogato e spippolato da programmi scritti in una decina di linguaggi diversi. I linguaggi sono cambiati, i programmi sono stati riscritti, ma la struttura del DB, ben congegnata, rimasta. Diceva Cicerone Programmata volant, Datarum Basae manent :-D

Uso dei Kanban, ovvero quando stimare impossibile

Questo stato il titolo di un open space fuori programma tenuto da Gabriele Lana.
Se non ho inteso male, il punto di vista di Gabriele il seguente. In particolari situazioni, dove ad esempio il dominio del problema sia particolarmente difficile o inusuale, oppure dove vi sia una grossa dipendenza da programmi o prodotti sviluppati da terzi fuori dal nostro controllo, effettuare delle stime dei tempi di realizzazione semplicemente impossibile. Non solo, ma la stima potrebbe risultare controproducente rispetto all'affidabilit del software. I programmatori potrebbero infatti cercare di abbassare la qualit (copia e incolla selvaggio, mancata stesura di test, design approssimativo e mancanza di refactoring) pur di rimanere all'interno dei tempi previsti. In questi casi l'approccio migliore sarebbe quello di stendere delle user story, che potremmo ora definire Kanban, che avrebbero solo la funzione di ordinare i lavori in base alla priorit e determinare lo stato di avanzamento degli stessi.
E la stima di tempi e costi? Visto che in ogni caso in queste situazioni una qualsiasi stima sarebbe solo una bugia, meglio concordare con il cliente un tipo di contratto flessibile, con punti di verifica frequenti ove poter eventualmente cambiare direzione.

Conclusioni

L'agile day si confermato un grande evento. Un grosso ringraziamento a chi si preso l'onere dell'organizzazione ed un arrivederci all'anno prossimo!!!