Waterfall vs Agile

Esempio: lo sviluppo di un compilatore per il linguaggio C. Un team di waterfallisti procederebbe in questa maniera: dato che la specifica funzionale è già fatta e consiste nel manuale del linguaggio C, si passa alla fase di design. Il design per il waterfallista consiste nello scomporre il sistema in moduli: l’analizzatore lessicale, che comunica con il parser, che comunica con il modulo che traduce l’albero sintattico in assembler, che comunica con l’ottimizzatore. Si definiscono delle interfacce, dopodiché la fase di design e conclusa, e si passa alla costruzione. Ciascuno di questi moduli viene sviluppato separatamente, il che permette (in questa fase) di fare lavorare più persone in parallelo. Ciascun modulo viene testato separatamente. Quando la fase di costruzione è finita, si passa all’integrazione: i vari moduli vengono compilati e linkati insieme. Quando il build funziona, si passa alla fase finale di test di integrazione.

Il problema di questo metodo di lavoro è che non c’è una misura concreta della qualità del lavoro fino a quando non si passa alla fase di testing. Il che significa che il committente può sapere qualche cosa di concreto sullo stato del lavoro solo verso la fine. L’avanzamento della costruzione dei vari moduli non è una misura concreta, perché non è possibile sapere per certo che il modulo funzioni nel contesto, fino a quando non viene integrato nel resto del sistema. I test unitari non possono trovare gli errori nell’implementazione o nell’interpretazione delle interfacce del modulo verso l’esterno.

Un team agile approccerebbe il lavoro in maniera molto diversa. Per prima cosa si fa funzionare il programma vuoto: “int main() {}”. Si scrive una prima versione funzionante del compilatore che è in grado di accettare il programma vuoto in ingresso e produce in output un file eseguibile (che non fa niente). Quindi dal primo giorno il committente ha in mano un programma funzionante, che implementa una parte, inizialmente molto piccola, delle specifiche funzionali.

Il passo successivo consiste, ad esempio, nell’accettare la dichiarazione delle variabili automatiche: “int main() { int x; }”, quello dopo nell’implementazione dell’assegnamento “int main() { int x; x = 0; }”, seguito forse dall’implementazione dei vari operatori aritmetici e logici, dalle chiamate di sistema, e così via. Ad ogni passo il compilatore è incompleto ma funzionante: implementa un sottoinsieme del linguaggio C. Ogni passo consiste nel prendere una carta dalla lista delle storie da implementare, scrivere i test di accettazione, i test unitari, e il codice di produzione, e integrare il tutto con il lavoro degli altri membri del team.

]]>

Leave a Reply