software, ingegneria del-
Indice
Descrizione generale
Disciplina che si occupa di definire e rendere misurabili le proprietà connesse alla gestione dei processi di analisi, progetto, sviluppo e manutenzione di programmi (software), di medio-grande complessità. L'ingegneria del software come disciplina a sé stante, distinta sia dall'informatica propriamente detta, la computer science, sia dalle caratteristiche dei domini di applicazione e utilizzo dei programmi, prende avvio dagli inizi degli anni Settanta, quando si prende atto della cosiddetta crisi del software, ovvero del modello fino a quel momento dominante di produzione del software, in cui lo sviluppo di nuovi programmi era prevalentemente svolto o dagli stessi utenti finali, specie nel caso del software scientifico, o da organizzazioni esterne dotate di apparecchiature di grandi dimensioni, ma senza un preciso modello dell'attività. I tipici modelli ingegneristici, quantitativi e basati su caratteristiche fisiche del prodotto, male si applicano infatti a un'entità immateriale quale il software. Non solo, ma la pervasività dell'informatica fa sì che essa sia impiegata in domini completamente diversi e con esigenze diverse. Un modello artigianale della sua produzione non permette quindi di fare fronte alle diverse e complesse esigenze poste dal mercato. La risposta a questo problema è stata quella di definire dei modelli e degli standard da seguire per gestire le varie fasi del cosiddetto ciclo di vita del software. Si è trattato quindi di definire fasi, metriche e discipline che permettessero di prevedere costi e tempi necessari alla realizzazione di un progetto software.
Modelli del ciclo di vita
Il primo modello storicamente proposto per descrivere le fasi del processo software è quello sequenziale lineare, o a cascata, in cui si distinguono le fasi di analisi, progetto, codifica e test. L'analisi parte dall'identificazione dei requisiti del cliente e li trasforma in specifiche per il progetto. Quest'ultimo dettaglia le caratteristiche della soluzione, che poi la fase di codifica si occupa di implementare in un linguaggio di programmazione. Infine la fase di test verifica la corrispondenza fra le funzionalità e le prestazioni offerte dalla realizzazione e i requisiti essenziali, basato su una marcata divisione del lavoro all'interno delle organizzazioni. I meriti di questo approccio consistevano nel descrivere, per la prima volta, la costruzione del software come un processo per il quale si potevano identificare delle metriche che dessero ragione della sua complessità, dei modi per valutare lo stato di avanzamento del lavoro e sancire il passaggio da una fase a un'altra, attraverso obiettivi da raggiungere a scadenze fissate. Il limite di tale approccio sta nel non prevedere la possibilità di revisioni delle fasi precedenti una volta passati a quella successiva, dovendo quindi assumere la correttezza di ogni passo. Inoltre, il tempo intercorrente fra la discussione con il cliente dei requisiti dell'applicazione e la produzione di una soluzione, senza prevedere momenti di ridiscussione e di descrizione dello stato di avanzamento, aumentava il rischio di una discrepanza fra quanto prodotto e quanto originariamente richiesto. Nel tentativo di superare le limitazioni del modello sequenziale lineare, se ne sono proposti diversi altri, che sfruttavano anche miglioramenti tecnologici quali la disponibilità di nuovi linguaggi e paradigmi di programmazione e la diffusione di interfacce grafiche a manipolazione diretta. Per esempio, i metodi basati sulla prototipizzazione prevedono la presentazione all'utente delle funzionalità dell'applicazione attraverso la simulazione dei dialoghi fra programma e utente che si svolgeranno nell'applicazione finale e fornendo solo degli embrioni di realizzazione. Altri modelli sfruttano la definizione delle fasi tipica del modello sequenziale lineare ma introducono possibilità di revisione e di ciclicità. Per esempio, si può prevedere la possibilità di utilizzare diversi gruppi che lavorino in parallelo su diverse parti del progetto (Rapid Application Development), oppure di ripetere le fasi realizzando miglioramenti successivi ed eventualmente rimettendo in discussione scelte operate in una fase precedente, o infine di operare in modo incrementale, elaborando quindi un progetto complessivo come integrazione di diversi mini progetti ognuno dei quali aggiunge funzionalità a quanto prodotto nel precedente. Particolare accento sul coinvolgimento del cliente, e di tutti coloro coinvolti nella costruzione e nell'utilizzo del prodotto finale, quali addetti o utenti di un servizio, viene posto nei cosiddetti modelli centrati sull'utente, spesso basati su modelli di ciclo di vita a spirale o a stella. Nel primo, le fasi tradizionali sono precedute e seguite da una fase di discussione con il cliente e da una sua valutazione, mentre la fase di pianificazione è seguita da una di analisi dei rischi, che permette di identificare, e successivamente tenere sotto controllo, fattori che mettono a rischio la realizzazione del progetto. Nel modello a stella ogni fase è seguita da una verifica della correttezza e dell'applicabilità dei risultati della fase. Queste tecniche sono state particolarmente sviluppate dalla scuola scandinava di progettazione, in cui si punta a definire con gli utenti finali non solo le caratteristiche dell'applicazione, ma anche a riprogettare le pratiche di lavoro conseguenti alla sua introduzione. Lo Unified Process, sviluppato all'interno di Rational per opera dei creatori di UML mira a integrare diversi approcci in un modello incrementale e interattivo, guidato dalla definizione dei casi d'uso di interesse per l'utente. A partire dalla fine degli anni Novanta si confrontano due approcci alternativi, uno centrato su modelli formali e uno sulle pratiche concrete delle persone coinvolte nello sviluppo. Nella MDA (Model Driven Architecture) il processo di sviluppo è visto come il progressivo raffinamento di modelli formali, per ognuno dei quali è possibile definire una semantica, attraverso opportune regole di trasformazione. In questo approccio si punta a produrre un modello generale di prodotto, indipendente dalla concreta piattaforma (hardware e sistema operativo) su cui esso dovrà operare. Le caratteristiche di una piattaforma possono pertanto venire utilizzate come parametri per trasformazioni che producono modelli specifici per tale piattaforma, con l'obiettivo di automatizzare il più possibile il processo che porta dall'analisi dei requisiti (la cui definizione è invece lasciata all'esperienza umana), alla realizzazione del codice. In tutti questi approcci, i documenti di progetto diventano la base per i successivi interventi di manutenzione del software, resi necessari, oltre che per correggere eventuali difetti riscontrati una volta elaborato il progetto, per adeguare il software prodotto in precedenza alle evoluzioni tecnologiche e alla richiesta di nuove funzionalità. Al contrario, le tecniche di programmazione agile (agile programming) mirano a rendere più efficienti le pratiche quotidiane di progetto e sviluppo, riducendo al minimo gli aspetti formali e la produzione di documentazione. Esse sfruttano pratiche quali la programmazione a coppie (peer programming), in cui due programmatori si alternano nel ruolo di produttore di soluzioni e di critico delle soluzioni proposte, o il refactoring, basato sulla continua trasformazione del codice per renderlo più generale e ridurne la complessità. Molta enfasi è posta sulla collaborazione all'interno del gruppo di lavoro, attraverso riunioni frequenti, addirittura quotidiane, in cui discutere gli avanzamenti del progetto. Le tecniche di agile programming, pur offrendo vantaggi nella riduzione dei costi aggiuntivi di gestione del processo software, possono essere soggette, in assenza di una disciplina specifica, a una perdita di controllo sui fattori di rischio, e richiedono per funzionare un maggiore impegno da parte di tutte le figure coinvolte nel progetto. Indipendentemente dal modello adottato, negli ultimi anni si è posta come esigenza quella del riuso del software, cioè della possibilità di creare nuove applicazioni attraverso l'integrazione di componenti preesistenti. Questo comporta che la stessa produzione di nuovo software avvenga in modo da renderne possibile il riutilizzo. Il problema principale legato al reimpiego è la disponibilità di descrizioni precise delle funzionalità delle componenti e delle loro interfacce all'interno del sistema.
Metodi di valutazione dei costi di un progetto
Un fattore essenziale del successo delle organizzazioni produttrici di software è la capacità di produrre stime valide dei costi e dei tempi dello sviluppo di un progetto. Il primo metodo proposto è stato quello fondato sulle linee di codice necessarie per la realizzazione di un progetto. Basandosi sulle dimensioni dei programmi prodotti in precedenza per progetti analoghi, e considerando la produttività e il costo orario dei membri dell'organizzazione, è possibile stimare durata e costi del progetto. I problemi di questo metodo discendono dal fatto che esso non tiene conto della possibile diversa distribuzione dell'impegno nelle diverse fasi, per cui progetti con lo stesso numero di linee di codice, e quindi con uguale complessità realizzativa, possono avere differente complessità progettuale, per esempio derivante dalla maggiore o minore novità dell'applicazione o delle soluzioni tecniche adottate. Come alternativa, si sono sviluppati diversi metodi che forniscono stime quantitative di caratteristiche più astratte, legate alla definizione delle funzionalità del sistema o a particolari requisiti dell'applicazione, e che possano in qualche modo fornire una stima più accurata della complessità e delle particolarità del processo. In particolare, la possibilità di quantificare lo sforzo necessario nelle diverse fasi del processo permette di valutare i costi in relazione alle diverse qualifiche professionali delle figure coinvolte. Indipendentemente dalla tecnica adottata, è essenziale che le stime siano basate su serie storiche dei risultati, dei costi e dei tempi dei progetti precedenti, raccolte al termine di ogni progetto, e vengano analizzati i costi effettivi per aggiornare le serie storiche e individuare tendenze migliorative o peggiorative nella pratica dell'organizzazione.
Rischi e qualità del software
La produzione di software è soggetta a numerosi rischi: il primo nasce dalla mancata comprensione dei requisiti richiesti dal cliente e, quindi, dalla necessità di ridefinire in corso d'opera aspetti del progetto. Altri rischi derivano dall'ineguatezza delle tecnologie e dal personale a disposizione, dal superare i tempi e i costi previsti, da errori nel marketing. Per limitare al massimo i fattori di rischio bisogna in primo luogo pianificare incontri periodici con il cliente e, soprattutto individuare gli indicatori di rischio in modo da predisporre piani di gestioni adeguati. La capacità di prevenire e gestire i rischi è un indicatore della qualità del processo di produzione del software, accanto all'utilizzo di tecniche formali per la conduzione di revisioni dei prodotti delle diverse fasi, o al mantenimento di dati storici sui progetti conclusi. Un'efficiente gestione del processo di produzione del software è ritenuta essenziale per permettere di ottenere un'elevata qualità del software prodotto. Diverse organizzazioni hanno prodotto standard di definizione della qualità del processo e possono certificare un'organizzazione produttrice conforme a tali standard. Essi riguardano aspetti quali la produzione della documentazione, la conduzione di test e verifiche formali, la gestione della configurazione del software, per esempio mediante strumenti quali CVS. La valutazione della qualità del prodotto finale risulta infine dalla rispondenza ai requisiti, dall'aderenza agli standard propri del dominio di applicazione (per esempio quelli relativi alla difesa della privacy, alla sicurezza, o all'impiego di apparecchiature radiologiche per applicazioni mediche), oltre che a criteri di usabilità e di efficienza nelle prestazioni.