Ingegneria e astrazione orientata agli oggetti

Progettazione e Sviluppo del Software

C.D.L. Tecnologie dei Sistemi Informatici

Danilo Pianini — danilo.pianini@unibo.it

Gianluca Aguzzi — gianluca.aguzzi@unibo.it

Angelo Filaseta — angelo.filaseta@unibo.it

Compiled on: 2025-09-07 — versione stampabile

back

Sistemi software

Obiettivo di questo corso

Insegnare tecniche moderne per la costruzione di sistemi software
$\Rightarrow$ utilizzando i concetti dei sistemi ad oggetti, che sono “mainstream”

Programma vs sistema software

Programma: un set di istruzioni che automatizzano la soluzione di una classe di problemi, spesso associato ad una visione algoritmica della computazione (Input $\rightarrow$ Output).
Sistema software: un’aggregazione di componenti di varia natura (programmi, librerie, parti del sistema operativo, basi di dati, interfacce grafiche, servizi Web, rete, dispositivi hardware) che cooperano per fornire una funzionalità computazionale.

Casi di sistemi software

Esempi

  • Calcolatrice matematica
  • Applicazione per gestire esami universitari
  • Simulatore di circuiti elettronici, movimento di folle, movimento pianeti
  • Monitor e elaborazione di dati biometrici (pressione, dati cardiaci,..)
  • App per smartphone che mostra dove si trovano i miei contatti social
  • Video-game in cui personaggi virtuali vivono in un ambiente 3D
  • Controllore per dispositivi domotici (luce, termosifoni, acqua)

Caratteristiche comuni

  • Non meri programmi, ma sistemi “pilotati” da software
  • Includono componenti algoritmiche, ma anche interazioni complesse
  • Alcuni realizzabili già alla fine di questo corso, altri richiedono maggiore expertise

Fasi del processo di sviluppo

Analisi

Si definisce in modo preciso il problema da risolvere (non la soluzione!)

Design

Si definisce la struttura del sistema da sviluppare

  • progetto architetturale + progetto di dettaglio
  • si descrive la soluzione, ad uno specifico livello di dettaglio

Implementazione/codifica

Si realizza il sistema sulla base del progetto, scegliendo le tecnologie adeguate (efficienti, efficaci)

  • ad esempio, il linguaggio di programmazione

Attività di manutenzione: Collaudo, Deployment

Fasi necessarie, che spesso impiegano più del 70% delle risorse complessive

Il problema dello sviluppo di sistemi software

http://it.wikipedia.org/wiki/Software_crisis

Quali cause possono comportare il fallimento di un progetto SW?

  • Inadeguata analisi (requisiti non compresi appieno)
  • Inadeguata (o assente) progettazione
  • Cattive pratiche di programmazione
  • Aspetti organizzativi nel team di sviluppo

Problem space vs solution space: il “buon progetto”

Problem space (fase di analisi)

L’insieme delle entità e relazioni nel mondo “reale” sulla base delle quali si formula il problema che il sistema software deve risolvere

  • per il gestionale per esami universitari: studente, corso, corso di laurea, appello, voto

Solution space (fase di progetto e implementazione)

Il corrispondente insieme di entità e relazioni nel mondo “artificiale” che devono risolvere il problema (realizzate mediante i linguaggi e le tecnologie scelte e a fronte del progetto).

  • funzione per il calcolo della media
  • struttura dati per rappresentare i dati di uno studente
  • form per visualizzare gli esami di uno studente

Un buon progetto mappa al meglio il problem space nel solution space

Concetti del solution/problem space: “livello di astrazione”

Definizione di astrazione (nell’informatica)

  • È un metodo per descrivere un sistema informatico complesso mettendone da parte alcune caratteristiche specifiche, per facilitarne la progettazione, implementazione e manutenzione.
  • Un livello di astrazione è un insieme di concetti e relazioni che definiscono una astrazione, usabili quindi per definire in modo conveniente un sistema informatico

Il livello d’astrazione dei linguaggi di programmazione

Astrazione e programmazione

  • Ogni linguaggio di programmazione introduce un livello di astrazione
  • I concetti del sistema da realizzare (nel gestionale esami: corsi, voti, studenti, calcolo media voti) devono essere tradotti nei “costrutti” forniti dal linguaggio
  • È facile? È conveniente? È flessibile? Dipende dal linguaggio…

Il livello di astrazione del C (e della progr. procedurale/imperativa)

  • Stato del sistema $\Rightarrow$ È costituito da strutture dati (costruite con tipi primitivi, array, puntatori e struct) tenute in stack e/o heap
  • Dinamica $\Rightarrow$ Esecuzione di procedure imperative, innestate ricorsivamente appoggiandosi allo stack
  • Organizzazione $\Rightarrow$ Librerie come set di funzioni, ricongiunte in un unico programma all’atto della compilazione/linking

I limiti del linguaggio C

C porta ad una visione piuttosto machine-oriented

  • È un livello di astrazione fortemente influenzato dall’HW sul quale si eseguono i programmi (CPU, memoria)
    • uso criptico di direttive di compilazione
    • allocazione/deallocazione dinamica manuale della memoria via librerie
    • difficile controllo degli errori di esecuzione
    • difficoltà a controllare gli aspetti HW-dependent
    • difficoltà a modificare codice già “acquisito”
      • Nota: il C nasce negli anni ‘70 per rimpiazzare l’Assembly nell’implementazione del sistema operativo UNIX

La direzione dei linguaggi moderni – o di “alto livello” (d’astrazione)

  • Introdurre un livello di astrazione vicino al problema da risolvere, ignorando il più possibile i dettagli dell’HW per risolverlo

L’ecosistema dei linguaggi di programmazione

Linguaggi e livelli di astrazione / paradigma

  • C, Pascal: Computing function/procedure over data structures
  • Lisp, ML: Everything is a function
  • Java, C++, C#: Everything is an object (OO Programming)
  • $\Rightarrow$ L’OOP si è dimostrata efficace per sistemi complessi general-purpose

L’evoluzione del “mainstream”

Machine Lang $\xrightarrow{1950-1960}$ Assembly $\xrightarrow{1970-‘190}$ C $\xrightarrow{‘90-2000}$ OOP (Java,..) $\xrightarrow{?}$ ?

Il futuro dei linguaggi (e anche la direzione dei linguaggi OOP)

  • OO + funzionale: Scala, Kotlin, Java 8+
  • Multi-target: Kotlin, Scala, LLVM
  • Linguaggi dinamici: Python, Ruby, Javascript, Groovy
    • O quasi…: TypeScript

I vantaggi della programmazione ad oggetti

Vantaggi

  • Poche astrazioni chiave (classe, oggetto, metodo, campo)
  • Usabili sia in progettazione che in codifica
  • Supporto a estendibilità e riuso
  • Supporto alla costruzione di librerie di qualità
  • Facilmente integrabile in linguaggi C-like
  • Eseguibile con alta efficienza

$\Rightarrow$ (quasi) tutti aspetti da discutere nel corso

Le critiche all’OOP

  • Serve molta disciplina per “scalare” bene con la complessità del problema
  • Altri paradigmi (fra cui quello funzionale) suggeriscono come farlo…

L’astrazione object-oriented

L’astrazione object-oriented (OO)

Un oggetto possiede

1. stato

2. comportamento

3. identità

Esempio “lampadina” in notazione UML (Unified Modelling Language):

« interface »
Light
on()
off()
brighten()
dim()

È un linguaggio visuale che consente di rappresentare gli elementi di un sistema software in modo standardizzato.

  • Funziona particolarmente bene per sistemi OO

Un proto-oggetto in C

La stessa lampadina, in C, diventerebbe…

typedef struct { // stato
    int isOn;
    double brightness;
} Lamp;

// comportamento (interfaccia)
void on(Lamp* l) {
    l->isOn = 1;
}

void off(Lamp* l) {
    l->isOn = 0;
}

void brighten(Lamp* l) {
    if (l->isOn) l->brightness += 0.1;
}

void dim(Lamp* l) {
    if (l->isOn && l->brightness > 0) l->brightness -= 0.1;
}

void main(void) {
    Lamp myLamp = {0, 0.0}; // Creazione dell'oggetto: nel caso di C, il riferimento in memoria è l'identità
    on(&myLamp); // messaggio
    brighten(&myLamp); // messaggio
}

OO: problem space, solution space

L’esperienza mostra che:

  • È piuttosto agevole modellare sistemi reali (o artificiali) come sistemi orientati agli oggetti
  • Infatti, gli strumenti di modellazione standard usano il paradigma object-oriented! (Vedi UML)

Il vantaggio delle soluzioni object-oriented

  • Consentono di “portare” il problem space nel solution space in modo diretto
  • Usando gli stessi concetti object-oriented anche a livello di programmazione
  • …ossia supportano il concetto di “buon progetto” che abbiamo discusso

Overview

  • Ogni oggetto ha un’interfaccia
    • I messaggi che può ricevere
  • Un oggetto (ben progettato) fornisce uno e un solo servizio
    • “Single Responsibility Principle”
    • Non vi aspettate che il vostro microonde possa anche lavare i panni, giusto?
  • Un oggetto (ben progettato) deve nascondere l’implementazione
    • Incapsulamento e “information hiding”
    • Non vi aspettate di dover smontare il microonde per scaldare un piatto di pasta, giusto?
  • Le implementazioni possono essere riusate
    • “Don’t Repeat Yourself” (DRY)
    • Non dovete cambiare microonde se invece della pasta scaldate il riso, giusto?

Java

Java

  • Linguaggio inventato da J. Gosling, alla Sun Microsystems (1995)
  • Ora gestito da un board che ne porta avanti l’evoluzione
  • Una semplificazione di C++ pensata per sistemi embedded
  • Filosofia Write once run everywhere
    • Software scritto in Java può funzionare su Windows, MacOS, Linux, Solaris, su architetture ARM, x86, PowerPC, amd64…
    • Senza bisogno di ricompilare!
  • Molto diffuso in industria

In questo corso

  • Useremo Java come riferimento per programmazione/progettazione
  • Le guideline progettuali che daremo sono di validità generale
    • Meccanismi simili o identici in C#, C++, Ruby, Python, Kotlin, Scala…

Strumenti Java

Java Development Kit (JDK)

  • Insieme di tool per lo sviluppatore
  • useremo l’ultima versione “long term support” (LTS)
  • https://adoptium.net/

Java Virtual Machine (JVM) – inclusa nel JDK

  • Un programma (C/C++) che carica il bytecode delle classi e lo esegue
  • Fornisce indipendenza dall’HW, e servizi aggiuntivi (SISOP, GC)

Schema compilazione/interpretazione

  • Compilazione dei programmi col compilatore Java (comando javac)
  • Esecuzione del programma con la JVM (comando java)

Write once, run everywhere

Delivered Application

processed by

produces

interpreted by

interpreted by

interpreted by

Java source code (*.java)

Java compiler (javac)

Byte code (*.class)

JVM for Windows

JVM for MacOS

JVM for Linux

Windows

MacOS X

Linux

Sviluppo storico di Java fino agli anni 10

  • Java (1996): versione iniziale
  • Java 1.2 (1998): aggiunta del framework grafico Swing
  • Java 5 (1.5) (2004): aggiunta di generici, inner class, annotazioni
    • Java è così diffuso che si decide non avrà una versione 2.x
    • Da qui, si usa il secondo numero per contare la release
  • Java 6 (2006): miglioramento prestazionale importante
  • Java 7 (2011): supporto a più linguaggi nella JVM, diamond operator
  • Java 8 (2014): aggiunta lambda expression e streams
  • Java 9 (2017): aggiunta Java Module System (Jigsaw)
    • Da qui, un rilascio ogni 6 mesi
  • Java 10 (2018): aggiunta local variable type-inference
  • Java 11 LTS (2018): rimozione di API deprecate e miglioramenti di performance
  • Java 12 (2019): switch expressions
  • Java 13 (2019): blocchi di testo

Sviluppo storico di Java dagli anni 20

  • Java 14 (2020): pattern Matching per instanceof e records
  • Java 15 (2020): classi sealed (gerarchie sigillate, sum types)
  • Java 16 (2021): stabilizzazione di features
  • Java 17 LTS (2021): miglioramento delle switch expressions
  • Java 18 (2022): miglioramenti minori
  • Java 19 (2022): supporto a Linux/RISC-V
  • Java 20 (2023): miglioramenti minori, introduzione di nuove features (alpha)
  • $\Rightarrow$ Java 21 LTS (2023): Virtual threads, record patterns
  • Java 22 (2024): Unnamed Variables, Stream Gatherers.
  • Java 23 (2024): miglioramenti alla gestione della memoria, documentazione in Markdown
  • Java 24 (2025): class file API, miglioramenti minori
  • Java 25 LTS (2025): Instance Main Methods

Modello di sviluppo attuale

  • Da Java 9, si ha una nuova release ogni 6 mesi
  • Ogni due anni, si ha una nuova LTS, e si raccomanda di non rimanere indietro
  • OpenJDK produce l’implementazione di riferimento del JDK
    • Ne esistono anche altre!
      • Eclipse OpenJ9, Amazon Corretto, GraalVM…

Ingegneria e astrazione orientata agli oggetti

Progettazione e Sviluppo del Software

C.D.L. Tecnologie dei Sistemi Informatici

Danilo Pianini — danilo.pianini@unibo.it

Gianluca Aguzzi — gianluca.aguzzi@unibo.it

Angelo Filaseta — angelo.filaseta@unibo.it

Compiled on: 2025-09-07 — versione stampabile

back