Fondamenti

Ora possiamo iniziare a parlare di Extreme Programming (XP), una tecnica di sviluppo agile nata tra la fine degli anni ’90 e l’inizio degli anni 2000 dalla mente di Kent Beck, che la ideò nell’ambito di un progetto Chrysler.

Variabili

Secondo Beck, durante lo sviluppo di software le principali variabili sono:

  • portata: la quantità di funzionalità da implementare, una variabile delicata dal valore mutevole poiché il numero di funzionalità richieste può cambiare nel corso dello sviluppo;
  • tempo: il tempo che si può dedicare al progetto;
  • qualità: la qualità del progetto che si vuole ottenere, principalmente relativa a correttezza e affidabilità. Di fatto è una costante perchè quando si realizza un progetto si cerca di avere la qualità migliore possibile (sappiamo non essere sempre così nella pratica a causa dei compromessi che a volte bisogna accettare);
  • costo: le risorse (finanziare o in termini di personale) che si possono impegnare per il progetto.

Queste 4 variabili non sono indipendenti tra di loro, in quanto cambiare una influenza automaticamente le altre, in positivo o in negativo. Ponendo quindi che la qualità non sia negoziabile (il software deve funzionare) bisognerà lavorare sulle altre, specialmente bilanciando costo e tempo.

Nel panorama classico di sviluppo la portata era definita in modo rigido dal cliente, che richiedeva certe funzionalità non negoziabili e pagava lo sviluppatore a progetto completo. Con l’XP si stravolge invece la prospettiva: il costo è orario, il tempo disponibile non è fisso ma pari al tempo richiesto per lo sviluppo e la portata viene ricalcolata durante il progetto, essendo così l’unica variabile a variare effettivamente. Si tratta di un approccio incrementale che mira ad avere sempre un prodotto consegnabile se il cliente decide di essere soddisfatto dello sviluppo; non si fa aspettare il cliente per dargli tutto il lavoro in un colpo solo, ma questo viene consegnato una parte alla volta. Oltre ad alleggerire la pressione sullo sviluppatore, questo approccio è utile per due motivi:

  • Il cliente è certo che lo sviluppatore si sia dedicando al progetto siccome vede il prodotto crescere a poco a poco, inoltre anche il cliente fa parte del team, di conseguenza può accertarsi in prima persona che il team di sviluppo si dedichi al massimo delle possibilità al progetto.
  • Dà la possibilità al cliente di avere comunque qualcosa in mano se ad un certo punto vuole interrompere la collaborazione.
  • Permette al cliente di cambiare idea sulla portata e sulle funzionalità richieste in corso d’opera, bandendo la rigidità dei documenti di specifica.

Tutti questi aspetti permettono di creare un rapporto molto meno conflittuale tra cliente e sviluppatore, cosa che crea le basi per una maggiore collaborazione tra le due parti. La presenza del cliente all’interno del team permette di avere un feedback rapido in ogni momento.

Principi

Parliamo ora un po’ dei fondamenti della filosofia XP, confrontandoli con quanto veniva prescritto nell’ambiente di sviluppo classico. I principi dell’ingegneria del software classica erano infatti i seguenti:

  • Separazione degli interessi (aspects o concerns): separare tempi, responsabilità e moduli, ovvero tutte le varie viste o le varie dimensioni su cui si deve affrontare il problema.
  • Astrazione e modularità: bisogna usare le giuste astrazioni che ci permettono di dominare i problemi complessi (possono essere i diversi linguaggi di programmazione, linguaggi di descrizione o vari altri costrutti). Questo aspetto è importante perchè più un problema è complesso più è necessario un certo livello di astrazione per rappresentarlo (ad esempio non è fattibile rappresentare un software complesso tramite il linguaggio macchina).
  • Anticipazione del cambiamento (design for change): in fase di progettazione il programmatore deve pensare a come potrebbe cambiare il prodotto, accomodando la possibile aggiunta di requisiti a cui il cliente magari non aveva neanche pensato; bisogna stare attenti però, perché spesso questo concetto complica arbitrariamente la progettazione e lo sviluppo, rischiando di far perdere molto tempo su cose che al cliente potrebbero non servire: può essere un’idea migliore partire da qualcosa di semplice ed incrementare man mano.
  • Generalità: per rendere più semplice la modifica e l’espansione futura è necessario scrivere interfacce molto generali ai sistemi che costruiamo.
  • Incrementalità: lo sviluppo avviene incrementalmente, un pezzetto alla volta.
  • Rigore e formalità: è importante essere rigidi e specifici sia nella comunicazione che nella descrizione dei requisiti.

L’XP non è niente di rivoluzionario, infatti non butta via tutti questi principi ma ne eredita invece alcuni e li adatta alle proprie esigenze (specialmente la separazione degli interessi, che viene data per scontata). L’XP pone pure l’accento su altri aspetti, ovvero:

  • Feedback rapido: bisogna mantenere un costante flusso di feedback; questo viene dato dai test, dai colleghi ma anche dal cliente, che dev’essere continuamente consultato sullo stato dei lavori. Tra le iniziative che favoriscono un veloce ciclo di feedback c’è lo standup meeting, una riunione mattutina fatta in piedi in cui ciascuno descrive in poche parole cosa ha fatto il giorno precedente e cosa intende fare oggi.
  • Presumere la semplicità: non bisogna complicare senza motivo né il codice, che dev’essere scritto con in mente ciò che serve a breve termine e non in un futuro remoto (carpe diem), né le relazioni tra colleghi, che non devono essere eccessivamente gerarchiche (tutti dovrebbero avere compiti molto simili); in generale si dovrebbe semplificare il più possibile in tutti gli ambiti del progetto.
  • Accettare il cambiamento: non ci si deve aspettare che il software sia immutabile; al contrario, deve essere dato per scontato il concetto di flessibilità e malleabilità, ovvero che il cliente vorrà fare cambiamenti sia dopo che durante lo sviluppo del prodotto, ma non deve essere nemmeno il primo obiettivo del lavoro. Se ne tiene conto senza perderci troppo tempo.
  • Modifica incrementale: ritornando al concetto di baby steps, ogni iterazione di sviluppo dovrebbe essere breve e le funzionalità introdotte piuttosto piccole; questa regola si applica tuttavia a tutti gli ambiti del progetto, dalla raccolta dei requisiti alla gestione del team: ovvero non bisognerebbe mai aggiungere più di una persona alla volta al gruppo di lavoro, in quanto aggiungerne di più potrebbe portare a passare più tempo ad istruirle che a sviluppare.
  • Lavoro di qualità: bisogna ovviamente ottenere un buon prodotto, ma per fare ciò la prospettiva cambia in favore dello sviluppatore, al quale si deve garantire un ambiente di lavoro salutare e un certo benessere; la fidelizzazione dei programmatori è importante perché più si trovano bene e meglio lavoreranno.

I due punti più in contrasto sono il presumere la semplicità e l’anticipazione del cambiamento: ci sembra infatti più previdente pianificare per il futuro e anticipare eventuali cambiamenti, ma come vedremo nel prossimo paragrafo talvolta questo può essere controproducente.

Presumere la semplicità vs anticipazione del cambiamento

XP mette davanti la semplicità all’anticipazione del cambiamento: non si scrive in anticipo codice che si pensa servirà in futuro. Questo non significa che non si stia progettando per il futuro, ma solo che questo non è il primo aspetto da guardare: il primo aspetto è la semplicità, ovvero fare le cose nella maniera più chiara possibile.

Non pianificare per il futuro sembra rischioso: secondo uno studio condotto da Bohem nel 1976 (basato anche sulla sua esperienza personale) viene ipotizzata una curva esponenziale per il costo delle modifiche all’aumento dell’avanzamento del progetto; più il progetto avanza più è costoso modificarlo, a causa dell’accumulo del debito tecnico, motivo per cui sembra necessario accomodare il cambiamento futuro in modo da ridurre tale costo.
Al contrario, XP presuppone una curva di tipo logaritmico che tenda ad un asintoto: passato un certo punto nello sviluppo il costo per le modifiche non subisce più cambiamenti sensibili. Questo si suppone accada grazie al miglioramento dei linguaggi di programmazione e delle tecniche stesse (re-factoring), per cui non ha senso fasciarsi la testa in anticipo in quanto un codice semplice è relativamente facile da modificare.

Curve di costo: XP vs tradizionale

Va inoltre considerato che Bohem parlava in realtà di cost-to-fix, non del costo per la modifica in sé; inoltre la sua statistica era poco affidabile poiché era stata costruita a partire da pochi dati. La curva esponenziale da lui descritta è stata poi successivamente ritrattata per accomodare il fatto che se un errore avviene in una fase affligge solo le successive, e non le precedenti.

Figure e responsabilità

Al fine di organizzare il lavoro, XP individua diverse figure che partecipano allo sviluppo:

  • Cliente: colui che richiede funzionalità e conosce il dominio applicativo.
  • Sviluppatore: colui che sviluppa concretamente scrivendo codice.
  • Manager: colui che amministra lo sviluppo con uno sguardo generale.

È interessante l’inclusione del cliente nel contesto dello sviluppo: esso non è più soltanto il committente ma ha un ruolo attivo nel lavoro, potendo cioè contribuire alla riuscita del progetto anche e soprattutto in virtù della già citata conoscenza del dominio applicativo.

Ciascuna di tali figure ha responsabilità e diritti riassunti nella seguente tabella (manager e cliente sono accorpati perché hanno grossomodo gli stessi compiti nelle tecniche di sviluppo moderne, come in scrum):

Soggetto Ha responsabilità di decidere... Ha diritto di...
Manager/Cliente
  • Portata del progetto, ovvero le funzionalità da realizzare
  • Priorità tra funzionalità e loro business value
  • Date dei rilasci, anche nel caso di release incrementali
  • Sapere cosa può essere fatto, con quali tempi e quali costi
  • Vedere progressi nel sistema e la sua correttezza, provati dai test da lui definiti (trasparenza)
  • Cambiare idea, sostituendo funzionalità o cambiandone le priorità a intervalli di tempo fissi (fine del ciclo di sviluppo incrementale)
Sviluppatore
  • Stime dei tempi per le singole funzionalità (no deadline imposte dall'alto)
  • Scelte tecnologiche e loro conseguenze, ovvero come si realizzano le funzionalità richieste
  • Pianificazione dettagliata delle iterazioni
  • Ricevere dei requisiti chiari (casi d'uso) con priorità per le varie funzionalità
  • Cambiare le stime dei tempi man mano che il progetto procede e il contesto di sviluppo cambia
  • Identificare funzionalità pericolose o troppo difficili da realizzare
  • Produrre software di qualità, per cui lo sviluppatore deve godere di un certo benessere

Business value: valore che assume una feature, dipendente dal costo (in termini di difficoltà) e dalla sua importanza all’interno del sistema. Questo valore viene sfruttato per decidere in che ordine dedicarsi le diverse feature da implementare.

Come si vede, per migliorare la fiducia tra sviluppatore e cliente sono necessari due requisiti: un certo grado di trasparenza da parte di chi sviluppa, ottenuta dall’uso delle contiene release incrementali per mostrare come sta evolvendo il sistema, e una certa dose di pazienza da parte del cliente, che deve accettare di lasciare allo sviluppatore la facoltà di decidere come si realizzano le funzionalità e di cambiare le prospettive temporali di sviluppo qualora fosse necessario.

Inoltre all’interno del team vi è anche la figura del tracker, ovvero una persona del team (non è fissa, può cambiare ad ogni iterazione) incaricata di tenere traccia delle problematiche incontrate durante l’iterazione. Per fare ciò il tracker definisce una metrica (ad esempio numero di issue aperti) ragionevole per misurare lo stato del problema preso in esame. Solitamente vi è un luogo fisico all’interno dell’ufficio in cui ogni giorno viene segnata la nuova misurazione (ad esempio una lavagna che è visibile da ogni membro del team). Grazie a questa figura tutto il team viene a conoscenza dei problemi principali che sono stati riscontrati durante il progetto, e ad ogni iterazione si cerca di capire in che modo risolverli in modo da migliorare il processo di sviluppo.