Convertire team esistenti in una della 4 topologie
Nella parte precedente avevamo visto le caratteristiche e le funzioni delle quattro tipologie di team previste in Team Topologies: Stream-Aligned Team, Enabling Team, Complicated-Subsystem Team e Platform Team. Vediamo ora come convertire classiche tipologie di team in una delle quattro tipologie descritte nella II parte.
Team di infrastruttura verso Platform Team
Team di infrastruttura — talvolta chiamati anche team IT, team “DevOps” a sproposito, team di sistemisti) — si trasformano in Platform Teams. Convertire un team di infrastruttura in un Platform Team abilita un rapido e sicuro flusso di valore sia all’interno della piattaforma, sia all’interno dei team Stream-Aligned. Questa conversione generalmente non è semplice perché, siccome una piattaforma deve essere gestita come un prodotto, spesso al team di sistemisti mancano capacità di product management e i suoi membri possono sentirsi spaesati. Questo è un ambito dove un Enabling Team può venire in supporto.
Component Team verso Platform Team o altri tipi
Team esistenti che si basano su componenti tecnologici dovrebbero essere dissolti, con il passaggio delle loro competenze a team Stream-Aligned, oppure convertiti in altri tipi come Platform Team se il componente è una “piattaforma” di basso livello, come Enabling Team se il componente è sufficientemente semplice da essere gestito a regime da team Stream-Aligned, o come Complicated–Subsystem Team se il componente è veramente troppo complicato per i team Stream-Aligned).
Tooling Team verso Enabling Team o parte di una piattaforma
Anche in questo caso, team che si occupano della manutenzione e dell’evoluzione di particolari tool rischiano di diventare silos rallentando l’organizzazione. Dovrebbero essere convertiti in Enabling Team di durata limitata, fintanto che la competenza non è stata assimilata dai team Stream–Aligned, oppure diventare parte di una piattaforma se l’evoluzione del tool prevede sforzi consistenti e duraturi.
Team di supporto verso esiti diversificati
Il modo tradizionale di fornire supporto è attraverso un team di generalisti in gradi di assistere i clienti/utenti finali su tutti i servizi erogati dall’organizzazione. Quando la velocità del cambiamento e la dimensione dell’organizzazione sono limitate, questo modello può essere economico ed efficace. Quando però la velocità di cambiamento o la dimensione dei prodotti/servizi erogati cresce, le cose cambiano perché il team di generalisti non riesce a mantenere la sua conoscenza sui servizi/prodotti al passo con la loro velocità di evoluzione. Un modello migliore prevede:
- team di supporto accoppiati a team Stream–Aligned;
- gruppi di persone di brevissima durata (swarming) per la risoluzione degli incident (war room).
In caso i team di supporto siano proprio necessari, dovrebbero affiancare i team Stream–Aligned nello stesso spazio fisico o virtuale, in modo da maturare la massima consapevolezza possibile sul prodotto/servizio e, contemporaneamente, restituire ai team Stream-Aligned feedback proveniente dal campo, mantenendo i diversi stream il più indipendenti possibile tra loro. Quando si verifica un incidente in produzione, il team di supporto cerca inizialmente di risolvere il problema in autonomia, ma se non ha successo, crea rapidamente una war room temporanea con membri dei team Stream-Aligned di riferimento che sono a portata di mano.
Team di Architetti verso Enabling-Team part-time
il pattern più efficace per convertire un team di architetti è un Enabling Team part–time, corrispondente a un chapter o una gilda, come viene spesso chiamato nelle organizzazioni. Part-time perché i suoi membri devono diventare membri di team Stream–Aligned o Platform Team, e spendere la maggior parte delle loro energie nel realizzare cose concrete. Le decisioni architetturali dovrebbero essere prese dai team operativi, e non imposte da persone esterne.
Affettiamo il monolite
Molti problemi nello sviluppo software derivano da confini non chiari tra i diversi team e le loro responsabilità. Il tutto aggravato tipicamente da una architettura in cui le diverse parti sono tenacemente accoppiate tra loro: il “monolite”.
Esistono diversi tipi di monolite di cui essere consapevoli prima di iniziare a fare cambiamenti, Vediamoli di seguito.
Applicazione monolitica
Una singola, grande applicazione con molte dipendenze e responsabilità, che espone molti diversi servizi e user journey.
Monolite Database-Level
Composto da diverse applicazioni o servizi accoppiati sullo stesso schema di DB, rendendo difficile modificare, testare e rilasciare ciascuna parte in modo indipendente.
Build monolitica
Usa un gigantesco sistema di Continuous Integration per ottenere una nuova versione anche del componente più piccolo e, solo in teoria, indipendente dal resto.
Release monolitica
Un insieme di piccoli componenti impacchettati insieme in una release. La build dei componenti può avvenire in pipeline di Continuous Integration indipendenti, ma il test può avvenire soltanto in un ambiente condiviso statico senza service mock.
Modello monolitico (“singola visione del mondo”)
Software che cerca di forzare un unico linguaggio di dominio e un’unica rappresentazione attraverso molti contesti differenti. Flessibilità e adattamento sacrificati sull’altare della consistenza .
Pensiero monolitico
Pensiero “one-size-fits-all” che impone ai team restrizioni non necessarie sull’uso di tecnologie o modelli implementativi. Standardizzazione a tutti i costi con lo scopo di minimizzare la variabilità, che semplifica le brame di risparmio e di controllo del management sui team, ma adun costo elevato e occulto. Privare i team della libertà di scelta, imponendo un singolo stack tecnologico o un singolo set di strumenti, mina la qualità del lavoro, la creatività, e, in ultimo, la motivazione delle persone.
Workplace monolitico
Un singolo modo di organizzare gli ambienti di lavoro, per qualunque team o persona, senza riguardo alle reali necessità collaborative e comunicative.
Spezzare il monolite con criterio
Come visto in precedenza, affettare un monolite correttamente è un’operazione che deve tenere in conto i team e il loro carico cognitivo, e la necessità di rendere i team il più autonomi e indipendenti possibile tra di loro. Altrimenti il rischio è di spezzare sì il monolite, ma generando un sistema di interdipendenze malsane: un “monolite distribuito”.
Bisogna anche evitare che, nel risolvere i problemi causati dal monolite, si generino altri problemi quali bassa consistenza tra le diverse parti, duplicazioni accidentali di dati, UX incoerente, aumento di complessità legata a sistemi distribuiti.
I piani di frattura del monolite
Un approccio efficace alla suddivisione dei monoliti è il concetto di “piano di frattura“ [1] mutuato dalla geologia. Un piano di frattura è una superficie di giunzione naturale che consente a un sistema di essere diviso facilmente in due o più parti. È possibile rompere un monolite combinando diversi piani di frattura:
Bounded Context del dominio di business
Il bounded context [2] è un concetto del Domain Driven Design. È un’unità internamente consistente per partizionare un dominio più grande. Un esempio: servizio di streaming on-line che può essere partizionato in tre bounded context ben allineati con aree di business: media discovery (trovare nuova musica), media delivery (lo streaming verso gli ascoltatori) e licensing (gestione dei diritti musicali, pagamento delle royalties). Identificare i bounded context richiede un’approfondita conoscenza del dominio di business unita a conoscenze tecniche.
Compliance regolatoria
isolare dal monolite le parti soggette a specifica regolamentazione (sanitaria, finanziaria, etc.) per non costringere tutta l’organizzazione alla conoscenza di questi aspetti regolatori, e per non obbligare aree non critiche del sistema a sottostarvi.
Frequenza di cambiamento
Ci sono sistemi in cui le diverse parti necessitano di cambiamenti con frequenze differenti ma in un monolite ciascuna parte si muove alla velocità della parte più lenta. Ad esempio, le funzionalità “ricerca” in un catalogo potrebbero richiedere una frequenza di cambiamento molto più lenta degli algoritmi di Machine Learning che suggeriscono agli ascoltatori nuova musica. Separando queste due parti si ottiene che la necessità di business guida la velocità di cambiamento, invece di avere un monolite che impone una velocità fissa per tutto quanto.
Ubicazione dei team
Quando per determinati team non è possibile avere una completa co-locazione, o una configurazione remote-first, è meglio spezzare il monolite in sottosistemi per team in differenti ubicazioni. In questo modo l’organizzazione può sfruttare la legge di Conway e allineare l’architettura del sistema ai vincoli comunicativi imposti dalla geografia.
Rischio
In un prodotto/servizio, possono coesistere diversi profili di rischio, solitamente legati a differenti livelli di desiderio di cambiamento da parte di diverse classi di clienti/utenti finali. Ad esempio, un prodotto SaaS multi-tier potrebbe avere milioni di utenti nel suo livello gratuito, e solo alcune migliaia nel livello a pagamento. Modifiche a funzionalità gratuite molto popolari potrebbero ricadere in un profilo di rischio elevato, perché qualunque bug potrebbe significare la perdita di milioni di potenziali clienti. Al contrario, un bug in una feature a pagamento potrebbe comportare rischi minori, in quanto il servizio di supporto ai clienti paganti è in grado di mitigarne la temporanea insoddisfazione.
Performance
Diverse parti del sistema possono aver bisogno di diversi livelli di attenzione riguardo le performance e allo scaling. Il calssico esempio sono quei sistemi che possono comportare un “click day”. Separare il monolite secondo questo criterio può far in modo che soltanto un sottoinsieme dei team abbia il carico cognitivo di doversi sobbarcare queste problematiche, evitando anche che i costi associati allo scaling vengano sostenuti anche per parti del sistema che non li richiedono.
User Personas:
Ci sono monoliti in cui coesistono tipi diffrenziati di utente o svariati user journey. Suddividere seguendo questo criterio regala anche un robusto focus verso le necessità di specifici clienti, e quindi tipicamente una migliore customer satisfaction.
Tecnologia
Suddividere in base alla tecnologia è un po’ l’ultima spiaggia. Questo tipo di criterio è solitamente l’unico utilizzato nelle organizzazioni tradizionali (team UX, team FE, team BE, team QA, etc.) e ne abbiamo già visto le disfunzioni. Tuttavia ci sono situazioni in cui tecnologie molto vecchie e difficilmente automatizzabili possono richiedere team dedicati, ma con l’accortezza di preparare l’organizzazione a evolvere nel medio periodo verso architetture e tecnologie più moderne. Anche perché team dedicati a vecchie tecnologie potrebbero avere problemi motivazionali. In questo scenario è facile cadere nella tentazione di avere due team Stream-Aligned, uno che si dedica alla manutenzione del “vecchio” sistema e uno che si dedica al costruzione del “nuovo” sistema che dovrà rimpiazzare quello vecchio, magari impiegando mesi o anni prima che avvenga la sostituzione. Questo è un antipattern perché, separando il lavoro di manutenzione del vecchio dal lavoro di costruzione del nuovo, il feedback proveniente dal campo si perde e esaurisce nel team di manutenzione, e il team che sta costruendo il nuovo sistema perde la possibilità di beneficiarne e costruire un prodotto migliore. Approcci più efficaci prevedono:
- di avere un solo team che si occupa di entrambi i sistemi, sempre che non superi i limiti imposti dal numero di Dunbar;
- spezzare i due sistemi, vecchio e nuovo, secondo un analogo piano di frattura, e assegnarne le corrispondenti funzionalità risultanti ai due team;
- se i due precedenti approcci non sono praticabili, assicurarsi per lo meno che i due team lavorino a stretto contatto in modalità Collaborazione (questa modalità di interazione viene approfondita poco sotto).
Custom
Con il termine custom, stiamo indicando piani di frattura specifici per una data organizzazione poiché talvolta, in particolari contesti, possono essere identificati altri piani di frattura naturali. La cartina di tornasole per l’applicabilità di un piano di frattura è abbastanza facile da individuare: l’architettura risultante genererebbe team più autonomi, con meno dipendenze, e con minore carico cognitivo? Se la risposta è affermativa, allora ci siamo. Naturalmente raggiungere questi risultati richiede un po’ di sperimentazione all’inizio. Una semplice euristica che può aiutare a capire se la strada intrapresa è quella giusta è chiedere al team e al resto dell’organizzazione: “Sarebbe semplice offrire al cliente/utente finale o al resto dell’organizzazione questo servizio? Sarebbe possibile consumarlo efficacemente senza frizioni?“. In caso di risposta affermativa, questo sottosistema può essere un buon candidato per l’assegnazione a un team dedicato.
E ora… andate e comunicate (con parsimonia)
In molte organizzazioni, interazioni tra team e responsabilità mal concepite sono fonte di frustrazione e inefficacia. Si può anche dire a un team che deve essere autonomo e autoorganizzato, ma, se per completare il lavoro i membri del team sono costretti a interagire con molti altri soggetti esterni al team, autonomia e autoorganizzazione sono parole vuote…
Ciò che bisogna evitare è la necessità dei team di dover comunicare con tutti gli altri team per riuscire a portare avanti il loro lavoro. La comunicazione è più efficace quando è intermittente.
Collaborazione, semplice scambio di informazioni, facilitazione
Team Topologies definisce tre modi di interazione tra i team:
- collaborazione: lavorare a stretto contatto con un altro team;
- X-as-a-service: offrire o consumare qualcosa con minima collaborazione;
- facilitazione: a offrire o chiedere aiuto a un altro team per rimuovere impedimenti.
Formalizzare le modalità con cui i team interagiscono aiuta a valutare l’efficacia del loro lavoro grazie alla definizione esplicita di interfacce tra di essi. Infatti, grazie alla legge di Conway, ci si aspetta che queste interfacce avranno riflesso nell’architettura del sistema che viene sviluppato.
Queste modalità di interazione dovrebbero diventare delle abitudini per i team. Offrendo e pretendendo dagli altri team queste modalità, un team può beneficiare di una migliore chiarezza degli scopi di ciascuno, un aumento dell’engagement, una riduzione della frustrazione nei rapporti con gli altri team. Un elemento chiave di Team Topologies è proprio nelle scelta consapevole che due team fanno tra scegliere se collaborare su qualcosa, oppure se scambiarsi qualcosa come servizio.
Modalità Collaborazione
La collaborazione promuove l’innovazione e una rapida discovery, ma rende opachi i confini di responsabilità tra i team. È una modalità adatta quando è richiesto un alto livello di adattabilità in situazioni complesse, incerte, esplorando nuove tecnologie o tecniche di lavoro; va bene durante le fasi iniziali dello sviluppo di un nuovo sistema, o in periodi in cui c’è bisogno di scoprire velocemente nuove informazioni. In questi contesti è efficace perché consente di evitare costosi passaggi di consegne tra team. La collaborazione avviene tra gruppi con differenti insiemi di competenze allo scopo di mettere in comune la conoscenza e l’esperienza di molte persone per risolvere problemi sfidanti.
Ci sono due modi di vedere team che interagiscono usando la collaborazione.
- Due team con conoscenze e responsabilità diverse che lavorano insieme su un piccolo insieme di cose: mantengono sostanzialmente le loro responsabilità ed esperienza per le loro reciproche aree di competenza, lavorando su uno specifico sottoinsieme di attività e dettagli.
- Il lavoro in comune può essere completo: c’è in atto effettivamente una fusione integrale dei due team che mettono insieme tutte le capacità e conoscenze. Necessario prestare attenzione che il limite massimo del “numero di Dunbar” — 15 unità — non venga superato.
In entrambi i casi, i due team devono avere responsabilità congiunta per l’outcome complessivo della loro collaborazione, perché si creano confini sfumati. Senza responsabilità comune, c’è il pericolo di una perdita di fiducia in caso qualcosa vada storto.
Il fatto che il costo della collaborazione sia elevato — i membri dei due team aumentano il loro carico cognitivo dovendo interessarsi di parti nel dominio dell’altro team — implica che deve esserci un valore ancora più elevato nel prodotto della collaborazione.
Quando ricorrere alla modalità Collaborazione
Usare questa modalità per lunghi periodi di tempo non è opportuno. Se si osserva una necessità di collaborazione che non si esaurisce nel medio termine, si è probabilmente in presenza del sintomo di una scorretta assegnazione di responsabilità o di un inefficace mix di skill all’interno di almeno uno dei due team.
Un team dovrebbe usare la modalità di collaborazione al più con un solo altro team per volta. Usi tipici: team Stream-Aligned che lavorano con Complicated-Subsystem team; team Stream-Aligned che lavorano con Platform Team, Complicated-Subsystem team che lavorano con Platform Team.
Stili di comportamento nella modalità Collaborazione
Forte interazione, condivisione di spazi fisici e virtuali, mutuo rispetto, uso assiduo di pratiche quali pair e mob programming, lavagne condivise, sketching.
Modalità X-as-a-service
Questa modalità definisce chiare responsabilità e promuove una delivery predicibile, ma necessita di robuste capacità di Product Management. Funziona bene se i confini del servizio sono scelti accuratamente. È adatta a situazioni in cui uno o più team hanno bisogno di utilizzare una libreria, un componente, delle API che funzionino senza frizioni, usufruendone come di un servizio. È la modalità che funziona meglio durante fasi avanzate dello sviluppo e periodi che necessitano di delivery predicibile, in opposizione all’esplorazione di nuovi approcci e tecnologie.
Affidarsi a qualcosa “as a service” richiede un lavoro di alta qualità da parte del team che fornisce il servizio, e consente agli altri team di lavorare velocemente senza bisogno di sobbarcarsi aspetti non-core del loro lavoro. Se il servizio fornito richiede poca o nessuna interazione tra il team che fornisce il servizio e quello che lo consuma, questo è il segnale che la modalità di interazione X-as-a-service sta funzionando correttamente.
È necessario che il team fornitore del servizio abbia una forte responsabilità verso i suoi consumatori, anche in termini di UX e documentazione. Il servizio deve essere gestito in modo che il suo valore venga mantenuto alto, che le richieste di nuove feature siano tenute in considerazione, ma non realizzate automaticamente solo perché un singolo team consumer le ha richieste. L’evoluzione del servizio deve avvenire invece nel miglior interesse di tutta l’organizzazione, con un’attenta pianificazione concordata con tutti i consumatori.
Quando ricorrere alla modalità X-as-a-service
Un team può aspettarsi di usare l’interazione X-as-a-service con diversi altri team contemporaneamente, sia che sia un fornitore, sia che sia un consumatore di servizi. Usi tipici: team Stream-Aligned e Complicated-Subsystem team che consumano una piattaforma realizzata da un Platform Team; team Stream-Aligned e Complicated-Subsystem team che consumano un componente o una libreria realizzata da un Complicated-Subsystem team.
Stili di comportamento della modalità X-as-a-service
Enfasi sulla user experience e sulla developer experience, robuste capacità di Product Management, robuste conoscenze in ambito API design.
Modalità Facilitazione
Questa modalità soddisfa le situazioni in cui uno o più team possono beneficiare dell’aiuto attivo di un altro team che facilita, fa coaching, agisce da mentore per alcuni aspetti del loro lavoro. La Facilitazione è la modalità principale di lavoro per gli Enabling Team. Un team con competenze di facilitazione non prende parte alla realizzazione del sistema; “non pesca, ma insegna a pescare”.
La facilitazione richiede spesso importanti upgrade culturali nelle organizzazioni, sia perché implica che delle persone particolarmente esperte si astengano dal lavorare concretamente alla costruzione di qualcosa, sia perché questo tipo di interazione potrebbe inizialmente apparire poco familiare a persone tecniche abituate a “sporcarsi le mani” tutto il giorno.
Quando ricorrere alla modalità Facilitazione
Un team dovrebbe aspettarsi di usare la facilitazione con un piccolo numero di altri team contemporaneamente, sia che stia consumando, sia che stia erogando la facilitazione. Usi tipici: un Enabling Team che aiuta team di altro tipo; team di qualunque tipo che aiutano un team Stream-Aligned.
Stili di comportamento della modalità Facilitazione
Aiutare ed essere aperti a ricevere aiuto, mente aperta nei confronti di nuovi approcci, capacità di ascolto, facilitazione, coaching e mentoring.
Conclusioni
Anche in questa terza parte abbiamo visto temi importanti e molto concreti: per primo aspetto, in che modo trasformare la realtà aziendale affinché i team preesistenti possano evolvere in un uno dei quattro tipi di team previsti in Team Topologie; in secondo luogo, quali sono le tre modalità di interazione fra team diversi che vengono individuate nel modello.
Nel prossimo numero concluderemo la trattazione approfondendo il discorso sull’interazione possibile tra i vari tipi di team e tentando una valutazione finale dell’intero modello.
Riferimenti
[1] Frattura (geologia)
https://en.wikipedia.org/wiki/Fracture_(geology)
[2] Jan Stenberg, Defining Bounded Context – Eric Evans at DDD Europe. InfoQ
https://www.infoq.com/news/2019/06/bounded-context-eric-evans/
[3] Matthew Skelton – Manuel Pais, Team Topologies: Organizing Business and Technology Teams for Fast Flow. IT Revolution, 2019
https://teamtopologies.com/book