In questo articolo andremo a esplorare cos’è un feature team e come i microservizi possano favorirne il lavoro.
Prima di addentrarci nel tema, però, è importante capire qual è il problema che vogliamo risolvere grazie all’organizzazione in feature team e cosa ci ha quindi portato a fare questa riflessione e ad organizzarci di conseguenza.
Vi è mai capitato di trovarvi nella situazione in cui il vostro team ha bisogno del supporto da parte di un altro team, e la persona di riferimento cui dovete rivolgervi è molto carica di lavoro, ha poco tempo da dedicarvi e vi mette in attesa?
Quando si crea questo tipo di situazione, automaticamente si rallenta il time to market e si genera stress. Non solo, cercando di andare comunque in produzione, ci si ritrova ad abbassare la qualità tagliando o riducendo i test, facendo spaghetti code e aumentando così la possibilità di imprevisti e di bug che si presentano tipicamente nel momento meno opportuno.
Questa situazione genera caos e il sistema va fuori dal nostro controllo.
Un esempio concreto
Pensiamo a un Product Owner (d’ora in avanti PO) che gestisce un e-commerce e vuole mandare in produzione 3 feature:
- Catalogo prodotti
- Acquisto prodotti
- Review prodotti
Come si organizza?
Tipicamente un e-commerce avrà un’app mobile, un sito e un insieme di servizi lato back-end da sviluppare.
Avremo quindi due team, uno front-end e l’altro back-end, che partono insieme a sviluppare la prima feature, e cioè il catalogo.
A un certo punto, qualcuno del team front-end ha bisogno di supporto dal team back-end e alza la mano. Dal team back-end c’è disponibilità, ma anche bisogno di tempo per capire meglio gli aspetti da risolvere. Così, nel team front-end, piuttosto che stare con le mani in mano si procede a sviluppare la feature successiva.
Quando il team back-end è pronto a confrontarsi, è invece il team front-end ad essere immerso nello sviluppo e nei rilasci, e così prende tempo.
Si avvia così una catena di disponibilità che non si corrispondono finché finalmente si trova un momento comune per confrontarsi, trovare la soluzione e passare finalmente alla feature successiva.
Il tempo di risoluzione a questo punto sarà stato però piuttosto lungo, contando i vari rimbalzi che ci sono stati tra i team.
Come si evita questo balletto?
Stop starting, start finishing: smettiamo di iniziare nuovi task finché non abbiamo chiuso quelli in progress, e cioè quei task sui quali abbiamo speso del tempo ma che non abbiamo ancora messo in produzione.
Se ci fermiamo un momento a pensare, il codice che scriviamo ogni giorno non crea valore per l’utente finale e per il business fino a quando non va in produzione. Quindi perché far partire nuove attività quando quelle sulle quali abbiamo già speso del tempo non sono ancora andate in produzione? Perché non ci concentriamo a chiudere prima quei task?
In concreto, però, come bisogna procedere?
Quando i due team partono a sviluppare la feature A, e si presenta un problema che impone a un team di restare in attesa, questo non deve partire con lo sviluppo di nuove feature ma deve utilizzare quel tempo per lavorare su quanto fatto.
Ad esempio, migliorando la qualità del codice e le performance dei test, facendo code review e distribuendo conoscenza. Svolgendo quindi attività che possono essere facilmente interrotte quando il team di back-end sarà pronto a lavorare con noi al problema emerso.
In questo modo sarà più rapido chiudere la prima feature e passare alle successive, accelerare il time to market e di portare in produzione velocemente quanto richiesto dal cliente.
Questa è una soluzione che funziona bene quando emerge un problema alla volta, ma sappiamo bene che i problemi possono presentarsi anche numerosi nella stessa fase e rischieremmo così di passare più tempo a sistemare il nostro codice che a sviluppare.
Questo metodo, infatti, si applica bene a determinati sistemi. Se pensiamo alle ambulanze o ai pompieri, questi passano la maggior parte del tempo fermi per poter essere pronti a intervenire e ridurre il tempo di azione quando necessario.
In un contesto lavorativo dove però l’obiettivo è ridurre il time to market a costi sostenibili, questo metodo potrebbe non essere sempre il più efficace.
Come favorire la sincronizzazione?
Bisogna individuare il processo adeguato a seconda del business.
Torniamo al nostro PO e ai nostri team di back-end e front-end, ma ribaltiamo l’organizzazione:
Non più dei team che lavorano parallelamente su back-end e front-end, ma team che lavorano su singole feature in modo verticale, unendo competenze di back-end e front-end e operando end-to-end su tutto il ciclo di vita di una feature.
Ma cos’è un feature team?
È un team cross funzionale con competenze di UX/UI, implementazione di design grafico, sviluppo front-end, back-end, progettazione e mantenimento API, conoscenza delle logiche di business, test, deploy, operations. In pratica è un team che sa gestire in autonomia, come fosse una piccola startup, le sue feature con uno sguardo diretto verso l’utente finale che le utilizzerà.
Strutturarsi in questo modo non è certo semplice, ma è un buon modo per avere diversi team che procedono nello sviluppo delle feature seguendo il principio stop starting, start finishing e che su ciascuna feature, se compare qualche difficoltà, sono facilitati nell'affrontarla perché hanno tutte le competenze in un unico team.
La comunicazione è quindi più facile, c’è meno stress, la qualità e le performance aumentano.
Know-how e skills: senza di loro, il feature team fatica a collaborare
Conoscere il contesto di business e avere le competenze tecniche è fondamentale per la buona collaborazione del team.
Sappiamo quanto sia difficile essere dei veri e propri full-stack developer, ciò che è importante è che ci sia una specializzazione ma con diverse competenze che permettono di muoversi agevolmente all’interno di un determinato contesto. Si tratta del modello T-shape: verticalizzazione su una competenza ma capacità di muoversi orizzontalmente su tutte le altre.
Se mancano know-how e skills il team non riesce ad essere autonomo e finisce per organizzarsi in componenti più che in feature. Organizzarsi in componenti però è un rischio, perché le componenti potrebbero non incastrarsi correttamente tra di loro e portare a interdipendenze che generano a loro volta le attese di cui parlavamo inizialmente.
La legge di Conway
Secondo la legge di Conway l’organizzazione aziendale, e il modo in cui le aree comunicano tra di loro, si rispecchiano nel sistema IT dell’azienda.
Se la mia azienda è organizzata in silos, facilmente creerò dei monoliti anche nell’IT. Definendo come interagiscono i dipartimenti tra loro, avrò sistemi IT che conversano allo stesso modo.
Proviamo quindi a partire da zero per costruire il nostro sistema IT, pensando innanzitutto agli aspetti di business invece che al design architetturale.
Torniamo quindi al nostro e-commerce, con una serie di feature da implementare: disponibilità prodotti, catalogo, pricing, clienti, logistica, review e customer care, motori di comunicazione, fatturazione, ecc.
Se prendiamo queste feature e le dividiamo tra i nostri team, ognuno di loro avrà una propria responsabilità sull’insieme di feature.
Vediamo così come, partendo da un dominio di business, costruiamo architetture IT che rispecchiano l’organizzazione e quindi come lo stile architetturale a microservizi possa favorire il lavoro dei feature team.
È importante parlare di stile architetturale piuttosto che di design pattern quando si parla di microservizi perché come gli stili artistici sono interpretabili, anche il design utilizzato per i microservizi è interpretabile ed è da contestualizzare a seconda dei casi.
Nessuno vi dirà quanto è grande un microservizio, quanto è granulare e come deve comunicare. Dipende sempre dalla specifica realtà nella quale viene calato.
Perciò, tornando alle nostre feature, possiamo accorparle in due microservizi che non saranno troppo granulari.
Saranno microservizi non troppo difficili da mantenere e far evolvere. I monoliti sono più facili da creare, ma hanno bassa capacità di evolvere nel tempo. Con i microservizi, invece, se esagero nella granularità, poi avrò difficoltà nell’orchestrarli.
Una volta fatta la divisione in due microservizi, dovrò considerare per ciascuno l’esposizione su app Android e iOS e web.
Back-end for front-end
I due feature team che abbiamo creato e che gestiscono ciascuno un microservizio avranno sicuramente varie intersezioni di competenze e di necessità. Queste dipendenze porteranno a quei momenti di attesa di cui abbiamo parlato in precedenza.
Possiamo però ridurre ulteriormente questi momenti inserendo il concetto dei back-end for front-end: in poche parole, come team mobile che lavora anche con responsabilità su servizi di prodotto, disaccoppio tutti i servizi di back-end con un front-end (back-end for front-end, appunto) che mi permette anche di fare eventuali mock verso servizi customer e, allo stesso modo, il team web può disaccoppiare i servizi product da quelli customer.
Il back-end for front-end ha quelle logiche di prossimità che permettono di aggregare i dati e di esporli in modi sempre diversi. Un esempio possono essere le tabelle e le differenti visualizzazioni che possono avere sui vari dispositivi.
I team però evolvono e il bello dei microservizi è di poter creare architetture evolutive. Per questo si può pensare di spezzare i due microservizi creati in precedenza e magari andare a costruire un microservizio che gestisce tutta la parte di logistica, che nel tempo è cresciuta con il nostro business.
Tutti i servizi comunicano tra di loro attraverso un event broker e sopra possiamo mettere un API Gateway che disaccoppia e fa diventare piattaforma questo sistema.
Quelle che stiamo raccontando sono tutte evoluzioni che possono avvenire nel tempo. I team iniziano a conversare tra di loro grazie al fatto che ciascuno ha una visione chiara di business e possono condividere informazioni e dati.
Feature toggle
A questo punto diventa importante capire come fare il delivery del sistema e come fare a contribuire su questi servizi senza creare le attese e le code all’origine della nostra riflessione.
Ipotizziamo di avere sprint di una settimana e che per ogni sprint rilasciamo qualcosa in produzione.
La prima settimana i nostri tre team al lavoro sviluppano delle feature, senza però completarle tutte interamente per la fine dello sprint.
Cosa si fa? Si rilasciano tutte, anche quelle non completate? Farlo potrebbe creare poca affidabilità del sistema e avere ricadute negative sul nostro lavoro.
Introduciamo allora il concetto di feature toggle: rilasciamo le nostre feature ma spente, così possiamo comunque testarle anche in A/B testing oppure lasciarle totalmente spente. Nel frattempo il team continua a lavorare e accende i toggle quando deve rilasciare.
In questo modo, con un ritmo sostenibile e ricorrente, si rilascia in produzione senza che i team debbano essere iper sincronizzati per i rilasci delle feature.
Dobbiamo ricordarci, infatti, che le feature non sono user story ma sono aggregati di queste ultime perciò, se all’interno di uno sprint completiamo delle user story che non creano valore per l’utente finale, normalmente non le rilasciamo. Rilasciamo solo quelle che sono feature tangibili.
Il concetto di contribution
Può accadere di avere un problema su un componente, ad esempio una single sign on (SSO) page fatta in web da integrare su mobile. Come possiamo evitare i colli di bottiglia?
Chiediamo aiuto e introduciamo il concetto di contribution, che deriva direttamente dal mondo open source.
L’idea è creare un ecosistema all’interno del quale il codice è di tutti, in modo simile a quanto accade nel mondo open source: questa pratica è conosciuta anche come Innersource.
La collective code ownership è una delle pratiche di extreme programming e nell’open source è stata declinata creando team che sono maintainer e team che sono contributor.
Se riusciamo a portare all’interno delle aziende questo concetto di maintainer e contributor possiamo far evolvere la conversazione tra team in modo efficace evitando molti colli di bottiglia.
Ovviamente il team contributor sarà più lento del team maintainer ma acquisisce know-how col tempo e permette di ridurre molti rallentamenti futuri.
Certo, non è tutto semplice.
Come facciamo a fare in modo che le persone collaborino e diventino esperte di qualcosa che non conoscevano il giorno prima?
Dobbiamo tenere a mente questi 4 punti:
- Un prodotto, un product owner, un product backlog, un feature team: con un coordinamento unico centrale e un focus di tutti i team sul valore di business generato per l’utente, ogni riga di codice genera valore per l’utente finale. Niente è fatto al di fuori di quello che può generare maggior valore all'utente finale. Anche ciò che fa parte del back-end.
- Standard e processi emergono dal lavoro delle persone. Iniziate a fare mob programming regolari, code writing di tutti i team insieme, anche 8 persone alla volte, dove si conversa sul perché un codice è scritto in un modo, che problema risolve ecc. Fare code review regolari per definire standard di scrittura del codice.
- Non innamorarsi della tecnologia: usare le unconference per dare a ognuno l’opportunità di presentare delle idee, confrontarsi e sperimentare anche nuovi linguaggi.
- Esercitarsi sempre: come a scuola ci si esercitava sulle espressioni, anche scrivere codice è una professione che richiede tanto esercizio. I kata sono un’attività che aiuta a migliorarsi attraverso lo svolgimento di esercizi anche semplici ma sempre al massimo delle proprie potenzialità e capacità di sviluppo.
Conclusioni
- I feature team non sono solo un’opportunità dal punto di vista tecnico ma anche di business perché permettono di ridurre il time to market;
- I microservizi sono stili architetturali, non architetture, quindi devono aiutare, allineati con il business, la conversazione tra team;
- Il codice è di tutti, ed essendo di tutti ognuno ha diritto di metterci le mani e dovere di mantenerlo pulito e performante. Il contesto open source favorisce questo aspetto;
- L’organizzazione e l’architettura emergono ed evolvono da una buona conversazione tra le persone. Non copiamo e incolliamo modelli di altri ma facciamo emergere il nostro.
Questo articolo ripercorre il talk di Giulio Roggero, CTO e co‑founder di Mia‑Platform, presentato in occasione degli eventi: GDG Dev Party 2020, FEVR Verona 2020, CloudCOn on Air 2020.
Puoi rivedere il talk di Giulio Roggero in occasione di GDG Dev Party 2020 a questo link.
© MIA s.r.l. Tutti i diritti riservati