Capire l'architettura del software

Di Riccardo Golia

Per chi opera nel campo dell’informatica e in particolare si occupa di realizzare applicazioni, non è insolito affrontare discussioni inerenti tematiche legate alla progettazione del software. In questi frangenti emergono inevitabilmente concetti come quello di architettura, di disegno, di pattern, di idioma, ecc. Proprio per la loro natura astratta, non sempre questi concetti sono ben chiari: talvolta si tende ad attribuir loro un significato errato, estendendo oltre misura o travisando ciò che ciascuno di essi effettivamente rappresenta.

Questo articolo si pone come obiettivo quello di fare chiarezza su cosa sia effettivamente e che cosa rappresenti l’architettura del software, proponendo un insieme di definizioni più o meno formali e una serie di riflessioni utili a rendere più comprensibile il concetto.

In questa pagina

La definizione di architettura La definizione di architettura
Perchè l’architettura è importante? Perchè l’architettura è importante?
Gli stili architetturali Gli stili architetturali
Conclusioni Conclusioni
Riferimenti utili Riferimenti utili

La definizione di architettura

La progettazione di un’applicazione rappresenta l’insieme delle attività mirate ad individuare la soluzione implementativa migliore allo scopo di centrare gli obiettivi funzionali (e quelli non funzionali) attesi dal committente e dall’utilizzatore finale. Queste attività possono essere di varia natura, possono essere svolte in tempi e modi diversi a seconda dell’approccio utilizzato, ma in generale aiutano l’architetto e il team di sviluppo a prendere decisioni importanti, spesso di natura strutturale.

La progettazione condivide con la programmazione la tendenza ad astrarre la rappresentazione delle informazioni e le sequenze logiche di elaborazione, ma il livello di dettaglio nei due casi è differente. La progettazione costruisce una rappresentazione del software che riguarda diversi aspetti, si concentra sulla struttura del sistema e sulle relazioni esistenti fra le parti costituenti, identifica le operazioni logiche che devono essere svolte, individua le modalità con cui il sistema può interagire con il mondo esterno.

Il risultato della progettazione è la definizione dell’architettura del sistema, intendendo con questo termine l’organizzazione strutturale del sistema stesso, che comprende i suoi componenti software, le proprietà visibili esternamente di ciascuno di essi (l’interfaccia dei componenti) e le relazioni fra le parti [1].

Pensare all’architettura di un sistema software semplicemente come alla sua struttura è peraltro estremamente riduttivo. In realtà l’architettura è molto di più. Essa include le modalità con cui le diverse parti si integrano e interagiscono a formare un tutt’uno, considera gli aspetti legati all’interoperabilità con i sistemi circostanti, rappresenta il livello con cui l’applicazione soddisfa i requisiti funzionali, comprende le caratteristiche non direttamente legate ai casi di utilizzo, ma orientate a favorire l’evoluzione nel tempo del sistema a fronte dei suoi cambiamenti strutturali e in relazione all’ambiente in cui esso è inserito (scalabilità, performance, manutenibilità, sicurezza, affidabilità, ecc.). L’architettura pertanto è una rappresentazione che permette all’architetto di analizzare l’efficacia del progetto per rispondere ai requisiti stabiliti, di considerare e valutare le alternative strutturali in una fase in cui i cambiamenti abbiano ancora un impatto relativo sull’andamento del progetto e sul risultato finale e di gestire in modo appropriato i rischi che sono collegati alla progettazione e alla realizzazione del software.

La definizione data di architettura richiama il concetto di “componente software” nella sua forma più generale. Per componente software si intende qualsiasi entità facente parte di un sistema, a diversi livelli di dettaglio e granularità, dal semplice modulo applicativo (per esempio, una classe in un’applicazione basata sul paradigma ad oggetti) al sottosistema complesso (per esempio, un DBMS o un server LDAP). Ciascun componente entra a far parte dell’architettura in funzione del ruolo che esso ricopre. Ogni componente presenta caratteristiche peculiari (nella definizione denominate “proprietà visibili esternamente”) che influenzano il modo con cui ciascuna parte del sistema comunica e interagisce con le altre. L’architettura considera gli aspetti che sono inerenti la comunicazione tra le parti, si focalizza sulle modalità di interazione, tralasciando i dettagli di funzionamento interni.

Nei moderni sistemi software (per esempio, le applicazioni basate sul paradigma ad oggetti piuttosto che quelle orientate ai servizi) le parti interagiscono tra loro per mezzo di interfacce/contratti che suddividono in modo netto ciò che non è direttamente accessibile dall’esterno da ciò che è pubblico. L’architettura si concentra unicamente sul secondo aspetto tra i due, tralasciando i dettagli interni che in generale non influenzano (o quasi) il modo con cui i componenti si relazionano tra loro. Le interazioni fra i componenti possono essere semplici quanto una chiamata a funzione da un modulo applicativo ad un altro piuttosto che essere particolarmente complesse quanto un protocollo di comunicazione o un meccanismo di serializzazione.

In definitiva, alla luce di quanto detto finora, risulta estremamente azzeccata la definizione di architettura così come compare nello standard ANSI/IEEE Std 1471-2000 [2]:

l'organizzazione basilare di un sistema, rappresentato dalle sue componenti, dalle relazioni che esistono tra di loro e con l’ambiente circostante, e dai principi che governano la sua progettazione ed evoluzione.

 

Perchè l’architettura è importante?

In linea con le definizioni date, possiamo affermare che ogni sistema software ha una sua architettura dal momento che ciascun sistema può essere visto come un aggregato delle sue parti costituenti e delle relazioni esistenti tra loro. Nei casi più semplici e banali un sistema è composto da un singolo elemento costitutivo. In queste situazioni l’architettura non è assolutamente complessa e probabilmente è poco interessante, ma in ogni caso sempre di architettura si parla.

Nei casi più complessi il sistema software è formato da una serie di sottosistemi eterogenei che interoperano tra loro sfruttando meccanismi di comunicazione più o meno complicati, lavora su moli di dati e su basi di utenza non trascurabili e richiede livelli di sicurezza, affidabilità e reperibilità importanti. In questi casi risulta quasi immediato e naturale sentire la necessità di individuare l’architettura del sistema, anche se non sempre è così.

In molti progetti, anche non banali, capita di assistere a situazioni in cui le scelte architetturali sono lasciate alla buona volontà dello sviluppatore con più esperienza. In questi casi la progettazione viene vista dal manager di turno come una attività opzionale, dal momento che il focus ricade inevitabilmente sugli aspetti funzionali che sono direttamente associati alle richieste del committente e in genere legati ad un riconoscimento economico tangibile. Trascurare la fase di concept architetturale è però un errore che si può tradurre in costi e ritardi anche importanti rispetto a quanto pianificato e pattuito con il committente.

Lo studio architetturale ha un suo valore intrinseco. La rappresentazione dell’architettura consente la comunicazione e lo scambio di idee fra i componenti del team di sviluppo, alla ricerca delle migliori soluzioni implementative. Durante la fase preliminare del progetto, essa permette di evidenziare le decisioni progettuali critiche che possono avere un profondo impatto sul risultato finale. Determinate scelte possono rivelarsi davvero importanti per limitare i rischi progettuali e centrare gli obiettivi prefissati. Il ricorso a strumenti e metodologie come UML o affini in questo senso può tornare molto comodo per favorire la condivisione delle idee e per prendere le decisioni giuste, non sempre così scontate, dal momento che, come si è già avuto modo di dire più volte, i fattori di rischio nelle scelte tecniche sono sempre elevati quando si sviluppano applicazioni non banali e complesse.

 

Gli stili architetturali

L’architettura costituisce pertanto un modello relativamente compatto e comprensibile del modo in cui un sistema è strutturato e di come i suoi componenti collaborano fra loro. Questo modello è trasferibile, nel senso che gli schemi e gli stili architetturali utilizzati in un particolare progetto possono essere ripresi e applicati anche nella progettazione di altri sistemi. Essi infatti rappresentano un insieme di astrazioni che consentono agli architetti di individuare e rappresentare l’architettura secondo modalità ripetibili e prevedibili.

Esistono diversi stili architetturali fondamentali, ciascuno caratterizzato da:

  • un insieme particolare di componenti pensati per assolvere a determinati compiti,

  • una serie di “connettori” che permettono la comunicazione tra i componenti,

  • vincoli che stabiliscono le modalità di interazione tra le parti,

  • modelli semantici che consentono al progettista di comprendere le proprietà globali di un sistema analizzando le proprietà note delle parti costituenti [1].

Alcuni di questi stili sono menzionati di seguito [1]-[3]. Possono in ogni caso esistere anche combinazioni di stili.

Architetture basate sui dati

Il componente principale in questa architettura è l’archivio dei dati (per esempio un database, un repository documentale, il filesystem) a cui accedono le altri parti del sistema per eseguire operazioni di lettura e modifica delle informazioni in esso contenute. Fondamentalmente si tratta di una configurazione di tipo client-server dove lo storage ha per lo più un ruolo passivo, mentre la logica è distribuita nei diversi client che accedono alla sorgente dati. Questo tipo di architettura favorisce l’integrabilità, ovvero i componenti esistenti possono essere cambiati e ne possono essere aggiunti di nuovi senza interferenze per quelli già esistenti. Possono esistere meccanismi di notifica delle modifiche e di coordinamento del trasferimento dei dati (contesto transazionale).

*

Architetture a flusso di dati (pipeline)

Questo stile di architettura si rivela efficace nel caso in cui si abbia un insieme di dati in input da trasformare attraverso una catena di componenti e di filtri software al fine di ottenere una serie di dati in output. Ogni componente della catena lavora in modo indipendente rispetto agli altri, trasforma i dati in input in dati in output e delega ai componenti successivi le ulteriori trasformazioni. Ogni parte è incosapevole delle modalità di funzionamento dei componenti adiacenti.

*

Architetture “call and return”

Questa tipologia di architettura consente di definire una struttura del software relativamente semplice e scalabile nel tempo. Alcuni casi che rientrano in questa categoria sono:

  • architettura a programma principale/sottoprogramma (plugin): il programma principale richiama una serie di programmi componenti che a loro volta possono richiamare altri componenti;

  • architetture a chiamata di procedure remote (RPC): la distribuzione dei componenti software è tale da contemplare più nodi fisici;

  • architetture orientate agli oggetti: i componenti sono per lo più moduli applicativi che incapsulano dati e comportamenti (classi);

  • architetture orientate ai servizi: i componenti sono distribuiti, le operazioni sono accessibili tramite servizi remoti e la comunicazione avviene tramite lo scambio di messaggi sulla rete.

Architetture a livelli (layered architecture)

Questo stile di architettura prevede la strutturazione logica di un sistema software in strati sovrapposti (layer), tra loro comunicanti, ciascuno caratterizzato da una forte omogeneità funzionale. La forma più nota e usata riguarda l’architettura a tre livelli composta da: User Interface (UI) o strato di presentazione, dove vengono gestite le interazioni dell’utente col sistema, Business Logic Layer (BLL) o strato di business, dove sono presenti i servizi applicativi, e Data Access Layer (DAL) o strato di accesso ai dati, dove sono gestite le interazioni con il sistema di persistenza delle informazioni.

*

 

Conclusioni

Sebbene nella definizione di architettura si sia detto che essa non contempla i dettagli implementativi dei componenti software, un buon architetto deve comunque avere un occhio di riguardo anche nei confronti della tecnologia che va ad utilizzare. Questo significa che un buon progettista non deve avere una visione unicamente astratta del risultato che intende ottenere. Molte delle scelte che un architetto è chiamato a fare sono spesso dettate dalla consapevolezza e dalla conoscenza della tecnologia che utilizza. La necessità di operare scelte mirate e consapevoli per gestire opportunamente i rischi e le criticità collegate alla realizzazione del software obbliga necessariamente l’architetto a conoscere il contesto tecnologico in cui si trova ad operare.

Pertanto l'architetto è spesso chiamato a valutare anche gli aspetti implementativi delle soluzioni su cui lavora. Questo è possibile, per esempio, attraverso la fase di prototipazione dove egli può trovare conferma delle sue scelte anche di natura architetturale calate nel contesto tecnologico utilizzato. Dalla bontà delle decisioni prese dall’architetto deriva spesso la riuscita del progetto e, non meno importante, il rispetto e la considerazione del team di sviluppo in cui egli è inserito.

 

Riferimenti utili

[1] Software Architecture in Practice (2nd edition) – Len Bass, Paul Clements, Rick Kazman – Addison-Wesley Professional, 2003.

[2] ANSI/IEEE Std 1471-2000, Recommended Practice for Architectural Description of Software-Intensive Systems.

[3] Principi di Ingegneria del software (4a edizione) – Roger S. Pressman – Mc Graw Hill, 2004.