Cos’è l’architettura di un software?

Cos’è l’architettura di un software?

Prima di continuare a leggere questo post, provate a dare una risposta. Secondo vuoi cos’è l’architettura di un software?

Non si tratta di un discorso meramente teorico, finalizzato a trovare una definizione sterile. Al contrario, abbiamo bisogno di trovare una risposta perché da questa dipende la nostra capacità di valutare la bontà di una architettura. In altre parole abbiamo bisogno di sapere cos’è l’architettura di un software per avere un criterio che ci guidi nell’effettuare corrette scelte architetturali.

“Ma io non sono un architetto software, sono solo uno semplice sviluppatore!”. Mi sembra già di sentire qualcuno che, con questa motivazione, sta cercando di defilarsi dalla discussione. Questo “qualcuno”, magari inconsciamente, sta pensando che l’architettura del software sia qualcosa che riguarda i massimi sistemi, prerogativa di colleghi con i super poteri, che hanno smesso di sviluppare per dedicarsi allo sciamanesimo informatico. Riunitisi in stanze segrete, gli architetti cadono in trance ed elaborano progetti per la costruzione di cattedrali informatiche.

Se la pensate così, siete fuori strada. Vi anticipo che a mio avviso tutti gli sviluppatori, senza farci tanto caso, fanno continuamente scelte architetturali. Ma andiamo con ordine.

Se cercate sul web troverete diverse definizioni di architettura software, quasi tutte incentrate sulla scomposizione del sistema informatico in componenti e sulle reciproche interazioni. Piuttosto deludente, non trovate? Espresso così, il concetto di architettura risulta piuttosto statico, quasi a voler dire che, una volta definita, l’architettura non può cambiare. Inoltre non ci dà alcun indizio su come progettare una buona architettura. Spesso si utilizzano termini come “modulare”, “estensibile”, “scalabile”, per indicare delle caratteristiche di una buona architettura, che però non ci danno alcuna informazione sul vero metro di giudizio di un progetto: il costo.

A mio giudizio l’architettura di un software è semplicemente la somma delle scelte progettuali effettuate sugli aspetti non funzionali, ovvero non visibili all’utente finale. Mi riferisco in particolare alle scelte “importanti”, ovvero vincolanti per numerosi elementi del progetto e pertanto non semplici da cambiare, che indicano una precisa strada scelta tra le alternative disponibili. In questo senso l’architettura riguarda anche lo sviluppatore, anche se in contesti più circoscritti, quando si trova a dover scegliere tra implementazioni alternative di una particolare funzionalità.

A ben vedere non tutti gli elementi dell’architettura sono frutto di una valutazione e di una libera scelta. In alcuni casi infatti esiste una sola soluzione tecnologia che permetta di realizzare un particolare requisito. In questi casi non c’è alcuna scelta da fare. Ci sono inoltre elementi architetturali esplicitamente richiesti dal committente o, più raramente, anche dal PM. In questi casi è bene far mettere nero su bianco queste richieste, in modo che rientrino tra i requisiti software e rimangano distinti dalle scelte progettuali, di responsabilità del progettista.

Design Stamina Hypothesis

Ma quale criterio utilizzare per fare scelte architetturali? Come anticipato, a mio avviso a guidare le nostre scelte deve essere il costo. Ma in che termini? Ci viene in soccorso, come al solito, il buon Martin Fowler che ha formulato quella che lui chiama la Design Stamina Hypothesis. Secondo Fowler, nei contesti in cui la progettazione è assente (curva blu del grafico), si osserva una iniziale velocità nella realizzazione delle prime funzionalità che però, con l’aumentare del codice scritto, rallenta considerevolmente poiché diventa estremamente oneroso realizzare nuove funzionalità su una base di codice caotica. Al contrario, nei progetti che godono di una buona progettazione (curva rossa del grafico), si osserva una costante accelerazione della capacità di sviluppare sempre nuove funzionalità.

Martin Fowler - Design Stamina Hypothesis

Questa costatazione empirica, facilmente riscontrabile nei progetti reali, può essere utilizzata come criterio di valutazione delle scelte architetturali. L’ipotesi di Fowler infatti ci suggerisce che se dobbiamo effettuare una scelta architetturale, tra le diverse alternative possibili, dobbiamo scegliere quella che maggiormente velocizza lo sviluppo delle nuove funzionalità, rendendole quindi più economiche. Certo, scegliere ad esempio tra un DB commerciale come Oracle ed un DB opensource come PostgreSQL comporta di per se delle ricadute economiche sul progetto, ma la velocità con cui un team di sviluppo realizza nuove funzionalità ha una valenza superiore, poiché al contempo economica e strategica. Un team di sviluppo messo nelle condizioni di realizzare velocemente nuove funzionalità permette, ad esempio, di anticipare un concorrente, completare un progetto nei tempi imposti dal committente, preparare una demo in tempo utile, più in generale ridurre il feature lead time.

Assodato quindi che l’ipotesi di Fowler ha conseguenze tutt’altro che banali, è necessario approfondire altri due concetti. Infatti abbiamo detto che la bontà di una scelta architetturale si valuta in base a quanto questa agevolerà la realizzazione delle future funzionalità. Ma quali attività ricadono nel concetto di realizzazione? Inoltre, quanto è remoto il futuro da prevedere?

Costo per realizzare una nuova funzionalità

Per valutare l’impatto che avrà una scelta architetturale sulla realizzazione delle funzionalità del sistema, dobbiamo necessariamente individuare quali sono le attività che compongono l’intero processo di progettazione, sviluppo e rilascio. Spesso si tende a focalizzare tutta l’attenzione sulla fase di sviluppo software. Viene spontaneo infatti chiedersi come una scelta architetturale possa influenzare il codice sorgente. Niente di sbagliato, fintanto che la fase di progettazione e rilascio contribuiscono solo marginalmente al costo complessivo della realizzazione della funzionalità.

Ci sono però dei contesti, caratterizzati ad esempio da frequenti rilasci, da grandi team di sviluppo, dove la progettazione ed il rilascio hanno un peso preponderante sull’intero effort di realizzazione. In questi casi la valutazione degli impatti di una scelta architetturale non può limitarsi ad analizzare le ripercussioni sul solo codice sorgente.

Orizzonte temporale

Se è vero che la bontà di una scelta architetturale si valuta in base a quanto agevolerà la realizzazione delle future funzionalità, quanto lontano dobbiamo spingere la nostra previsione? Nell’ingegneria tradizionale, nonché nel modello di sviluppo del software a cascata, la progettazione si deve concludere prima dell’avvio della attività di realizzazione: plan your work, work your plan. Questo approccio richiede quindi che tutte le scelte architetturali debbano essere effettuate prima dello sviluppo software. Di conseguenza l’orizzonte temporale da tener presente nella fase di progettazione è massimo, poiché deve contemplare le necessità dell’intera fase di sviluppo. Gli architetti software tendono persino ad andare oltre, e si sforzano di fare ipotesi sulle potenziali evoluzioni del sistema, tanto più improbabili quanto più collocabili in un futuro remoto. In pratica gli architetti si trasformano in profeti.

Questo approccio predittivo è stato fortemente messo in discussione negli anni, poiché basato implicitamente sulla stabilità dei requisiti software che si è dimostrata utopica. Le metodologie agili, come l’Extreme Programming, hanno invece puntato su un approccio adattativo, in grado di reagire alla variazione dei requisiti. Ne consegue che, nel contesto agile, l’orizzonte temporale da analizzare per valutare una scelta architetturale è più ristretto e le scelte architetturali non devono essere tutte prese prima di avviare lo sviluppo. Anzi, le stesse scelte architetturali possono essere oggetto di refactoring durante lo sviluppo software.

Come regola di buon senso, ritengo che lo sforzo predittivo connesso ad una scelta architetturale debba essere proporzionato al costo di un successivo ripensamento. Tanto più sarà oneroso modificare una decisione progettuale, tanto più è necessario prevedere i suoi effetti a lungo termine.

Conclusioni

In questo post ho voluto condividere la mia visione dell’architettura di un software, certamente ispirata da grandi maestri. Secondo me l’architettura è un concetto tutt’altro che statico, composto da una miriade di scelte effettuate, lungo tutta la durata di un progetto, su aspetti invisibili all’utente finale ma che determinano il funzionamento del sistema. Obiettivo primario di queste scelte dovrebbe essere quello di velocizzare la realizzazione delle funzionalità di valore per l’utente. È necessario quindi analizzare le singole fasi di realizzazione di una funzionalità, per scoprire come velocizzarle, e prevedere, secondo un orizzonte temporale più o meno lungo, quali e quante funzionalità saranno impattate dalla particolare scelta architetturale.

Nel prossimo post proverò a fare qualche esempio di scelta architetturale pensata proprio per velocizzare la realizzazione del software.