FormularioIngegneria del Software e Laboratorio di Programmazione: definizioni, teoremi e formule delle note, in ordine di capitolo
In questa pagina 13
1. Primi programmi in C++: compilazione, tipi e funzioni
C++ - introduzione, compilazione e linking
Definizione. C++ è un linguaggio compilato, staticamente tipizzato, standard (ISO) e multipiattaforma: lo stesso sorgente si compila su Windows, Linux e macOS.
C++ - tipi, variabili, espressioni e dichiarazioni
Definizione.
- Tipo: stabilisce la natura del contenuto, l'intervallo dei valori e l'insieme delle operazioni possibili su un oggetto.
- Oggetto: una regione di memoria che ha un tipo; il tipo dice quale dato ci può stare.
- Valore: la configurazione di bit contenuta nell'oggetto, interpretata secondo il tipo.
- Variabile: un oggetto con un nome (named object).
Definizione. Un'espressione calcola un risultato da uno o più operandi. È il più piccolo elemento con cui si esprime la computazione. Le espressioni semplici sono i literal (
10,'a',3.14,"Norah") e i nomi di variabili; si combinano con gli operatori in espressioni più complesse:int perimeter = (length + width) * 2;.
Definizione (dichiarazione). Una dichiarazione introduce un nome in uno scope, specificando il nome, il tipo e, facoltativamente, un inizializzatore. Un nome deve essere dichiarato prima di essere usato.
Definizione (definizione). Una definizione è una dichiarazione che specifica completamente l'entità dichiarata. Una definizione è anche una dichiarazione; ma alcune dichiarazioni non sono definizioni.
C++ - scope, namespace e librerie
Definizione. Lo scope è una regione del testo di un programma. Ogni nome è dichiarato in uno scope ed è valido (in scope) dal punto della dichiarazione fino alla fine di quello scope.
Definizione. Un header file è un insieme di dichiarazioni (alcune delle quali definizioni) di entità, utilizzabili da chi lo include. Esempio:
math.hdichiaradouble sqrt(double x);.
2. Classi e tipi definiti dall'utente
C++ - classi, membri e invarianti
Definizione. Una struct è una variante della
classcon un'unica differenza tecnica: i membri sono pubblici di default. Si usa quando ci sono dati ma non funzioni (retaggio del C).
Definizione (invariante). Un invariante è una regola che definisce i valori validi dello stato di un oggetto, e che il costruttore stabilisce e ogni funzione membro conserva.
C++ - enumerazioni e overloading degli operatori
Definizione. Un'enumerazione (
enum) è un tipo definito dall'utente molto semplice: specifica un insieme di valori rappresentati da costanti simboliche (gli enumeratori); una variabile di quel tipo è una scelta in questo insieme.
Definizione. L'overloading degli operatori (operator overloading) è la possibilità di definire il comportamento di quasi tutti gli operatori per operandi di tipo definito dall'utente (
classoenum), scrivendo una funzione di nome speciale:operator+,operator++,operator*,operator[], ...
3. Puntatori e memoria dinamica
C++ - puntatori, array e cast
Definizione. Un puntatore è una variabile che contiene un indirizzo di memoria, come un
intcontiene un intero. Ha un tipo:T*è un "puntatore aT", quindi sappiamo che tipo di dato si trova all'indirizzo che contiene.
Definizione. Un array è una sequenza omogenea di oggetti allocati in locazioni di memoria contigue: stesso tipo, nessuno spazio vuoto fra gli elementi. È indicizzato con
[], con accesso casuale, e non c'è controllo sulla lettura e scrittura fuori dai limiti: gli errori sono facili e difficili da trovare.
C++ - allocazione dinamica della memoria con new e delete
Definizione. Il distruttore
~T()è una funzione membro che il compilatore chiama implicitamente quando un oggetto deve essere distrutto: esce dallo scope, oppure è deallocato condelete.
4. Ciclo di vita degli oggetti e programmazione generica
C++ - costruttori, inizializzazione, copia e spostamento
Definizione. Il costruttore di default è un costruttore che si può chiamare senza argomenti. Ha senso quando esistono valori di default significativi:
stringè vuota,vectorè vuoto. Per i tipi built-in vale 0 (int{}è0,double{}è0.0).
C++ - template e programmazione generica
Definizione. Un template è un meccanismo che permette al programmatore di usare un tipo come parametro per una classe o una funzione. Il compilatore genera il codice necessario per ogni tipo per cui il template è specializzato.
5. Interfaccia delle classi e progetti su più file
CMake - build di progetti C++
Definizione (CMake). CMake è un meta-sistema di build: non compila nulla da solo. Legge la descrizione del progetto in un file di testo
CMakeLists.txte genera i file del sistema di build nativo (iMakefileper Make, un progetto per Visual Studio o Codelite, ...), che poi esegue la compilazione.
6. Ereditarietà e polimorfismo
C++ - ereditarietà, funzioni virtuali e layout degli oggetti
Definizione (ereditarietà pubblica). Con
class D : public B,Dè la classe derivata eBla classe base.Deredita tutti i membri diBe può accedere a quellipubliceprotected(non aiprivate). Esistono anche l'ereditarietàprivateeprotected, usate di rado.
Definizione (override). Una funzione di una classe derivata fa override di una virtuale della base se ha stesso nome, stessi tipi dei parametri e stessa constness. Allora la chiamata attraverso un puntatore o riferimento alla base esegue la versione della classe effettiva dell'oggetto.
C++ - polimorfismo
Definizione (polimorfismo). È la capacità di associare comportamenti specifici diversi a un'unica notazione generica. La stessa espressione, per esempio
obj.draw(), produce effetti diversi a seconda del tipo dell'oggetto.
7. Eccezioni, RAII e smart pointer
C++ - eccezioni e gestione delle risorse (RAII)
Definizione (RAII, Resource Acquisition Is Initialization). Tecnica per cui una risorsa si acquisisce nel costruttore e si rilascia nel distruttore di un oggetto: l'oggetto esiste solo se è stato possibile acquisire la risorsa. Vale per la memoria, ma anche per socket, buffer di I/O (compresi i file), lock.
C++ - smart pointer
Definizione (smart pointer). Classe template (header
<memory>) che si comporta come un puntatore (supporta*e->), detiene un puntatore e ne gestisce automaticamente la deallocazione. Elimina memory leak e dangling pointer, con un overhead molto ridotto rispetto a un garbage collector.
8. La libreria STL
STL - sequenze, iteratori e container (vector, list, string)
Definizione (sequenza). Una sequenza è un intervallo di elementi con un inizio e una fine, indicato
[begin, end):beginè il primo elemento,endè il primo elemento dopo l'ultimo. La sequenza si gestisce tramite iteratori.
Definizione (iteratore). Un iteratore è un oggetto che identifica un elemento di una sequenza (o uno dopo l'ultimo). Ricorda un puntatore, e ne ha la sintassi.
STL - algoritmi, predicati e lambda
Definizione (predicato). Un predicato è una funzione (o un oggetto richiamabile) che restituisce
trueofalse. Esempio:bool odd(int x) { return x % 2; }.
Definizione (function object). Un function object è un oggetto di una classe che ridefinisce l'operatore di chiamata
operator()(function call operator), quindi si usa come una funzione. La soglia è un dato membro salvato dal costruttore.
9. Ingegneria del software e Java avanzato
Ingegneria del software - prodotto software e processo di sviluppo
Definizione (ingegneria del software). È l'insieme di teorie, metodi e strumenti per lo sviluppo di software professionale; copre tutti gli aspetti della produzione (specifica, progetto, realizzazione, test, manutenzione) e anche la parte organizzativa, non solo quella tecnica. L'obiettivo è una produzione industriale e ripetibile, non un'arte.
Definizione (software). Programmi e documentazione. La documentazione non è accessoria: ciò che è ovvio per uno sviluppatore non lo è per un altro né per l'utente.
Definizione (verifica). Verification: il software è corretto? Soddisfa la specifica? E la specifica è corretta rispetto ai requisiti, assumendo vere le proprietà del dominio?
Definizione (validazione). Validation: i requisiti sono corretti? Sono completi, coerenti, e riflettono davvero il problema del cliente?
Java - generics, reflection e passaggio dei parametri
Definizione (identità dei dati). In Java ogni oggetto conosce la propria classe a tempo di esecuzione. In C un cast cambia solo l'interpretazione dei byte da parte del compilatore.
Definizione. In Java il passaggio dei parametri è sempre per valore. Per i tipi primitivi si copia il valore; per gli oggetti si copia il riferimento (l'indirizzo dell'oggetto), quindi il chiamante e il metodo vedono lo stesso oggetto ma hanno due variabili diverse che lo riferiscono.
Definizione (generics). Una classe o un metodo con uno o più parametri di tipo (
class CodaG<T>): il tipo degli elementi è deciso da chi usa la classe (CodaG<Integer>), e il compilatore rifiuta gli usi incoerenti (ci.aggiungi("30")non compila).
Definizione (riflessione). L'insieme di classi di
java.langejava.lang.reflectcon cui un programma ispeziona e manipola classi, metodi e campi a tempo di esecuzione, anche senza conoscerli a tempo di compilazione.
Concorrenza in Java - thread, sincronizzazione e pool
Definizione. Un thread Java è un flusso di esecuzione di un oggetto
Thread; il codice che esegue è il metodorun()di unRunnable. Tutti i thread di una JVM condividono lo stesso heap (ognuno ha il proprio stack).
Definizione. Due o più thread sono in stallo quando ciascuno aspetta un lock posseduto da un altro, e nessuno può procedere.
10. Requisiti e architettura
Ingegneria dei requisiti - requisiti funzionali e non funzionali
Definizione (ingegneria dei requisiti). Il requirements engineering (RE) è il processo con cui si stabiliscono i servizi richiesti al sistema dal cliente e i vincoli sotto i quali deve operare ed essere sviluppato. I requisiti di sistema sono le descrizioni di servizi e vincoli che questo processo produce.
Definizione (stakeholder). Chiunque sia interessato al sistema o abbia un interesse legittimo nel suo funzionamento.
Architettura del software - decisioni, organizzazione e stili
Definizione (architettura del software). L'organizzazione fondamentale di un sistema: i suoi componenti (sottosistemi, moduli), le relazioni tra loro e con l'ambiente, la loro distribuzione sulla rete e i principi che ne guidano il progetto e l'evoluzione.
Definizione (stile architetturale). Uno schema ricorrente di organizzazione di un sistema, con tipi di componenti, tipi di collegamenti tra componenti e vincoli sul loro uso. È ai componenti ciò che un design pattern è alle classi, ma a scala maggiore.
11. Responsabilità e design pattern
Principi GRASP per l'assegnazione delle responsabilità
Definizione (GRASP). General Responsibility Assignment Software Patterns: nove principi, espressi come pattern (problema-soluzione con un nome), per assegnare le responsabilità alle classi e progettare le interazioni tra oggetti. Il nome suggerisce l'importanza di afferrare (to grasp) i principi fondamentali della progettazione a oggetti. Il corso tratta i cinque principali: Creator, Information Expert, Low Coupling, Controller, High Cohesion.
Definizione. Una responsabilità è un contratto o obbligo di una classe. Si distinguono:
- di sapere (knowing): che cosa la classe deve conoscere (i suoi dati privati, gli oggetti collegati, ciò che può calcolare); derivano dagli attributi e dalle associazioni del modello di dominio. Esempio: un
Prestitoè responsabile di sapere la propria scadenza.- di fare (doing): che cosa deve fare (creare un oggetto, un calcolo), avviare azioni in altri oggetti, controllare e coordinare azioni di altri. Esempio: una
Bibliotecaè responsabile di creare iPrestito.
Definizione (accoppiamento). Misura di quanto una classe dipende da altre (ha attributi di quel tipo, chiama i loro metodi, ne conosce la struttura, estende o implementa). L'accoppiamento alto significa che un cambiamento in una classe si propaga alle altre.
Definizione (coesione). Misura di quanto le responsabilità di una classe sono fortemente collegate e focalizzate su un unico scopo.
Design pattern - introduzione e catalogo GoF
Definizione (pattern). "Un pattern descrive un problema che si ripresenta di continuo nel nostro ambiente e poi ne descrive il nucleo della soluzione, in modo da poterla usare un milione di volte senza mai farlo due volte nello stesso modo" (Christopher Alexander, architetto). In sintesi: una soluzione ricorrente a un problema standard, in un contesto. Per l'ingegneria del software: una coppia nome-problema/soluzione applicabile in contesti nuovi, con consigli su come adattarla (Craig Larman).
Pattern creazionali - Singleton, Factory Method, Abstract Factory, Builder e Prototype
Definizione. I pattern creazionali riguardano l'inizializzazione e la configurazione di classi e oggetti: nascondono quali classi concrete si creano e come, così che il resto del programma dipenda solo da interfacce (Design pattern - introduzione e catalogo GoFUn design pattern è una soluzione generale, riusabile e collaudata a un problema ricorrente di progettazione in un certo contesto, con un nome (che arricchisce il vocabolario dei progettisti), un problema, una soluzione (struttura e partecipanti) e le conseguenze; il catalogo GoF (Gamma, Helm, Johnson, Vlissides) ha 23 pattern in tre famiglie: 5 creazionali (come si creano gli oggetti), 7 strutturali (come si compongono classi e oggetti), 11 comportamentali (come collaborano e si ripartiscono le responsabilità); dietro i pattern ci sono principi come programmare verso un'interfaccia, incapsulare ciò che varia, preferire la composizione all'ereditarietà, aperto/chiuso e inversione delle dipendenze; un pattern si sceglie dal problema, non dal nome, e usarlo senza bisogno complica il progetto.Design pattern - introduzione e catalogo GoF →). Sono cinque: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
Pattern strutturali - Adapter, Decorator, Composite, Facade e Proxy
Definizione. I pattern strutturali riguardano la composizione di classi e oggetti per formare strutture più grandi o realizzare nuove funzioni, disaccoppiando interfaccia e implementazione. Il catalogo ne ha sette (Design pattern - introduzione e catalogo GoFUn design pattern è una soluzione generale, riusabile e collaudata a un problema ricorrente di progettazione in un certo contesto, con un nome (che arricchisce il vocabolario dei progettisti), un problema, una soluzione (struttura e partecipanti) e le conseguenze; il catalogo GoF (Gamma, Helm, Johnson, Vlissides) ha 23 pattern in tre famiglie: 5 creazionali (come si creano gli oggetti), 7 strutturali (come si compongono classi e oggetti), 11 comportamentali (come collaborano e si ripartiscono le responsabilità); dietro i pattern ci sono principi come programmare verso un'interfaccia, incapsulare ciò che varia, preferire la composizione all'ereditarietà, aperto/chiuso e inversione delle dipendenze; un pattern si sceglie dal problema, non dal nome, e usarlo senza bisogno complica il progetto.Design pattern - introduzione e catalogo GoF →): qui sono trattati con esempio completo Adapter, Decorator, Composite, Facade e Proxy; Bridge e Flyweight sono descritti in fondo. Tutti i programmi sono compilati ed eseguiti con JDK 21, sul dominio biblioteca.
Pattern comportamentali - Observer, Strategy, Command, Iterator e Template Method
Definizione. I pattern comportamentali riguardano le interazioni dinamiche tra gruppi di classi e oggetti e come distribuiscono le responsabilità (Design pattern - introduzione e catalogo GoFUn design pattern è una soluzione generale, riusabile e collaudata a un problema ricorrente di progettazione in un certo contesto, con un nome (che arricchisce il vocabolario dei progettisti), un problema, una soluzione (struttura e partecipanti) e le conseguenze; il catalogo GoF (Gamma, Helm, Johnson, Vlissides) ha 23 pattern in tre famiglie: 5 creazionali (come si creano gli oggetti), 7 strutturali (come si compongono classi e oggetti), 11 comportamentali (come collaborano e si ripartiscono le responsabilità); dietro i pattern ci sono principi come programmare verso un'interfaccia, incapsulare ciò che varia, preferire la composizione all'ereditarietà, aperto/chiuso e inversione delle dipendenze; un pattern si sceglie dal problema, non dal nome, e usarlo senza bisogno complica il progetto.Design pattern - introduzione e catalogo GoF →). Sono undici; qui sono trattati con esempio completo Observer, Strategy, Command, Iterator e Template Method, gli altri sei sono descritti in fondo. Esempi sul dominio biblioteca, compilati ed eseguiti con JDK 21.
12. Software testing
Software testing - progettazione dei casi di test e JUnit
Definizione (testing). Eseguire un programma con dati artificiali per due scopi: mostrare allo sviluppatore e al cliente che soddisfa i requisiti (validation testing) e scoprire situazioni in cui il comportamento è scorretto, indesiderato o non conforme alla specifica (defect testing). Il testing può rivelare la presenza di errori, non la loro assenza (Dijkstra).
Definizione. I dati d'ingresso (e le uscite) si dividono in classi di equivalenza: gruppi i cui membri il programma tratta allo stesso modo. Si sceglie almeno un caso di test da ogni classe: si presume che un errore, se c'è, compaia con tutti i membri della classe o con nessuno.
Definizione (TDD). Nel test-driven development i test si scrivono prima del codice, e passare i test è il fattore critico dello sviluppo. Si sviluppa in incrementi piccoli, e non si passa al successivo finché il codice non supera il test. Nato con i metodi agili (XP), si usa anche nei processi pianificati (Processi di sviluppo - modelli plan-based, metodi agili e ScrumUn processo software è un insieme strutturato di attività (specifica, progetto e realizzazione, validazione, evoluzione) e si descrive con attività, prodotti, ruoli e condizioni; i processi plan-driven pianificano tutto in anticipo e misurano il progresso sul piano (cascata, modello a V con i livelli di test corrispondenti, sviluppo incrementale pianificato, integrazione e configurazione di componenti, con prototipi e consegna incrementale per gestire il cambiamento, e miglioramento del processo con i livelli di maturità SEI), mentre i metodi agili pianificano in modo incrementale e accolgono il cambiamento (manifesto agile, XP con i suoi valori e le sue dodici pratiche, storie dell'utente e story point); Scrum organizza il lavoro in sprint con tre ruoli (Product Owner, Scrum Master, team), eventi (planning, daily scrum, review, retrospective) e artefatti (product backlog, sprint backlog, incremento), stimando con il planning poker; non c'è un processo giusto, ma priorità diverse (stabilità dei requisiti, criticità, dimensione e distribuzione del team).Processi di sviluppo - modelli plan-based, metodi agili e Scrum →).
13. Processi di sviluppo
Processi di sviluppo - modelli plan-based, metodi agili e Scrum
Definizione (processo software). Un processo software è un insieme strutturato di attività richieste per sviluppare un sistema software. Un modello di processo è una rappresentazione astratta di un processo, che ne descrive una parte da un punto di vista particolare.
Definizione. Un modello plan-driven con fasi separate e distinte, svolte in sequenza, ciascuna da completare prima di passare alla successiva.
Definizione. Specifica, sviluppo e validazione si sovrappongono: si sviluppa una versione iniziale, la si mostra al cliente e la si fa evolvere in incrementi che si costruiscono su quelli precedenti. Può essere plan-driven o agile.
Definizione. Scrum è un framework agile che organizza il lavoro in iterazioni brevi a durata fissa (gli sprint) con ruoli, eventi e artefatti precisi. Il nome viene dalla mischia del rugby: tutta la squadra spinge insieme verso lo stesso obiettivo.