Infrastruttura, approccio greedy e qualita’

Sulla mailing list di xp e’ stata sollevata la questione dell’approccio all’architettura in XP. Io non ho la presunzione di parlare per conto di alcuna metodologia, ma tendo ad apprezzare molto i risultati che ottengo quando riesco a impormi di non fare scelte in anticipo.

Riporto qui la mia posizione sull’architettura e sul ruolo dell’architetto, come espressa sulla ML, con piccole modifiche per evitare riferimenti esterni, e che non vuole essere altro se non la mia attuale percezione del problema :

Se vediamo l’architettura come l’insieme di quelle decisioni che sarebbero troppo costose da cambiare ex-post (non ricordavo chi lo diceva, ma mi e’ stato fatto notare che probabilmente mi arriva da Fowler) io credo che le capacita’ architetturali debbano manifestarsi proprio nel disinnescare quelle decisioni e renderle inoffensive per il futuro, questo per me passa dalle spike, per affrontare le incognite tecnologiche, come suggeriva Uberto, e dal tdd, per garantire un design disaccoppiato e coeso.

L’obiettivo e’ che ogni modifica sia localizzata, anche modifiche che in altri sistemi sembrerebbero inesorabilmente “strutturali” (che e’ un altro modo per dire “architetturali”, che e’ un altro modo di dire “costa troppo per cambiarlo”).

Ecco, per me e’ questo che dovrebbe fare un architetto. Che e’ poi quello che dovrebbe fare uno sviluppatore; se poi si lo si vuole chiamare “architetto” a me va benissimo, basta che passi piu’ tempo a programmare e condividere la sua conoscienza di quanto ne passi a diagrammare.

Anche dopo solo due storie di solito la scelta del framework dovrebbe avere piu’ elementi che se fatta in partenza. Il meccanismo per me rimane lo stesso anche in seguito, entrando in questioni come le transazioni, la scalabilita’ e via discorrendo.

Ammetto che per poter scegliere le cose all’ultimo bisogna aver fiducia nelle capacita’ degli sviluppatori, avere fiducia che creino del software sufficientemente malleabile. Per non fare “l’architetto”, e quindi non fare scelte a priori, devi avere degli sviluppatori che siano in grado di disinnescare quelle scelte che altrimenti sono critiche.

Premesso che gli sviluppatori siano in grado di farlo, magari concedendo un 40% di “junior”, non di piu’, io fino ad oggi credo che il maggior guadagno lo si ottenga programmando con il resto del team, a prescindere dalla propria esperienza, quindi mirando a rendere non critiche le scelte critiche e formando, dove serve, i “junior”.

In un team del genere non penso davvero sia necessario fare alcuna scelta strutturale a priori, nemmeno per quel che concerne la persistenza o il framework web. In un team diverso forse si dovrebbe davvero ricadere all’architetto vecchio stile. Argomento ricco.

Detto questo c’e’ la questione di come seguire una tattica greedy come quella del “fai solo quello che serve”, mi permetto di sintetizzare il discorso con l’affermazione : e se la tua soluzione ottima localmente si dimostrasse un cul-de-sac quando si manifestano necessita’ strutturali nuove che la tua implementazione minimalista non solo non e’ adatta a supportare, ma che di fatto ostacola con la sua sola presenza?

Per illustrare la mia idea al riguardo ho rispolverato photoshop e ho fatto qualche disegnino… l’architettura e’ chiamata infrastruttura di proposito, non rappresenta la qualita’ di design del codice, e potrebbe essere richiesta per motivi che esulano dallo sviluppo dell’applicazione in se’. In ML si parlava di reporting, tanto per dire.

La tonalita’ di grigio rappresenta il costo/difficolta’ per spostarsi in una qualunque direzione.

Quindi, senza ulteriori indugi, ecco il panorama che spesso si ci trova a considerare :

Se immaginiamo un approccio YAGNI ecco cosa succede : partiamo con un’infrastruttura minima per avere un senso nel contesto dello sviluppo (tanto per dire, la piattaforma software, il modello generale, client-server, solo client, cose cosi’) e partiamo a sviluppare features senza troppa fatica


A questo punto notiamo, ad esempio, che se ci appoggiassimo a un database e magari a un framework di persistenza le prossime features ci costeranno meno :

A questo punto siamo in un minimo locale, siamo molto contenti, ma ci fanno notare che la prossima iterazione ci sara’ da buttare dentro il reporting, o magari bisognera’ far scalare e parallelizzare. Siamo in una conca e abbiamo due alternative, distruggere quel poco di design che abbiamo inserito e iniziare a spingere su per la collina, con costi in continua crescita, l’affidabilita’ che cala e sempre meno strada fatta a ogni iterazione, la marcia della morte :

Altrimenti possiamo riconoscere che la qualita’ della nostra applicazione non ci permette di inserire a basso costo una funzionalita’ trasversale come la scalabilita’ e che dobbiamo appuggiarci a un’infrastruttura molto piu’ complessa, ma ormai e’ tardi, possiamo solo scegliere se tornare in dietro (sull’asse delle features), riscrivere tutto o quasi tutto con un’infrastruttura molto piu’ complessa (in giallo), o tentare un “porting” sulla nuova infrastruttura (in rosso), in entrambi i casi il cliente sara’ molto scontento, nel peggiore dei casi ci troveremo a dover aggiungere features in un sistema in grande transizione per “tener buono” il cliente :

A questo punto vediamo che in fin dei conti si poteva architettare tutto prima e spingere da subito verso “la valle” invece che la conca.
Se tutte le previsioni dell’architetto -qui una figura isolata, che guarda lontano, prima ancora che il cliente chieda lui scruta l’organizzazione in cui il prodotto andra’ a inserirsi, che prevede ben altro che le necessita’ tecniche, ma anche gli incerti del cliente- dovessero avverarsi si finisce nella valle, dove il lavoro puo’ iniziare con le migliori premesse. Se niente cambia si puo’ procedere e chiudere il progetto.

Cosa succede se invece l’architetto non c’e’, ma abbiamo un numero sufficiente di sviluppatori esperti nel far emergere l’architettura a ogni passo e tengono il sistema veramente disaccoppiato?
Nella mia umile opinione non si velocizza tanto il lavoro in se’, ma cambiano le curve dell’equazione, il sistema si piega bene a quello che vogliamo fare, quindi la valle e’ piu’ vicina, non c’e’ una grande collina tra la conca e la valle, piuttosto mi immagino che ogni aggiunta in features si trovera’ (se la modularita’ e’ veramente e intimamente tale) davanti a un panorama che si ripete, con caratteristiche geografiche piu’ piccole, piu’ facilmente percepibili anche da chi si trova a lavorare ogni giorno dentro al codice.

Mantenendo alta la qualita’ credo che possiamo mirare ad aggiungere features senza preoccuparci di pensare a priori piu’ di quanto non serva per evitare di andare in una direzione evidentemente sbagliata. Piu’ siamo in grado di fare evolvere l’architettura piu’ la parte grigio chiaro sara’ ampia, le propaggini delle colline saranno piu’ piccole, perche’ aggiungere infrastruttura non ci costera’ troppo, purche’ non si esageri (a destra) al punto che questa vada a intaccare il design e aumentare i costi di sviluppo.

Se ci chiedono di aggiungere infrastruttura a fini di integrazione col resto della piattaforma saremo in grado di aggiungerla senza pagare il prezzo di una ristrutturazione che diventa sempre piu’ difficile.

Ad ogni modo aggiungeremo infrastruttura gradualmente, la cosa che pero’ mi preme sottolineare e’ come, con del software molto malleabile, le conseguenze delle scelte sono piu’ visibili, sono piu’ “vicine” ed e’ piu’ semplice individuare la strada e questa strada sara’ probabilmente sempre rivolta verso l’aggiunta progressiva di nuove features, senza grandi balzi di fede o sforzi di ristrutturazione.

Io credo che questo profilo geografico si ottenga solo se l’architetto e’ lo sviluppatore e viceversa, altrimenti il codice si muovera’ su tutta un’altra geografia. Basta anche solo che la duplicazione cresca un minimo perche’ la “lumaca” ricompaia, le scelte diventino di piu’ lungo periodo e i rischi di queste scelte aumentino, basta che per modificare la gestione dell’accesso al database si debba andare a toccare piu’ di un singolo punto perche’ questa diventi ristrutturazione e la collina avanzi per bloccarci nei nostri movimenti a destra.

L’approccio greedy (fai solo quello che serve, la cosa piu’ semplice etc.) funziona solo se ogni giorno ridimensioniamo la geografia del nostro progetto mantenendolo snello a prescindere.