INTRODUZIONE
Cosa significa Ingegneria del Software?
L'applicazione di un approccio sistematico, disciplinato e quantificabile allo sviluppo, al funzionamento e alla
manutenzione del software; ovvero, l'applicazione dell'ingegneria al software. [IEEE Std 610.12-1990]
Software Developing vs. Software Engineering:
• Lo sviluppo del software (software developing) riguarda la scrittura di codice, lo sviluppo di un algoritmo per poi
istruire la macchina ad elaborare il linguaggio.
• L'ingegneria del software (software engineering) riguarda la comprensione e la gestione del processo di ingegneria
del software (i.e., Software Development Life Cycle) alla base della costruzione di un sistema SW (implementazione
di base problemi auto-contenuti come trovare un elemento in una sequenza, lavorare con una matrice e così via).
Qui non si sviluppa un algoritmo, ma un sistema.
Un sistema viene descritto per le sue funzionalità poiché non vi è un solo algoritmo da risolvere, ma più di uno,
perciò viene definito complesso.
Esempio: OPS (sistema elettronico del conto)
I sistemi di pagamento online (OPS) forniscono un ambiente elettronico per lo svolgimento di transazioni finanziarie.
Tradizionalmente, le persone eseguono le loro transazioni finanziarie manualmente autorizzando il loro istituto
finanziario a trasferire denaro dal loro conto a un altro conto (tramite assegni o bonifico bancario), pagando il
denaro effettivo. Il sistema OPS dovrebbe fornire le seguenti funzionalità:
1. Creare un account per una persona nel sistema OPS. Ogni conto OPS deve essere associato al conto bancario
(risparmi/assegni) del titolare del conto. (Identificare un conto bancario mediante l'unione di un numero di
instradamento e di un numero di conto).
2. Inizializzare l'account OPS con un credito prelevato dal conto bancario del proprietario.
3. Eliminare un account nel sistema OPS. Nota: l'eliminazione di un conto OPS può portare alla restituzione del
denaro disponibile sul conto bancario del proprietario, se presente.
4. Effettuare il pagamento periodico (settimanale/mensile) delle bollette su un conto OPS. Una transazione per il
trasferimento di una specifica somma di denaro (identificata dal titolare del conto) a un altro conto nel sistema OPS.
5. Informare il proprietario dell'account di un imminente pagamento periodico.
6. Informare il proprietario dell'account di qualsiasi transazione sul suo account, che si tratti di prelievo o deposito.
7. Avvisare il proprietario dell'account di un possibile rimbalzo del pagamento; vale a dire, se il denaro disponibile è
inferiore all'importo di un pagamento.
8. Generare una cronologia di tutte le transazioni per il proprietario dell'account mensilmente o su richiesta.
Un sistema software complesso, come l'esempio precedente, possederà diverse caratteristiche, funzionalità che
devono essere orchestrate e mantenute, per questo vi è bisogno di passaggi fissi. Ognuno di questi è “costruito” da
un gruppo di persone differenti, le quali a loro volta fanno parte di un team ancora più grande; per questo non ci
interfacciamo direttamente con la macchina (come invece succede in Python).
Questi “step” sono:
• Analisi SW (SW Analysis): contiene ciò che deve fare il sistema;
Funzionalità: ciò che deve fare il sistema (es. autentificazione tramite password)
Non funzionalità: ciò che caratterizza il mio sistema (es. quanto è reattivo il mio sistema)
Safety critical: se il mio sistema mantiene aspetti di sicurezza per l’uomo (es. sbarra treno se guasta
scende). Lo garantisco tramite il comportamento del mio sistema.
Business critical: se il sistema mi dà informazioni in tempi non ragionevoli pur essendo corretta,
poiché perdo transazioni.
• Progettazione SW (SW Design): come faccio il sistema (progettazione);
• Implementazione SW (SW Implementation): come implemento il sistema e dove;
• Test SW (SW Testing): faccio un test (diverso da fare debugging);
• Distribuzione SW (SW Deployment): mi stabilisce dove lo vado a collegare;
• Manutenzione SW (SW Maintenance): fase di mantenimento (in base a dove l’ho sviluppato, oppure se deve essere
aggiornato.
Questo definisce ciclo di vita del software. Parto da niente e costruisco qualcosa, ma non è detto che siano sempre
nello stesso ordine (ovviamente gli ultimi due step non potranno essere mai prima dei primi due).
Poca flessibilità del codice: La riscontro se devo rimetterci mano nel caso in cui io debba aggiungere qualcosa.
Programma: serie di oggetti che si comunicano messaggi.
Maintenance e flessibilità: minimizzano il costo del software quindi anche per l'azienda.
Nel regno in rapida evoluzione dello sviluppo software, due paradigmi di programmazione emergono come pilastri
fondamentali, ognuno dei quali modella in modo distintivo l'architettura del codice:
• Programmazione strutturata
• Programmazione orientata agli oggetti (OOP)
Programmazione strutturata:
La programmazione strutturata funge da modello fondamentale per l'organizzazione logica nella codifica. L'utilizzo di
processi e funzioni come elementi costitutivi principali comporta la suddivisione di problemi complessi in strutture
gestibili. Infatti, questo paradigma favorisce un flusso di controllo lineare paragonabile a una danza ben
coreografata, al cui interno le istruzioni e i cicli if-else sono orchestratori, armonizzando l'esecuzione del programma.
Caratteristiche:
• Approccio organizzativo: la programmazione strutturata enfatizza un approccio procedurale, in cui le attività sono
sistematicamente suddivise in procedure passo-passo. Questo approccio strutturato è particolarmente adatto per
scenari in cui una sequenza di esecuzione lineare è sufficiente per affrontare l'attività (ad esempio un problema
numerico).
• Flessibilità del codice: questo approccio strutturato può tuttavia limitare la flessibilità del codice. Il suo punto di
forza risiede nella sua semplicità, che lo rende più facile da capire per progetti più piccoli con meno complessità.
• Leggibilità e manutenzione: il flusso lineare della programmazione strutturata migliora la leggibilità del codice e le
strutture più superficiali contribuiscono a una manutenzione più semplice. Questo lo rende una scelta eccellente per
i progetti in cui la chiarezza e la semplicità sono fondamentali.
Programmazione orientata agli oggetti:
Nella programmazione orientata agli oggetti il codice trascende le istruzioni per diventare un'entità vivente
composta da oggetti. In questo paradigma, ogni cosa è trattata come un oggetto, ognuno dei quali possiede
proprietà e comportamenti unici. Le classi fungono da progetti, definendo le caratteristiche e le azioni che gli oggetti
possono intraprendere. Termini come incapsulamento, ereditarietà e polimorfismo emergono come principi guida,
promuovendo un codice che non sia solo funzionale ma anche modulare e riutilizzabile.
• Approccio organizzativo: la programmazione orientata agli oggetti si concentra sull'organizzazione del codice in
oggetti, rispecchiando le entità del mondo reale e le loro interazioni. Questo approccio è convincente quando si ha a
che fare con sistemi complessi in cui varie entità interagiscono e collaborano.
• Flessibilità del codice: la programmazione orientata agli oggetti promuove il codice modulare e riutilizzabile,
facilitando la scalabilità e l'adattabilità in progetti complessi. Questa flessibilità consente agli sviluppatori di creare e
riutilizzare gli oggetti, migliorando l'efficienza e la manutenibilità della base di codice.
• Leggibilità e manutenzione: gli oggetti e le classi nella programmazione orientata agli oggetti migliorano la
leggibilità del codice e il design modulare semplifica le attività di manutenzione. Questo lo rende adatto per progetti
su larga scala in cui l'organizzazione e la manutenibilità del codice sono fondamentali.
Confronto tra i due tipi di programmazione:
• Approccio organizzativo: la programmazione strutturata enfatizza un approccio procedurale, suddividendo le
attività in procedure passo-passo; invece, l'idea principale alla base della programmazione orientata agli oggetti è
quella di strutturare il codice in oggetti che rappresentano gli elementi del mondo reale e il modo in cui
interagiscono tra loro.
• Flessibilità del codice: per la programmazione strutturata il codice deve essere più flessibile e modulare, il che lo
rende adatto a compiti più semplici e lineari; invece, la programmazione orientata agli oggetti promuove il codice
modulare e riutilizzabile, facilitando la scalabilità e l'adattabilità in progetti complessi. La programmazione
strutturata assomiglia a un insieme di istruzioni ben organizzate, simile a un saggio ben strutturato , al contrario, la
programmazione orientata agli oggetti rispecchia gli scenari del mondo reale in cui gli oggetti interagiscono e
collaborano.
• Leggibilità e manutenzione: nella programmazione strutturata il flusso lineare migliora la leggibilità e le strutture
più superficiali facilitano la manutenzione; mentre nella programmazione orientata agli oggetti gli oggetti e le classi
migliorano la leggibilità del codice e il design modulare semplifica le attività di manutenzione.
Java:
È un linguaggio in cui tutto dipende dall'oggetto. Gli elementi del linguaggio Java sono:
• Fondamenti (tipi di dati primitivi, variabili, operatori, espressioni, istruzioni, metodi);
• Concetti di programmazione orientata agli oggetti (tipi di dati di riferimento, classi e oggetti, sottoclassi, interfacce,
enumerazioni, annotazioni, matrici);
• Concetti avanzati (Framework Java Collections e Java Generics, Framework JUnit che mi permette di testare
automaticamente ciò che ho scritto).
Debug (usando IDE): quando ho un output diverso da quello che vorrei applico il debug ovvero controllo e correggo il
codice (è diverso dal testing).
Introduzione all'Unified Modeling Language (UML):
L'Unified Modeling Language (UML) è un linguaggio di modellazione visuale universale nel campo dell'ingegneria del
software. Consiste in un insieme di diagrammi integrati e ha lo scopo di specificare, visualizzare, costruire e
registrare i componenti di un sistema software. La specifica UML è progettata per supportare la maggior parte dei
processi di sviluppo orientati agli oggetti esistenti. Questa è una notazione standard per la modellazione di sistemi,
ma non un metodo per progettare un sistema. Per utilizzare UML, è necessario applicarvi un metodo. Poiché UML
non è vincolato da alcun metodo di modellazione specifico, può essere applicato da qualsiasi metodo di
progettazione richiesto.
Il diagramma UML (activity diagram) descrive il sistema come elenco di funzionalità e chi usufruisce di esso. Uno di
questi è il diagramma delle classi, il quale è anemico, ovvero vi sono scritti solo gli attributi e non la logica delle loro
interazioni.
Diagrammi e modelli di casi d'uso UML per SW (funzionale) Specifica dei requisiti:
Figura 1: Diagramma dei casi d'uso (da uml-diagrams.org)
Diagrammi di classe per la modellazione di progetti SW, sia dal punto di vista concettuale che software:
Figura 2: Diagramma di classe (da uml-diagrams.org)
Altri diagrammi:
BPMN:
BPMN è l'acronimo di Business Process Modeling Notation ed è uno standard creato e mantenuto da The Open
Management Group. È un linguaggio visivo che consente la descrizione e l'ottimizzazione dei processi aziendali, ma è
neutrale rispetto al fornitore e il significato preciso degli elementi grafici e
delle relazioni sono definiti in una specifica. È un metodo per mappare
l'approccio a un processo aziendale, consente di creare una
rappresentazione visiva di una pratica o di un processo aziendale complesso. È un linguaggio di modellazione
orientato ai processi. I diagrammi in BPMN mostrano tutte le attività che fanno parte di un processo.
Il BPMN serve a schematizzare un processo ed ha una semantica di flusso, ovvero un inizio e una fine.
Petri Nets: Strumento diagrammatico per modellare la concorrenza e la sincronizzazione in sistemi
distribuiti. È molto simile ai diagrammi di attività ed è utilizzato come ausilio alla
comunicazione visiva per modellare il comportamento del sistema. È basato su solide basi
matematiche e le varianti delle Petri nets sono ampiamente utilizzate come tecnica di
modellazione del flusso di lavoro.
Chat GPT:
Chat GPT è un programma di intelligenza artificiale che genera dialogo. Creato da Open AI, questo chatbot ad alta
capacità utilizza algoritmi di apprendimento automatico per elaborare e analizzare grandi quantità di dati per
generare risposte alle richieste degli utenti. Questo programma di elaborazione del linguaggio che applica in maniera
più performante la NLP (Natural Language Processing) e viene usato nel software Engineering, è in grado di
comprendere il linguaggio umano mentre viene parlato e scritto, permettendogli di capire le informazioni che gli
vengono fornite e cosa “sputare” (dare come output). Un essere umano può digitare una domanda e ChatGPT
“risputa” (dà come output) una risposta facilmente comprensibile, in una varietà di formati con clausole precise.
ChatGPT consente agli sviluppatori di abilitare test del codice in tempo reale o guidati da prompt in diverse istanze
per garantire che il processo di codifica diventi più efficiente e fornisce un'ampia gamma di suggerimenti e asserzioni
basati sulle funzioni e sulle variabili utilizzate in quel particolare codice per consentire test completamente
personalizzati del codice per quel particolare ambiente (questa operazione può essere particolarmente utile nelle
successive fasi di debug e documentazione).
ChatGPT può essere sfruttato per eseguire il debug di migliaia di righe di codice per l'identificazione degli errori e
quindi eseguire nuovamente il debug in base a qualsiasi messaggio di errore ricevuto. Indipendentemente dal fatto
che tu sia un veterano, esperto o che abbia appena iniziato, in questo caso particolare, ChatGPT può essere prezioso
per scansionare il codice e suggerire possibili correzioni. Utilizzato in modo efficace, può aiutare gli sviluppatori a
svolgere le loro funzioni in modo più efficiente, eliminando le laboriose ore trascorse a identificare il problema da
risolvere. Inoltre, questo dovrebbe rivelarsi particolarmente utile quando si scrivono casi di test e si documenta il
processo di debug per identificare cosa ha causato il bug in primo luogo.
ChatGPT può essere sfruttato per assistere o, in alcuni casi limitati, eseguire l'intero processo di documentazione:
• Forward engineering: generare in modo esplicito i diagrammi UML
• Reverse engineering: è in grado di analizzare codice complesso, contestualizzarne e comprenderne la logica e
sviluppare una spiegazione appropriata della funzionalità del codice. Ancora più importante è il fatto che il linguaggio
specifico utilizzato in tale documentazione può essere adattato alla persona che lo legge considerando le sue abilità
e il livello di comprensione. Immagina di non dover spiegare e rispiegare come funziona il codice in base a chi legge
la documentazione. Di conseguenza, gli sviluppatori possono dedicare più tempo alla codifica piuttosto che
documentare ciò che fa il loro codice.
Il modo più eccitante, se non il più efficace, in cui ChatGPT promette di rivoluzionare ciò che significa essere uno
sviluppatore è la generazione di codice. Con la sua funzionalità di generazione di codice, ChatGPT funziona
efficacemente come un assistente di codifica personale che comprende le preferenze di codifica e il linguaggio
naturale degli utenti e li trasforma in codice eseguibile. In questo modo si promette di portare un'efficienza senza
precedenti a tutta la generazione di codice, poiché è possibile utilizzare semplici prompt dei comandi per produrre
codice. In altre parole, la generazione di codice che avrebbe richiesto pochi minuti può ora essere eseguita in pochi
secondi. Inoltre, questo dissipa i timori della generazione completa del codice da parte di ChatGPT, poiché i
programmatori possono assumere un ruolo di supervisione sul codice generato. Questo, insieme ad alcuni degli altri
vantaggi discussi, ha un grande potenziale di risparmio di tempo e può massimizzare la produttività.
Vari cicli di sviluppi software:
-Modelli prescrittivi: scrivere qualcosa per poi aggiungere nuove cose
• Modello a cascata (Waterfall model)
• Modello di processo incrementale (Incremental process model)
• Modello a forma di V (V-shaped model): usato nei safety critical
-Modelli di processo evolutivo:
• Modello di prototipazione (Prototyping model)
• Modello a spirale (Spiral model)
-Modelli Agile:
• Scrum
• eXtreme Programming (XP)
Committente: chi richiede il lavoro. Nel modello Agile viene richiamato più volte, mentre nel Prescrittivo viene
consultato solo all'inizio. JAVA
Java environment:
Java è un potente ambiente di programmazione generico (powerful general-purpose programme, ovvero non è
legato al contesto in cui opera, quindi è un sistema generico) sviluppato da James Gosling presso Sun Microsystems
nel 1995 e acquisito da Oracle Corporation nel 2010. La tecnologia Java è una piattaforma (in realtà, 4 piattaforme)
e, allo stesso tempo, un linguaggio di programmazione.
Ha introdotto il concetto di Java Virtual Machine, ovvero un linguaggio che perora la interdipendenza dalla macchina
(come Phyton che però non è una macchina virtuale, infatti ho un interprete per Python). In Java il mio programma è
indipendente dalla mia macchina virtuale, quindi neutrale, quindi la Java Vi
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Appunti Ingegneria del software
-
Appunti corso completi per superare esame di Ingegneria del Software
-
Appunti di Ingegneria del software
-
Appunti completi corso Ingegneria del Software