Introduzione all’ingegneria del software

  1. L’origine L’ingegneria del software è la disciplina che si occupa della produzione sistematica, scientifica e controllata del software. Essa include l’insieme di attività, metodi, tecniche e strumenti necessari per sviluppare prodotti software affidabili, sicuri, manutenibili e in linea con requisiti definiti. Il software non consiste solo nel codice: comprende documentazione, procedure operative, dati associati e tutto ciò che concorre al suo funzionamento e alla sua comprensione.
  2. Origini e crisi del software Negli anni ’50 e ’60, lo sviluppo del software era visto come un’arte: programmatori e utenti erano spesso la stessa persona (scienziati, ricercatori). I programmi venivano scritti per scopi specifici, senza processi strutturati o documentazione formale. Con l’espansione dell’informatica nacquero problemi: progetti complessi fallivano, i costi aumentavano, i tempi si allungavano, il software era inaffidabile. Questo fenomeno prese il nome di “crisi del software”. Le conferenze NATO del 1968 (Garmisch) e 1969 (Roma) segnarono la nascita ufficiale dell'ingegneria del software, sottolineando la necessità di applicare un approccio ingegneristico rigoroso al ciclo di vita del software.
  3. Programmi vs prodotti software Un programma è un artefatto personale: sviluppato da una persona per uso proprio, poco documentato, manutenuto in modo informale. Un prodotto software è invece un sistema complesso, destinato a utenti terzi, che richiede test, documentazione, affidabilità, manutenzione e conformità ai requisiti. Per produrlo serve un processo organizzato. Questa distinzione giustifica l’esistenza dell’ingegneria del software come disciplina autonoma.
  4. Principi fondamentali I principi cardine dell’ingegneria del software includono: • Rigore e formalità: applicare precisione, controlli e metodi formali quando necessari. • Separazione dei punti di vista: analizzare il sistema da prospettive diverse (funzionale, strutturale, comportamentale). • Modularità: suddividere il sistema in componenti indipendenti; preferire alta coesione e basso accoppiamento. • Astrazione: isolare gli aspetti essenziali, riducendo i dettagli non rilevanti. • Anticipazione del cambiamento: progettare con flessibilità per facilitare l’evoluzione. • Incrementalità: sviluppare per passi successivi con miglioramenti costanti. • Generalità: formulare soluzioni il più possibile generali ma senza eccessiva complicazione.
  5. Il processo software Il processo software comprende tutte le attività che trasformano i requisiti in un sistema finito. Le fasi principali sono: • Analisi dei requisiti — raccogliere, formalizzare e chiarire ciò che il cliente vuole. • Progettazione — definire architettura, componenti e comunicazione interna. • Implementazione — sviluppare il codice sorgente. • Verifica e validazione — assicurare che il sistema rispetti requisiti e qualità attese. • Installazione e rilascio — preparare l’ambiente e fornire il prodotto agli utenti. • Manutenzione — correggere difetti, migliorare funzionalità, adattare a nuovi contesti. • Smaltimento — dismettere il sistema e migrare i dati. Problemi diffusi includono requisiti incompleti, confusione tra fasi, test insufficienti e mancanza di comunicazione tra gli stakeholder.
  6. Strumenti CASE Gli strumenti CASE supportano automaticamente attività del ciclo di sviluppo: • Upper-CASE — modellazione dei requisiti, design, diagrammi UML, analisi formale. • Lower-CASE — generazione di codice, versionamento, test automatici, debugging. Il loro scopo è aumentare qualità, produttività, standardizzazione e tracciabilità del processo.
  7. Qualità del software La qualità può essere interna (struttura del software) o esterna (percepita dall’utente). Caratteristiche principali della qualità: • Correttezza — il software fa ciò che è richiesto. • Affidabilità — riduce la probabilità di malfunzionamenti. • Efficienza — usa le risorse in modo appropriato. • Usabilità — è facile da imparare e da usare. • Scalabilità — cresce al crescere dei dati o degli utenti. • Portabilità — funziona su piattaforme diverse. • Manutenibilità — può essere modificato senza costi elevati. • Riusabilità — componenti riutilizzabili in altri contesti. Metriche interne come complessità ciclomatica, densità di difetti e profondità dell’ereditarietà aiutano a stimare qualità esterna e futura.
  8. Modelli del ciclo di vita I modelli di sviluppo descrivono come organizzare attività e iterazioni: • Modello a prototipi — crea prototipi, mock-up e breadboard per chiarire i requisiti. • Incrementale — rilascia funzionalità prioritarie prima e completa il sistema via incrementi. • Iterativo — produce una versione completa iniziale e la migliora ciclicamente. • Modello a spirale — combina approccio iterativo e gestione esplicita dei rischi; ogni ciclo comprende: obiettivi, analisi dei rischi, sviluppo, verifica. Il modello a spirale è ideale per sistemi innovativi e ad alta incertezza.
  9. Gestione dei rischi Un rischio è un evento futuro incerto che può compromettere il progetto. Tipologie: • Tecnici — tecnologia nuova, prestazioni non garantite, integrazione complessa. • Organizzativi — personale inesperto, turnover, comunicazione inefficace. • Economici — budget ridotti, costi non previsti. • Esterni — dipendenze da fornitori, normative variabili. La gestione dei rischi comporta identificazione, analisi, priorità, piani di mitigazione e monitoraggio.
  10. I miti del software Miti del management: • “Più persone = sviluppo più rapido.” — spesso avviene il contrario (Legge di Brooks). • “Basta definire gli standard.” — senza formazione e controllo non servono. • “Outsourcing risolve tutto.” — senza supervisione il rischio aumenta. Miti del cliente: • “Definiamo i requisiti alla fine.” — il software non può adattarsi illimitatamente. • “Tutto è modificabile.” — i costi di modifica crescono enormemente nel tempo. Miti del programmatore: • “Il lavoro finisce al rilascio.” — la manutenzione è la parte maggiore del ciclo. • “La qualità si misura eseguendo il codice.” — la qualità nasce prima, nella progettazione. • “La documentazione rallenta.” — accelera nel lungo periodo. Conclusione L’ingegneria del software è un insieme di principi, tecniche e processi che permettono di sviluppare sistemi complessi in modo controllato, affidabile e sicuro. Sebbene la crisi del software non sia del tutto risolta, l’evoluzione dei metodi ingegneristici ha permesso di mitigare fallimenti, aumentare la qualità e migliorare la collaborazione tra stakeholder. Con l’aumento della complessità dei sistemi moderni, l’ingegneria del software è più essenziale che mai.

Riassunto_parte_2.pdf

Riassunto_parte_3.pdf

Diagrammi di macchina a stati I diagrammi di macchina a stati sono uno strumento fondamentale per rappresentare il comportamento di un oggetto in termini di stato. Essi descrivono il comportamento attraverso una serie di transizioni da uno stato all'altro, basate su stimoli esterni. Il concetto di stato è legato al ciclo di vita di un'entità, e l'insieme completo degli stati possibili rappresenta tale ciclo. I diagrammi di stato sono stati utilizzati fin dagli anni '60 e sono stati adottati dagli approcci orientati agli oggetti per modellare il comportamento di un oggetto all'interno di una classe. Ogni diagramma è associato a una classe e mostra il comportamento di un singolo oggetto durante il suo ciclo di vita. Per modellare un oggetto con una macchina a stati, è necessario: Individuare le condizioni interne (stati) significative per il comportamento dell'oggetto. Descrivere come e sotto quali condizioni l'oggetto passa da uno stato all'altro (transizione di stato). Identificare una sequenza di azioni associata alla transizione di stato. Identificare gli eventi che inducono transizioni di stato e/o azioni. Gli elementi base sono: stati significativi, transizioni di stato, condizioni, eventi e azioni. Mentre i diagrammi di sequenza modellano il comportamento di più classi che si scambiano messaggi, i diagrammi di macchina a stati si concentrano sugli aspetti dinamici di una classe durante il suo ciclo di vita, o di un sistema. L'enfasi è sull'evoluzione tra gli stati in risposta a stimoli esterni. Per rappresentare graficamente un comportamento tramite macchina a stati, è necessario rispondere a domande come: Quali sono gli eventi scatenanti? Quali proprietà deve avere l'oggetto per cambiare stato? Quale stato deve verificarsi per modificare il comportamento? Cosa succede in uno stato specifico al momento dell'evento? I diagrammi di macchina a stati sono utili per visualizzare stati e transizioni per un processo di controllo ottimizzato. Sono diffusi nella progettazione di sistemi di controllo, come la funzione "Acqua Stop" di una lavatrice. La rappresentazione grafica utilizza un grafo orientato con stati come nodi e transizioni come archi, etichettati con condizioni ed effetti.

Gli stati sono qualità distintive dell'oggetto, che influenzano il comportamento. Lo stato è caratterizzato dal dare la stessa risposta qualitativa a un evento. Solo un singolo stato può essere attivo in un momento. Gli stati sono rappresentati da rettangoli arrotondati. Lo pseudostato iniziale indica il punto di partenza, mentre lo pseudostato finale indica la conclusione. Considerando un motore, gli stati "spento" e "acceso" sono significativi. Le transizioni e gli eventi sono altri elementi chiave. La transizione modella il cambiamento di stato in seguito a un evento, rappresentato da una freccia con informazioni su evento, condizione di guardia e azione. Un evento è un'occorrenza nel tempo o nello spazio che determina il comportamento dell'oggetto. Un esempio è la funzione di controllo di accensione/spegnimento di un motore. Se il motore è spento e si preme Start, il motore passa da spento ad acceso. Non sempre c'è un cambiamento di stato in seguito a un evento, ma possono essere necessarie azioni. In questo caso, si può avere un'auto-transizione, ovvero transizioni che escono ed entrano nello stesso stato. Un esempio è la funzione di controllo di un menù a tendina. Altri concetti avanzati includono attività interne, che rispondono agli eventi senza transizioni, e stati con attività continue. Le attività interne sono rappresentate con la stringa: evento[condizione]/azione. Le attività interne hanno origine e destinazione nello stesso stato. Le attività di ingresso (entry) e di uscita (exit) sono attività speciali. È possibile definire stati in cui l'oggetto svolge un'attività continuativa. Un esempio è lo stato InRicerca, con l'attività do/intendendo do-activity. Gli stati possono condividere transizioni e attività interne, trasformandosi in sotto-stati e raggruppando il comportamento comune in un superstato. Un superstato contiene altri stati. Un esempio è una macchina a stati che regola la visualizzazione e l'inserimento di contatti in un social network. I diagrammi di attività illustrano il flusso di lavoro di un sistema, rappresentando una sequenza di azioni. Possono essere usati per rappresentare i processi aziendali, il flusso di lavoro, o per modellare il flusso di azioni in un caso d'uso.

A differenza dei diagrammi di macchina a stati, il focus è sull'attività e non su chi la svolge. Le azioni sono unità di comportamento che si susseguono per realizzare un'attività complessa. L'azione è rappresentata dal Nodo Azione, un rettangolo arrotondato con una voce verbale che descrive l'azione. Può avere una freccia entrante e una uscente. Le azioni operano su dati o entità informative (oggetti), rappresentati tramite Nodi Oggetto. È possibile aggiungere indicazioni dello stato ai Nodi Oggetto. Un'attività è rappresentata tramite un grafo diretto, con nodi che sono le azioni e gli archi che collegano i nodi azione, rappresentando i percorsi di esecuzione. I nodi di controllo specificano il flusso di esecuzione. Ogni diagramma ha un Nodo iniziale e un Nodo finale. Il token è un'entità di controllo che viaggia lungo il diagramma, passando dalle azioni. Il flusso dei token definisce il flusso di esecuzione, o flusso di controllo. Il flusso di controllo inizia al nodo iniziale, passa alle azioni e termina al nodo di uscita. Altri nodi di controllo includono: Fork: esecuzione in parallelo di più azioni. Join: esecuzione di un'azione solo quando le azioni precedenti hanno terminato. Decision: esecuzione di un'azione dipende da una condizione (guard). Merge: ricongiungimento di due o più flussi alternativi. I diagrammi di attività possono essere modularizzati, usando attività che richiamano altre attività. L'attività invocata è rappresentata come un insieme di azioni racchiuse in un rettangolo arrotondato, identificato dal nome dell'azione che lo richiama. Le partizioni raggruppano le azioni in base agli attori responsabili. I nodi segnali rappresentano l'accettazione di un evento o l'invio di un segnale. Sono di tre tipi: Segnale inviato: azione lanciata alla fine di un'azione. Segnale ricevuto/di accettazione: evento atteso dall'esterno. Segnale temporale: istante di tempo o termine di intervallo temporale.

Gli archi possono essere rappresentati in modi diversi, come connettori, o usando pin per il passaggio di parametri. Le regioni di espansione rappresentano azioni che avvengono per ogni elemento di una collezione. La fine di un flusso indica la fine di un particolare flusso senza terminare l'intera attività. I diagrammi UML offrono diverse viste del sistema. Ogni diagramma ha un ruolo diverso. I diagrammi delle classi descrivono le classi, le relazioni, gli attributi e le operazioni. I diagrammi dei casi d'uso rappresentano come il sistema può essere usato. I diagrammi di sequenza descrivono la collaborazione di oggetti per implementare un comportamento. I diagrammi di macchina a stati descrivono il comportamento di un oggetto in più casi d'uso. I diagrammi di attività illustrano il flusso di lavoro di un sistema. Altri diagrammi UML includono: Diagramma degli oggetti: istanze di oggetti e relazioni. Diagramma di package: raggruppamento di elementi UML. Diagramma di deployment: distribuzione fisica del sistema. Diagramma di temporizzazione: vincoli temporali. UML è un linguaggio di modellazione affermato per la sua notazione visuale, la sua evoluzione da linguaggi esistenti e la sua flessibilità. UML può essere usato con una prospettiva concettuale o software. I diagrammi UML dovrebbero essere usati per rappresentare vari aspetti delle entità, modulando la rappresentazione dei dettagli. UML è uno strumento di comunicazione e lavoro. L'uso di UML varia a seconda della fase di sviluppo del software. Nell'analisi dei requisiti, i casi d'uso, i diagrammi delle classi, i diagrammi delle attività e i diagrammi di stato sono utili. In fase di progettazione, i diagrammi delle classi, i diagrammi di casi d'uso, i diagrammi di sequenza, i diagrammi di package e i diagrammi di deployment sono utilizzati.

Riassunto_parte_5.pdf

Riassunto_parte_6.pdf

Riassunto_parte_7.pdf