Cosa è l'Ingegneria del Software?
Già il termine Ingegneria può spavantare la maggior parte dei lettori.
Ma tranquillo, non preoccuparti.
Possiamo semplicemente considerarla come la disciplina che studia le varie fasi e processi che portano alla produzione di uno specifico software.
Prima di iniziare vorrei precisare due semplici concetti.
Le uniche accortezze che dobbiamo assolutamente mantenere per il corretto funzionamento dell'applicazione, riguardano sia la mancanza di ambiguità e inconsistenze nel prodotto che si sta per creare, sia la fornitura di un supporto veloce e sicuro per la riusabilità del codice.
Ma soprattutto un'attenta attività di test e manutenzione.
Tieni bene a mente questi consigli. In caso contrario il tuo programma non funzionerà e tutto ciò porterà ad un ulteriore spreco di denaro.
A tuo rischio e pericolo :).
Le Fasi dell'Ingegneria del Software
Possiamo schematizzare il processo di Ingegneria del Software nelle fasi:
- Analisi dei requisiti;
- Progettazione;
- Scrittura del codice;
- Collaudo;
- Manutenzione.
Ora viene il bello.
Ci concentreremo sulle prime due operazioni, facendo riferimento ad esempi riguardanti il progetto Work World nel quale viene descritta un'applicazione web che ha l'obiettivo di orientare l'utente nel mondo del lavoro.
Ma basta chiacchiere! Entriamo nel mondo dell'Ingegneria del Software cercando di capire insieme come bisogna muoverci e il significato dei termini che contraddistinguono questo ramo del mondo informatico.
Descrizione del Problema
Inizialmente è preferibile descrivere le specifiche iniziali (ovvero i requisiti principali) divisibili in:
- Funzionali: proprietà che l'applicazione deve obbligatoriamente avere;
- Non funzionali: proprietà opzionali.
Il tutto definito tramite la tabella MosCow che prevede le voci** Must Have** o Should Have in relazione alle caratteristiche in questione.
Requisiti Funzionali
ID | Descrizione | MosCow |
---|---|---|
0 | Il sito deve permettere la registrazione degli utenti | Must have |
1 | Nella registrazione, il sito deve chiedere quale ruolo avrà l'utente (richiedente/offerente) | Must have |
2 | Il sito deve proteggere i dati personali per la privacy | Must have |
3 | […] | […] |
Requisiti Non Funzionali
ID | Descrizione | MosCow |
---|---|---|
0 | Il sito deve permettere il caricamento di file di grosse dimensioni | Should have |
1 | Il sito deve incorporare un file *.doc all'interno del contenuto | Should have |
2 | Il sito deve mettere a disposizione degli utenti registrati, istruzioni esaustive sull'utilizzo dello strumento di caricamento del file *.doc | Should have |
3 | […] | [...] |
Ecco poi la fase dell'Analisi dei Requisiti, che riguarda:
- Specifica dei domini di applicazione del programma (dove sarà collocato una volta completo);
- Informazioni sull'applicazione;
- Funzioni che svolgerà;
- Prestazioni che può offrire;
- Interfacce richieste.
Questa fase dell'Ingegneria del Software è la più importante.
Errori di progettazione o di specifica dei requisiti, possono comportare una perdita di tempo, in quanto in alcuni casi bisogna tornare indietro a modificare il documento.
Ad esempio, se ci accorgiamo di un errore mentre stiamo scrivendo il codice, dobbiamo modificare le specifiche definite in questa fase).
Questi errori comportano anche una perdita economica, in quanto una superficiale descrizione del software può portare a un suo malfunzionamento finale.
Dunque, è bene fare particolare attenzione alla raccolta, alla descrizione e alla specifica dei requisiti che il nostro programma deve avere, per non incontrare poi nelle fasi successive gravi errori.
Specifica dei requisiti con Gellish
In questa tappa del nostro percorso che ci conduce alla progettazione del software, vengono inizialmente spiegati i significati dei concetti primari.
Ad esempio nel caso di World Work i termini Utente, Utente Richiedente e cosi via, approfondendoli ulteriormente tramite l'utilizzo del linguaggio di specifica Gellish.
Gli elementi che lo contraddistinguono sono:
- Concetti, definiti come gli elementi cardine del programma, che condensano la conoscenza (appunto l'Utente nel WW);
- Relazioni tra concetti;
- Caratterizzazioni che li legano.
Tutto utilizzando termini come è specializzazione di, è un sottotipo di.
Termine | Relazione | Termine |
---|---|---|
Utente-richiedente | È specializzazione di | Utente |
Utente-offerente | È specializzazione di | Utente |
Lavoro | È richiesto da | Utente-richiedente |
Lavoro | È offerto da | Utente-offerente |
Operazioni molto facili, vero? Ma fondamentali.
Specifica dei Requisiti con Alloy
La cosa si complica di più nella specifica dei requisiti tramite Alloy, elemento fondamentale poichè esprime i vincoli riguardanti la struttura e il comportamenti degli elementi dell'applicazione. L'obbiettivo di chi fa uso di questo linguaggio è quello di eliminare l'ambiguità tramite strumenti come:
- Fatti (fact): vincoli validi;Signature (sig): dichiarano classi principali degli insiemi che sono descritti nel corpo della sig;
- Predicati (pred): vincoli espressi tramite dei parametri, in modo tale che il modello SW rispetti determinate proprietà.
Ad esempio:
sig Utente {nome: String, cognome: String, [...]}
Dichiara l'insieme Utente con le sue proprietà.
fact NoStessiDati {some u,v : Utente | (u.mail != v.mail) and (u.username != v.username)}
Ci dice che non ci possono essere utenti con stessi dati di login (mail e username).
Ti consiglio di utilizzare come software Alloy Analyzer, il più completo in circolazione.
Diagrammi UML
Terminiamo la fase di specifica inserendo due diagrammi appartenenti al linguaggio UML, elemento cardine dell'Ingegneria del Software: esso permette di astrarre i concetti del prodotto in creazione dandone una visualizzazione grafica.
Saranno quindi fondamentali le rappresentazioni espresse tramite due diagrammi:
- Use Case Diagram: specifica le relazioni tra attori (es Utente) e il sistema (analizzandone ogni singola azione);
- Activity Diagram: fornisce una visione immediata e intuitiva della logica interna al programma.
Progettazione
Nella fase di progettazione vengono definite le strutture dati, le funzioni e i comportamenti in modo tale da rispettare i vincoli e i requisiti precedentemente riportati.
Tra i tanti, ci sono tre importanti strumenti che vale la pena approfondire: il diagramma delle classi, il linguaggio di progettazione OCL e le Reti di Petri.
L'Object Constraint Language
Il primo è sicuramente il metodo che più ci aiuterà nella fase della scrittura del codice: esso infatti rappresenta gli oggetti che compongono il sistema, con relativi attributi, comportamenti, e vincoli tra le varie classi.
Ogni classe ha un nome, attributi (privati e pubblici) e dei metodi.
Tra le classi possono esserci delle relazioni che possono essere descritte da classi di associazioni.
Altri concetti del diagram riguardano la generalizzazione, l'aggregazione e l'associazione tra le classi.
Tutto ciò, se prendiamo ad esempio un qualunque linguaggio ad oggetti, come Java, si riflette nel concetto di Classe, di Oggetti e anche Erediterietà e Polimorfismo.
OCL (Object Constraint Language) ha dei suoi particolari costrutti ed è basato sulle espressioni che arricchiscono l'espressività dei diagrammi.
In molti casi è strettamente collegato al Class Diagram.
Riprendendo sempre l'esempio dell'Utente che nel caso del World Work non può avere stessa mail di un altro, in OCL si tradurrà come:
Context Utente inv: Utente : AllIstances() → for all (u,w / u <> w => u.mail <> w.mail
Con Context
che incica il “contesto” in cui vale l' invariante (inv), ovvero un espressione che deve essere sempre valida.
Le Reti di Petri
Ecco lo strumento più potente dell'Ingegneria del Software.
Tramite questo, si può comprendere facilmente l'intero programma: basta infatti avere il concetto di posti, di transizioni (collegamento tra posti), di archi (che collegano posti e transizioni) e di token (stato attuale del sistema) affinché venga compreso anche il significato complessivo del software.
Eccone un esempio:
Siamo nel posto iniziale della rete di Petri, denominato Homepage: il token indica appunto che ci troviamo in quella posizione.
Da li possiamo muoverci in due direzioni: o verso la transizione registrazione come utente offerente, o registrazione come utente richiedente: entrambi poi portano al posto chiamato registrato al sito.
Da qui possiamo intuire che mentre le transizioni indicano delle azioni che il sistema attua, i posti indicano i vari stati che si evolvono nel nostro sistema.
Solo ora è possibile scrivere il codice.
Scrittura del Codice
Alla sua stesura deve essere affiancata una documentazione precisa e dettagliata, in modo tale che chiunque possa menttere mano all'elaborato per eventuali modifiche.
Si costruisce quindi il codice pensando ad un suo successivo riuso adeguando parti riutilizzabili per il nuovo uso ed integrando tutti gli elementi.
Collaudo
Ovviamente poi bisogna testarlo. Ciò deve essere effettuato dagli utilizzatori del programma, come ad esempio in un software gestionale, dai dipendenti di un'azienda.
Raccolti i risultati, si modifica il software allo scopo di eliminare eventuali difetti.
Si introducono nuove funzionalità richieste e si modifica il software per rendere più semplici correzioni, adattamenti e migliorie future.
Manutenzione
Anche questa fase fa parte dell'Ingegneria del Software.
Solo ora il nostro programma può essere commercializzato: ma non è finita qui.
Infatti, per una buona riuscita del software biosogna seguirlo, ovvero aggiornarlo periodicamente, fornendo un supporto costante verso gli utilizatori.
Ci Siamo?
Insomma progettare un software è come progettare una casa.
Se la sua costruzione non è preceduta da un'attenta attività di analisi (come ad esempio la geologia del terreno; vedi la Torre di Pisa), ma si inizia subito a costruire le fondamenta dell'edificio è assolutamente impossibile che il risultato sia per lo meno accettabile.
Cosi come se noi volessimo iniziare di getto a scrivere codice: il programma risultante sarà un disastro.