Avete mai sentito parlare di mob programming?
E’ una pratica di sviluppo software che consente ad un team di lavorare insieme, collaborando attivamente e divertendosi.
In questo articolo vi parlerò del percorso di apprendimento svolto dal team su questo interessante approccio allo sviluppo: i primi due paragrafi sono dedicati a nozioni teoriche sul Mob Programming e sul paradigma Driver e Navigator per poi passare ad un’interessante parte dedicata ad alcune riflessioni in merito all’approccio. Infine viene dedicato un paragrafo ai suggerimenti sulla pratica del Mob Programming, figli dell’esperienza acquisita dal workshop e dalla pratica della tecnica.
Buona lettura.
Che cosa significa mob programming
Il mob programming è una pratica di sviluppo software in cui tutti i membri del team collaborano sulla stessa attività usando un solo computer.
Una persona è alla tastiera, mentre gli altri lo indirizzano dicendogli cosa scrivere. Alla sessione possono partecipare non solo sviluppatori, ma anche product owner e scrum master, business analysts, Q.A., stakeholder e tutte le persone che possono essere utili per portare avanti lo sviluppo.
Tale pratica si è diffusa negli ultimi anni fra i team di sviluppo software, ma si ispira a modalità di lavoro già diffuse in altri ambiti: in generale, ogni gruppo di persone che collabora attivamente all’esecuzione di un task più o meno complesso sta facendo una sorta di mob programming.
Il paradigma “driver e navigator”
Le interazioni tra chi scrive e chi indirizza sono regolate dal paradigma del driver e navigator.
Come funziona? Spieghiamolo con un esempio.
Immaginiamo di essere in auto: solo uno è al volante ed ha la responsabilità di condurre il veicolo; chi gli è a fianco, può consultare una mappa, suggerire percorsi alternativi, avvisare di eventuali rischi, e così via. Chi guarda la mappa ha un’idea chiara dell’itinerario e delle strade da seguire così da poter fornire a chi è al volante tutte le informazioni che gli servono per operare il veicolo.
Allo stesso modo, nel mob programming, chi naviga si concentra sull’obiettivo da raggiungere mentre il driver si occupa di adottare le strategie migliori per riportare nel codice le indicazioni ricevute.
Questo tipo di interazione richiede un certo grado di equilibrio: può essere che il driver sia un esperto guidatore e conosca anche le strade, così che sia sufficiente un’indicazione di alto livello come ad esempio “Prendiamo l’autostrada e usciamo a Genova”; potrebbe anche succedere che servano indicazioni più specifiche come “Vai dritto e al semaforo gira a destra per prendere l’autostrada”, o ancora più tecniche se il driver è alle prime armi: “Premi la frizione e inserisci la prima marcia”.
Smart input device
Il ruolo del driver è quindi quello di recepire le indicazioni dei navigator e tradurle in codice, senza partecipare attivamente alla discussione o prendere iniziativa.
È come se fosse un dispositivo che riceve input vocali (come Amazon Echo Dot o Google Home per intenderci), ma più intelligente perché riesce a tradurre un concetto, anche di business, in codice.
Avvalendosi della sua esperienza, ad esempio, partendo dall’indicazione “moltiplica l’importo di ogni prodotto nel carrello per la sua quantità, poi stampa il totale”, può decidere di implementarla scrivendo un ciclo in cui incrementa una variabile “somma”, oppure con un’operazione di “reduce”, o una funzione ricorsiva.
Il principio alla base di questa regola che definisce il ruolo del driver è che, per entrare nella codebase di un progetto, un’idea deve passare dalle mani di qualcun altro. In questo modo l’idea viene condivisa, discussa e validata e siamo sicuri che sia comprensibile, perché l’ha implementata qualcun altro.
L’idea è semplice ma è il concetto chiave alla base del mob programming.
Fughiamo alcuni dubbi sul mob programming
Nell’approfondire il mob programming, sono sorte fra noi diverse obiezioni, che riportiamo insieme alle riflessioni e alle possibili risposte che sono emerse dalle nostre lunghe discussioni.
“Il mob programming è inefficiente”
Dipende.
In termini di efficienza, il mob programming aiuta a massimizzare il flusso, ovvero minimizzare il tempo che trascorre fra l’inizio della lavorazione di una storia dello sprint e la sua conclusione. In termini Lean [1], stiamo minimizzando il waste.
Per fare questo, il mob programming riunisce nella stessa stanza tutte le persone che servono per portare la storia a conclusione. Nessuno deve aspettare nessuno perché stanno tutti collaborando alla stessa attività.
Se si vuole però analizzare a fondo il tema efficienza, bisogna poi ragionare su chi partecipa alla sessione di mob.
“Non so chi debba partecipare alla sessione di mob programming”
Tutte le persone che servono a portare a termine l’attività, idealmente tutti coloro che possono contribuire alla soluzione del problema (da sviluppatori a designer, da PO a stakeholder e utenti finali). Qualsiasi impedimento che possa sorgere durante lo sviluppo deve poter essere risolto dalle sole persone presenti.
“Allora nel dubbio faccio venire tutti quanti”
Ok, idealmente è così.
Attenzione a qualche rischio, ad esempio:
- Chi sta partecipando alla sessione senza poter realmente contribuire su quella attività forse potrebbe impiegare meglio il suo tempo, ad esempio un designer che partecipa a un mob programming per il setup delle pipeline su GitLab.
- Troppa confusione nel caso ci siano tanti navigator può rallentare il flusso: bisogna fare molta attenzione a moderare le discussioni e controllarne lo scope. Più persone vogliono dire la loro più il livello di “rumore” si alza.
- Avere troppe persone può essere inefficiente: il contributo aggiuntivo di ogni singola persona tende inevitabilmente a ridursi con il crescere del gruppo. Aggiungere una terza persona ad un’attività in coppia quasi sicuramente colmerà delle lacune, aggiungere la decima a un gruppo di nove probabilmente farà poca differenza e quest’ultima potrebbe portare più valore altrove.
“Secondo me si perde solo tempo, lavorando da soli possiamo portare avanti tante cose diverse invece che una sola”
Ipotizzando di avere un backlog di qualità, la storia in cima al backlog è quella con il maggior valore di business e può avere senso portarla in produzione il prima possibile, a discapito di tutto il resto.
Il mob programming può essere uno strumento che aiuta a concentrare tutti gli sforzi in vista di un singolo obiettivo: massimizzare il valore di business rilasciato il prima possibile.
Al contrario, se non ci sono chiare priorità nel backlog, allora potrebbero mancare i presupposti per avere un vantaggio rilevante dal mob programming. Pensiamo ad un caso in cui è necessario provare diverse aggiunte al sistema per identificare quale possa essere quella che porta più valore: in questa situazione, tanti sviluppatori che realizzano piccole parti in parallelo possono rispondere più rapidamente alle esigenze rispetto al mob.
Altro scenario in cui l’adeguatezza del mob programming va valutata in base agli obiettivi che si pone il team potrebbe essere quello della realizzazione di un MVP: è più importante implementare anche separatamente molte piccole parti del sistema o costruire fin da subito una conoscenza condivisa con poche storie implementate insieme con un livello di qualità elevato?
“Ma se non conoscessi le vere priorità, tutti durante il “mob” potrebbero lavorare sulla cosa sbagliata. E se il P.O. non partecipasse potrei non avere risposte subito. E se….”
Sì, il mondo è difficile.
Per lavorare bene, aiuta sempre avere condizioni di lavoro il più possibile “ideali” quali:
- Priorità del progetto abbastanza chiare.
- “Customer on site”, quindi cliente sempre presente e a stretto contatto con il team.
- Nessuna dipendenza esterna (ad esempio nessuna libreria di terze parti inclusa nel codice sorgente).
- P.O. e S.M. presenti nel team.
- Feedback rapido sulle storie completate nell’ultimo sprint.
Se la situazione è sub-ottimale, anche gli altri modelli di sviluppo non rendono al meglio.
La nostra esperienza
Nel corso di questa gilda, abbiamo partecipato a un workshop sul Mob Programming tenuto da Woody Zuill [2] – uno dei pionieri del mob programming [3] – ed abbiamo sperimentato nei mesi successivi questa modalità di lavoro.
Dalle retrospettive fatte al termine di ogni sessione, abbiamo individuato alcuni suggerimenti relativamente ai punti di attenzione su cui abbiamo trovato delle difficoltà.
Affinché il mob programming sia efficace, è necessario che il gruppo impari a lavorare bene assieme: le dinamiche sociali vengono amplificate e vanno monitorate, correggendo la rotta in caso di bisogno.
Discipliniamoci e misuriamo gli interventi
Un esempio di dinamica disfunzionale è la mancanza di disciplina negli interventi di più navigator, che può far perdere il filo del ragionamento impedendo al driver di cogliere in quale direzione andare. È necessario quindi che i navigator prestino attenzione nel dosare i propri interventi, per apportare valore senza creare confusione.
Un esercizio che abbiamo trovato utile sperimentare in tal senso è stato il Coding Dojo [4]: in questa modalità abbiamo un solo navigator a turno, mentre gli altri partecipanti non possono dare indicazioni al driver. Questa modalità aiuta a prendere consapevolezza della necessità di riflettere prima di intervenire, affinché l’intervento non generi “rumore” e sia costruttivo.
Diamo spazio d’intervento a tutti
Un’altra dinamica da tenere sotto controllo è una partecipazione troppo difforme, dove alcune persone intervengono in modo prevaricante, mentre altre sono restie ad intervenire. È consigliabile che il team trovi delle misure correttive per mitigare questa dinamica, ad esempio per noi è stato utile provare, in alcune sessioni di mob programming, a lasciare il ruolo di navigator solo ai più “timidi”.
Stiamo attenti all'”effetto gregge”
È da monitorare anche l’effetto gregge: se c’è troppa uniformità tra i membri del team ed i contributi dei singoli sono molto simili, si rischia di non considerare soluzioni o proposte alternative, perdendo uno dei possibili vantaggi di questa pratica.
Troviamo un equilibrio ed il giusto livello di comunicazione tra driver e navigator
L’equilibrio tra driver e navigator richiede un buon flusso di comunicazione: il driver può chiedere indicazioni più specifiche se ne ha bisogno, il navigator può “correggere” se il driver sta andando nella direzione sbagliata e così via.
Nella nostra breve esperienza, abbiamo trovato molto utile partire con indicazioni di alto livello, scendendo nel dettaglio soltanto quando il driver lo chiede o se è strettamente necessario. Così facendo si ottengono alcuni vantaggi interessanti:
- La conversazione tra i navigator rimane a livello alto, dando priorità al contenuto piuttosto che ai dettagli implementativi
- Può navigare anche qualcuno che non sa programmare
- Se il driver è esperto, può dare un grande contributo senza essere “limitato” dalle indicazioni specifiche dei navigator (se dico “scrivi un ciclo for”, sto “costringendo” il driver a farlo, anche nel caso pensasse che un “map” sarebbe più efficace in quel caso)
Ulteriori pro del mob programming
Altri aspetti piacevoli che si possono verificare nel mob:
- Agevola l’espressione di idee diverse e diversi punti di vista, con diverse sensibilità
- Feedback immediato
- Divertente e coinvolgente
- Rende superflue code review e merge request
- Si condivide il carico cognitivo
- Collective code ownership ➡ nessuno può dire “non l’ho fatto io”
- Se una persona ha bisogno di un attimo di pausa, può prenderlo tranquillamente senza fermare il lavoro del team
- Può favorire la condivisione della conoscenza.
Conclusioni
Il mob programming non è una “soluzione”: non per forza deve essere utilizzato sempre, ma si può valutarne l’impiego a seconda della situazione, come alternativa ad altre tecniche di sviluppo, quali il pair programming.
Il mob programming è uno “strumento”: è importante imparare ad usarlo, definendo poche regole base del team e mettendolo in pratica per trovare il setup più adatto al proprio team.
Comprendere i vantaggi della pratica di sviluppo software del mob programming