Concetti Chiave
- La cronologia dello sviluppo dei paradigmi di programmazione evidenzia una progressiva astrazione dal controllo delle azioni negli anni '50 all'adozione della programmazione orientata agli oggetti (OOP) negli anni '90.
- I linguaggi di programmazione possono essere classificati in base al loro utilizzo, al paradigma che supportano e al livello di astrazione, variando da linguaggi di basso livello a quelli di alto livello.
- L'approccio classico alla programmazione evidenzia l'importanza di mantenere una disciplina nell'uso dei campi di un record, con l'OOP che promuove un corretto utilizzo delle variabili negli oggetti.
- La costruzione di componenti software attraverso moduli e librerie permette la protezione delle informazioni e la condivisione di risorse, come funzioni matematiche, senza l'uso di variabili non-locali.
- La programmazione per tipi di dato astratto e moduli assicura l'inaccessibilità alla struttura dei dati, promuovendo la separazione tra interfaccia e implementazione, e l'indipendenza dalla rappresentazione.
1. Organizzazione delle azioni (lista istruzioni, anni '50, astrazione sul controllo, calcoli di funzioni matematiche).
2. Astrazione procedurale (sottopgm con parametri, anni '60, programmazione strutturata (Th.di Bohem e Jacopini (1966) e metodologia top-down).
3. Astrazione di dato (anni '70).
4. ADT (anni '80).
5. Oggetti (organizzazione dei dati, anni '90, OOP).
Paradigmi procedurali
Paradigma imperativo: si basa sul concetto di comando (fa pensare alle azioni).
Paradigma OOP: si basa sul concetto di oggetto (fa pensare ai dati).
Linguaggio Anno Utilizzo Paradigma
- Fortran 1954 - '57: Calcolo numerico Imperativo;
- Lisp 1958: Intelligenza artificiale Dichiarativo;
- Cobol 1959 - '61: Applicazioni gestionali Imperativo;
- Pascal 1970: General purpose Imperativo;
- Prolog 1972: Intelligenza artificiale Logico;
- C 1972 - '78: General purpose.
Programmazione di sistema Imperativo
Smalltalk 1971 - '80: Applicazioni personali Ad oggetti;
C++ 1980 - '83: General purpose Ad oggetti;
Java 1995: General purpose Ad oggetti.
Classificazione dei linguaggi
In base al loro utilizzo (cioè l’ambito applicativo per cui sono stati principalmente progettati).
In base al paradigma di programmazione che supportano.
In base al loro livello di astrazione (l. di basso livello (machine oriented) / l. di alto livello (problem oriented).
Approccio classico: esempio 1
struct persona{
…i
nt altezza;
int peso;
};
void aggiornaPeso(persona & p, int peso)
{
p.peso = peso;
}
int main()
{
persona pietro;
aggiornaPeso(pietro,2329); //!!!!!!!!!!!
//pietro.peso=2329;
}
Osservazioni
Possiamo inserire controlli nella procedura aggiornaPeso().
Ma poi è comunque consentito scrivere: pietro.peso=2329;
E’ comunque possibile mantenere una certa disciplina nell’uso dei campi del record.
La OOP, vedremo, incoraggia un uso corretto delle “variabili” che fanno parte degli oggetti.
Componenti s/w
Il modulo è uno dei costrutti più usati per costruire componenti software. Esso costituisce un contenitore di informazioni
con proprietà di protezione dovute alla possibilità di esportare ed importare (nel senso di usare altri moduli) risorse (costanti, variabili, tipi, procedure/funzioni, ADT, …).
Costruzione di componenti s/w
Mediante moduli: Librerie
Il modulo in questo caso (libreria) rende visibili un insieme di procedure/funzioni che non fanno uso di variabili non-locali. In questo caso il modulo raccoglie una collezione di operazioni, cioè funge da
libreria. Il classico esempio è quello delle funzioni matematiche.
Programmare per (singola) astrazione di dato
Il modulo rende visibili un insieme di procedure/funzioni che fanno uso di variabili non
visibili, locali al modulo. In questo caso un modulo realizza un singolo oggetto il cui stato interno (modificabile) è costituito dai dati locali (nascosti) del modulo e reso accessibile solo attraverso le operazioni (procedure/funzioni) definite nell’interfaccia.
Programmare per tipi di dato astratto
Il modulo esporta un identificatore di tipo e un insieme di procedure/funzioni intese come insieme di operazioni eseguibili su oggetti del tipo esportato.
La rappresentazione concreta del tipo è nascosta all’interno del modulo. I clienti definiscono e controllano (il tempo di vita
de) le istanze del tipo che devono essere esplicitamente trasferite come parametro alle operazioni esportate dal modulo.
Conclusione
L’ideale sarebbe:
- garantire l’inaccessibilità alla struttura dati, se non attraverso le operazioni messe a disposizione;
- consentire al cliente di creare tanti oggetti quanti gliene occorrono garantendo inoltre:
1. separazione interfaccia/implementazione;
2. indipendenza dalla rappresentazione.
Soluzione: OOP (classe – oggetti)
Domande da interrogazione
- Qual è l'evoluzione storica dei paradigmi di programmazione?
- Quali sono i principali paradigmi di programmazione menzionati nel testo?
- Come vengono classificati i linguaggi di programmazione secondo il testo?
- Qual è il ruolo dei moduli nella costruzione di componenti software?
- Qual è l'obiettivo ideale nella programmazione orientata agli oggetti secondo il testo?
L'evoluzione storica dei paradigmi di programmazione inizia con l'organizzazione delle azioni negli anni '50, seguita dall'astrazione procedurale negli anni '60, l'astrazione di dato negli anni '70, gli ADT negli anni '80 e infine gli oggetti negli anni '90 con la programmazione orientata agli oggetti (OOP).
I principali paradigmi di programmazione menzionati sono il paradigma imperativo, che si basa sul concetto di comando, e il paradigma OOP, che si basa sul concetto di oggetto.
I linguaggi di programmazione vengono classificati in base al loro utilizzo, al paradigma di programmazione che supportano e al loro livello di astrazione, distinguendo tra linguaggi di basso livello (machine oriented) e di alto livello (problem oriented).
I moduli sono utilizzati come contenitori di informazioni con proprietà di protezione, permettendo l'esportazione e l'importazione di risorse. Possono fungere da librerie, rendendo visibili procedure e funzioni, o realizzare singoli oggetti con dati locali accessibili solo tramite operazioni definite nell'interfaccia.
L'obiettivo ideale nella programmazione orientata agli oggetti è garantire l'inaccessibilità alla struttura dati se non attraverso le operazioni disponibili, consentendo al cliente di creare oggetti necessari, assicurando la separazione tra interfaccia e implementazione e l'indipendenza dalla rappresentazione.