Ingegneria del software
Per ingegneria del software si intende la branca dell'informatica che si occupa di definire medodi, formalismi grafici e strumenti utili a governare il ciclo di vita di un prodotto software, ovvero l'insieme delle attività da svolgere per la sua realizzazione, dall'analisi dei requisiti utente alla manutenzione dopo il rilascio.
Storia
La necessità di creare una disciplina che si occupi della realizzazione dei software nasce, intorno alla fine degli anni '60, dall'esigenza di sviluppare prodotti sempre più complessi ed evoluti che rispondano a richieste di grandi utenze. Il software come prodotto industriale, diventa anche oggetto di un attento esame per evolvere la capacità di realizzazione dello stesso.
Nasce in pratica un concetto simile alle ottimizzazioni da catena di montaggio per le industrie del secolo scorso che avevano similmente stravolto il modo di produrre apparecchiature meccaniche. Si cerca di identificare quei punti focali che devono governare la realizzazione di un buon prodotto software e soprattutto si cerca di definire formalmente cosa possa descrivere un buon prodotto software.
Fino alla nascita dell'ingegneria del software, la realizzazione di prodotti per computer era una mera attività di programmazione eseguita attraverso l'applicazione di discipline come:
Con l'avvento delle tecnologie informatiche anche nel settore industriale e commerciale, bacini di utenze non più tecniche si trovano a sentire l'esigenza di informatizzare le proprie strutture. Nascono l'incontro tra i requisiti dell'azienda cliente e le funzionalità che il programmatore deve realizzare.
Fino a questo stadio, la programmazione consisteva soprattutto nel mettere insieme una sequenza di istruzioni di codice per realizzare compiti ben specifici.
Differenti utenze generano nuove esigenze nella realizzazione di un software. Le aziende pongono ad esempio l'accento sulla necessità di definire processi di sviluppo del software che permettano di rispettare le scadenze fissate per ridurre i costi di realizzazione die prodotti stessi. Altri processi, voluti ad esempio da organizzazioni come il Pentagono, spingono fortemente lo studio di modelli che permettano di minimizzare fortemente la presenza di errori all'interno dei software.
L'ingegneria del software racchiude questi e molti altri elementi creando una scienza che si preoccupa effettivamente di concretizzare come permettere non più ad una singola persona ma ad un team di tanti sviluppatori, di realizzare un buon software.
Vengono identificati differenti ciclo di vita del software ovvero diversi processi che possono essere attualizzati da team per giungere ad un risultato comune. Ognuno di questi differenti processi identifica una serie di passi chiave da seguire per realizzare un prodotto sofware secondo uno stile di realizzazione differente per raggiungere differenti obiettivi.
Metodi di analisi
Numerose sono le metodologie proposte per guidare l’attività dei gruppi di lavoro per lo sviluppo di un prodotto software. Queste sequenziano e dettagliano le attività da eseguire per portare a termine con successo il ciclo di vita di un prodotto software. L’applicazione di queste metodologie è in parte automatizzata da una famiglia di strumenti nota come CASE Tool (Computer Aided Software Engineering).
A grandi linee tutte queste metodologie suddividono il ciclo di vita in 5 macro attività ben distinte e successive: analisi dei requisiti, progetto (design, nella dizione anglosassone), programmazione o codifica (programming), integrazione e test. In funzione della complessità del problema e del prodotto finale, queste fasi possono essere ulteriormente suddivise.
In generale durante l’analisi dei requisiti si cerca di capire quali debbano essere le carateristiche del software che si vuole sviluppare, e di formalizzarle in termini di funzionalità e requisiti tecnici. Questa formalizzazione è passata ai responsabili della progettazione per individuare gli algoritmi e le strutture dati utili alla soluzione del problema. Nella successiva fase di programmazione, le soluzioni così individuate sono implementate utilizzando un linguaggio di programmazione. In funzione della complessità del prodotto finale, la programmazione può essere suddivisa tra soggetti o gruppi di lavoro distinti, ciascuno responsabile della realizzazione di una parte o modulo del prodotto software atteso. In questo caso è necessaria una fase di integrazione dei moduli per avere il prodotto finale. Al termine è previsto il test del prodotto prima del rilascio.
Ogni attività svolta sul prodotto successivamente al rilascio è identificata come manutenzione. La manutenzione può essere correttiva se è finalizzata alla correzione di malfuzionamenti o evolutiva se mira a realizzare nuove funzioni.
In funzione delle relazioni organizzative tra le fasi, dal punto di vista metodologico si riconoscono due cicli di vita, illustrati nei prossimi paragrafi:
- ciclo di vita a cascata
- ciclo di vita a spirale
Ciclo di vita a cascata
A grandi linee, il ciclo di vita a cascata (waterfall nella dizione anglosassone) a volte noto anche come classico, prevede che le attività vengano svolte in modo strettamente sequenziale.
In generale durante l’analisi si formalizzano tutti i requisiti utente. Questa formalizzazione é passata alla progettazione per la sua soluzione che, nella successiva fase di codifica, é implementata in un linguaggio di programmazione. Infine si effettua l’integrazione ed il test del prodotto prima del rilascio.
Così semplificato, il ciclo di vita classico può essere rappresentato come:
File:Ciclo di vita a cascata.gif
da cui il richiamo alla cascata che troviamo nel nome.
A titolo di esempio, consideriamo il ciclo di vita definito con le MIL-STD-2167 da parte dell’autorevole DoD (Department of Defense, il Ministero della Difesa Americano) per il linguaggio ADA (altro prodotto del DoD).
Le MIL-STD-2167 dividono il ciclo di vita del software nelle seguenti 6 macro attività:
- ANALISI:
- Analisi dei requisiti: definisce cosa viene richiesto in termine di funzioni, senza specificare come esse devono essere realizzate
- Progetto preliminare: segue i requisiti, sviluppa un approccio al software che comprende anche modelli matematici, diagrammi di flusso funzionali e procedure di collaudo. In questa fase si definiscono la struttura generale e le operazioni del sistema, indicando anche le relazioni tra i principali blocchi funzionali (moduli)
- PROGETTAZIONE:
- Progetto esecutivo: effettiva scomposizione gerarchica e dettagliata di tali moduli; questa scomposizione continua fino a che un’ulteriore scomposizione porterebbe al codice del programma
- IMPLEMENTAZIONE:
- Codifica e verifica: scrittura e verifica dei programmi partendo dal progetto esecutivo e utilizzando le procedure di verifica
- Computer Software Code (CSC): integrazione e verifica delle unità comprese nei singoli sottosistemi
- Convalida dell’integrazione del CSC
Il maggior pregio di questo metodo di lavoro è certamente la semplificazione del controllo dell’andamento del progetto tramite la suddivisione del ciclo di vita in fasi successive ben definite. Le diverse metodologie che adottano questo ciclo di vita si distinguono essenzialmente per la suddivisione e specificazione delle fasi in sottofasi più elementari, nella definizione di standard di documentazione e nella individuazione di momenti di verifica al termine di ciascuna attività (milestone). Per ottimizzare il ciclo di vita, la scomposizione delle fasi in sottofasi persegue due obiettivi:
- assegnare a ciascuna fase la soluzione di problematiche specifiche
- rendere, per quanto possibile, le fasi indipendenti allo scopo di poterne parallelizzare le attività
Benché l’adozione di questi principi appaia estremamente produttiva, la loro applicazione pratica ha come effetto collaterale, soprattutto per i progetti di grandi dimensioni, un pericoloso scollamento fra le diverse attività, sia per le difficoltà di coordinamento che per la difformità delle metodologie e dei formalismi specialistici adottati. Ad esempio, normalmente l’individuazione delle strutture dati e delle funzionalità del sistema sono affrontate con metodologie diverse e, soprattutto per i progetti di grandi dimensioni, contemporaneamente e separatamente da gruppi di lavoro differenti. Nel primo caso i risultati sono formalizzati con uno Schema Entità-Relazione (ER o Entity-Relationship diagram nella dizione anglosassone) nel secondo con un metodo di scomposizione funzionale. Solo quando queste due attività terminano viene avviata una ulteriore attività di armonizzazione dei rispettivi risultati. Un ulteriore problema di questa impostazione deriva dalla necessità di terminare completamente tutta la fase di analisi e progettazione dell’applicazione per cominciare la programmazione e quindi verificarne sul campo le conclusioni.
Ciclo di vita a spirale
Ogni tentativo di descrivere formalmente una attività che coinvolge esseri umani dotati di libero arbitrio è destinato a produrre al più vaghe approssimazioni della realtà, e questo vale anche per lo sviluppo di software.
Sotto questo punto di vista, l'ingegneria del software può essere vista come il tentativo di applicare ad una attività con forte contenuto creativo, la scrittura di software, i metodi di organizzazione del lavoro della fabbrica, con l'obiettivo di realizzare un processo con costi e tempistiche certe e risultati prevedibili.
Un grosso limite del modello "ciclo di vita a cascata" è che nella realtà i risultati delle prime fasi di sviluppo devono spesso essere rimessi in discussione, sia durante l'implementazione che dopo il rilascio, nella fase di manutenzione, con modifiche che impattano tutte le fasi del ciclo di vita.
Gli sviluppatori e gli utenti infatti non riescono a capire tutte le implicazioni delle scelte fatte in fase di analisi dei requisiti, specifica e progettazione, senza avere in mano il prodotto finito, o almeno un suo prototipo. Nel caso del software, il prototipo è una versione semplificata del prodotto che si stà realizzando, con funzionalità ridotte o anche totalmente assenti (può ridursi anche ad uno schizzo dell'interfaccia grafica su un foglio di carta, o a una simulazione del funzionamento del programma con dati calcolati a mano).
La difficoltà di realizzare correttamente il software all'interno di un processo lineare ha portato anche a colossali fallimenti, con lo sforamento di tutti i vincoli di budget sia economico che temporale.
L'evoluzione del metodo di sviluppo classico, o se si vuole la presa d'atto del modo di lavorare nel mondo reale, ha portato a quello che viene descritto come "ciclo di vita a spirale": le fasi del ciclo di vita classico vengono percorse fino ad ottenere una prima versione estremamente semplificata del programma; questa viene utilizzata per comprendere meglio i requisiti degli utenti, le specifiche e la progettazione, portando alla realizzazione di una nuova versione più evouta. Il processo si interrompe in teoria quando viene costruita una versione soddisfacente, in pratica quando il budget è stato eccessivamente superato.