Paradigmi di programmazione

10

Click here to load reader

description

Il concetto di paradigma. Paradigmi imperativo e procedurale. Esempi in Java.

Transcript of Paradigmi di programmazione

Page 1: Paradigmi di programmazione

I paradigmi di programmazione

Nel linguaggio comune un paradigma è un modello di riferimento, un termine di paragone.In informatica il paradigma è uno stile di programmazione che influisce sull’approccio seguito nell’affrontare e risolvere un problema. Ogni linguaggio di programmazione è generalmente ispirato (e riconducibile) a un particolare paradigma di programmazione. Alcuni linguaggi di programmazione sono influenzati da molteplici paradigmi. In molti casi un nuovo paradigma nasce come evoluzione di un altro, aggiungendo nuovi concetti ma mantenendo anche quelli fondamentali del precedente (ponendoli eventualmente in una prospettiva nuova o modificandone l'importanza relativa). Talvolta questo "salto evolutivo" consiste nel rendere obbligatoria e/o supportare esplicitamente quella che nei paradigmi precedenti si era affermata come regola di buona programmazione. Per esempio, la programmazione strutturata ha introdotto strutture di controllo standard (sequenze, cicli e alternative) e ha vietato l'uso dell'istruzione di goto, della quale si era dimostrata la non indispensabilità (teorema di Böhm-Jacopini). Quando questo avvenne, i rischi legati all'uso indiscriminato dell'istruzione di salto incondizionato goto erano già noti a molti programmatori, ed erano diffuse regole di stile che suggerivano di restringere l'uso del goto in modi che si potessero far sostanzialmente corrispondere alle strutture di controllo della programmazione strutturata.Nel seguito saranno descritti alcuni di questi paradigmi.

Programmazione imperativa

Nella programmazione imperativa un programma è una sequenza di dati e istruzioni. Le caratteristiche essenziali della programmazione imperativa sono strettamente legate all’architettura di Von Neumann. I linguaggi sviluppati per la programmazione imperativa, nati più per la manipolazione numerica che per quella simbolica, adottano uno stile prescrittivo, ovvero uno stile in cui tutte le operazioni da compiere sono già state previste in anticipo. L'ordine di esecuzione è sequenziale (con l'eccezione delle strutture di controllo che possono frammentare l'azione).

Un programma è strutturato in: una sezione dichiarazioni in cui si dichiarano tutte le variabili del

programma; una sezione istruzioni che descrive l’algoritmo risolutivo mediante

istruzioni del linguaggio.

Le istruzioni possono essere: istruzioni di lettura e scrittura (scrittura a video, scrittura su disco, lettura

da tastiera, ...); istruzioni di assegnamento (astrazione di cella di memoria); istruzioni di controllo (if, while, for, foreach, try, catch, ...).

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

1

Page 2: Paradigmi di programmazione

L'approccio imperativo è stato in seguito adottato da molti altri paradigmi, compreso quello orientato agli oggetti. Esso si contrappone a quello dichiarativo, in cui un programma consiste in un insieme di "affermazioni" (non "istruzioni") che definiscono l’obiettivo da raggiungere (cosa fare) senza specificare un algoritmo (come fare).

Esempio: Area di un quadrato (approccio imperativo)

Fase 1: individuazione dei dati

ID Descr I/O/L TIPO VAL. INIZ.lato lato quadrato input double -area area quadrato output double -

Fase 2: individuazione dell’algoritmo risolutivo

Start

input (lato)

area = lato * lato

output (lato)

End

Fase 3: scrittura del programma in Java

import javax.swing.*;

class Quadrato {

public static void main(String[] args) {

//Dichiarazione variabilidouble lato, area;//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areaarea = Math.pow(lato,2);//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

2

Page 3: Paradigmi di programmazione

Programmazione procedurale

Nella programmazione procedurale un programma è costituito da blocchi di codice, identificati da un nome, detti sottoprogrammi. Questi blocchi possono essere dotati di parametri, cioè variabili locali i cui valori vengono forniti dall'esterno del blocco di codice. Un sottoprogramma ha una struttura simile a quella di un programma è può restituire o meno un valore. Nel primo caso si parla di funzioni, nel secondo caso di procedure.

Esempio: Area di un quadrato (approccio procedurale)

Fase 1: individuazione dei blocchi o sottoprogrammi

Sottoprogramma calcolaArea: calcola l’area di un quadrato di cui sia noto il lato.

Fase 2: individuazione dei dati e dell’algoritmo del programma principale

ID Descr I/O/L TIPO VAL. INIZ.lato lato quadrato input double -area area quadrato output double -

Start

input (lato)

output (lato)

End

calcolaArea

Fase 3: Applicazione dell’approccio imperativo per la risoluzione di ciascun sottoprogramma

Algoritmo risolutivo per calcolaArea

Start

area = lato * lato

End

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

3

Page 4: Paradigmi di programmazione

Fase 4: scrittura del programma in Java

import javax.swing.*;

class Quadrato {

//Dichiarazione variabili di classeprivate static double lato;private static double area;//Sottoprogramma che calcola l'areapublic static void calcolaArea(){

area= Math.pow(lato,2);}//Programma principalepublic static void main(String[] args) {

//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areacalcolaArea();//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

Una versione di calcolaArea che utilizza i parametri:

import javax.swing.*;

class Quadrato {

//Sottoprogramma che calcola l'areapublic static double calcolaArea(double l){

return Math.pow(l,2);}//Programma principalepublic static void main(String[] args) {

//Dichiarazione di variabilidouble lato,area;//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areaarea = calcolaArea(lato);//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

4

Page 5: Paradigmi di programmazione

Sottoprogrammi in Java

Java è un linguaggio che segue il paradigma ad oggetti e, di conseguenza, non è adatto alla scomposizione procedurale. Tuttavia, con opportuni accorgimenti è possibile adottare una scomposizione in sottoprogrammi anche con tale linguaggio (nonostante sia fortemente sconsigliato).

In Java i sottoprogrammi si chiamano metodi e restituiscono sempre un risultato, eventualmente “vuoto” (void). Di conseguenza, nonostante il linguaggio fornisca solo strumenti adatti a costruire funzioni, è possibile simulare il comportamento di una procedura restituendo un risultato void. Prima di addentrarci in tale spiegazione, due parole sulla sintassi per dichiarare i metodi:

Esempio

public static double calcolaArea(double l){

return Math.pow(l,2);}

Per il momento tralasciamo lo specificatore static e andiamo a descrivere le varie componenti di un metodo.

• VISIBILITÀ

Indica il livello di visibilità di un metodo (public, protected, private), caratteristica che approfondiremo in seguito.

• TIPO RESTITUITO

Indica il tipo del valore restituito dal metodo, che può essere uno qualsiasi dei tipi primitivi o riferimento visti nelle precedenti lezioni. Se una funzione non restituisce un valore, occorre specificare void.

• NOME METODO

E’ un identificatore liberamente scelto dall’utente, la cui lettera iniziale è convenzionalmente minuscola.

• LISTA PARAMETRI

La lista dei parametri contiene un elenco di dichiarazioni di variabili, dette parametri formali, separate da virgole. Per ogni parametro occorre indicare

I parametri di un metodo sono opzionali ma le parentesi () devono sempre essere presenti, anche se il loro contenuto è vuoto.

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

<visibilità> <tipo restituito> <nome metodo> (<lista parametri>){ <dichiarazione di variabili> <istruzioni>}

<tipo parametro> <nome parametro>

5

Page 6: Paradigmi di programmazione

• DICHIARAZIONE DI VARIABILI

Le variabili definite all’interno di un metodo sono opzionali: saranno presenti solo se necessarie.

• ISTRUZIONI

Le istruzioni, create utilizzando i costrutti di base del linguaggio, possono comprendere anche chiamate ad altri metodi e devono includere una particolare istruzione la cui sintassi è:

L’istruzione return può essere inserita in qualunque punto della sezione istruzioni del metodo; essa ne causa la terminazione restituendo il valore specificato. Solitamente è l’ultima istruzione del metodo. Se il tipo restituito è void, l’istruzione assume la forma:

e, nel caso sia posta al termine della sezione istruzioni, diventa superflua.

Esecuzione di sottoprogrammi in Java

Riprendiamo il codice visto in precedenza:

import javax.swing.*;

class Quadrato {

//Dichiarazione variabili di classeprivate static double lato;private static double area;//Sottoprogramma che calcola l'areapublic static void calcolaArea(){

area= Math.pow(lato,2);}//Programma principalepublic static void main(String[] args) {

//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areacalcolaArea();//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

Potete osservare che i 2 metodi definiti all’interno della classe presentano la parola chiave static nella dichiarazione. Osservate, inoltre, che anche le variabili lato e area sono static e sono dichiarate esternamente ai metodi. Il motivo è che entrambi i metodi devono potervi accedere per leggere/scrivere valori e quindi, dichiarandole all’interno di un metodo non sarebbero accessibili dall’altro.

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

return <valore>;

return;

6

Page 7: Paradigmi di programmazione

Le variabili dichiarate esternamente ai metodi e contrassegnate dalla parola chiave static si chiamano variabili di classe. I metodi static possono essere utilizzati senza necessariamente creare un oggetto, consentendo così di applicare una scomposizione procedurale. La parola chiave private, invece, ha una funzione completamente differente, che sarà chiarita affrontando il paradigma a oggetti.

L’esecuzione del programma inizia dalla prima istruzione del metodo main:

lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));

Essa consente all’utente di inserire un valore del lato mediante una finestra di dialogo.

L’istruzione

calcolaArea();

effettua una chiamata al metodo calcolaArea. Il metodo main diviene quindi il chiamante, mentre il metodo calcolaArea è il chiamato. Il chiamato può restituire un valore al chiamante. Questo è il motivo per cui la chiamata di un metodo viene realizzata solitamente mediante una assegnazione ad una variabile. La variabile dovrà essere dello stesso tipo del valore restituito dal metodo. Fanno eccezione i metodi che restituiscono void, che possono essere chiamati senza utilizzare un’assegnazione ma semplicemente scrivendo il loro nome, come nel nostro esempio.

La chiamata a calcolaArea() determina la sua esecuzione: il controllo passa al chiamato e viene eseguita la prima (e in questo caso unica) istruzione

area= Math.pow(lato,2);

Terminata l’esecuzione del metodo, il controllo torna al chiamante e viene eseguita l’istruzione successiva a quella che ha determinato la chiamata del metodo.

JoptionPane.showMessageDialog(null,”Area = “+area);

Si veda la simulazione del precedente programma nella dispensa dal titolo Simulazione 1.

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

7

Page 8: Paradigmi di programmazione

Variabili globali e locali

Dalla simulazione si evince che le variabili lato e area, una volta allocate in memoria centrale, vi rimangono per tutta la durata dell’esecuzione; inoltre, esse sono visibili a tutti i metodi della classe, i quali possono accedervi sia in lettura sia in scrittura. Le variabili che presentano le predette caratteristiche sono dette, in generale, variabili globali. In Java, come si è già detto, sono chiamate variabili di classe, anche se i due concettti non sono completamente coincidenti.

Le variabili definite all’interno di un sottoprogramma o presenti nella lista di parametri formali, sono dette variabili locali. Le variabili locali hanno un tempo di vita pari al tempo di esecuzione del sottoprogramma stesso e, a differenza delle variabili globali, sono visibili solo all’interno del sottoprogramma in cui sono dichiarate.

Le procedure per poter produrre un qualche effetto, visto che non restituiscono alcun valore, devono modificare almeno una variabile globale; in altre parole esse producono degli effetti collaterali (side effect). La modifica di una variabile globale da parte di sottoprogrammi diversi è potenzialmente un’azione pericolosa, che può portare a comportamenti indesiderati del programma. In generale, quindi, è consigliabile utilizzare il minor numero possibile di variabili globali. Nel seguito vedremo una soluzione che consente di ridurre il numero di variabili globali, grazie all’uso di funzioni.

Utilizzo di funzioni al posto di procedure

Consideriamo il codice seguente:

import javax.swing.*;

class Quadrato {

//Dichiarazione variabili di classeprivate static double lato;//Sottoprogramma che calcola l'areapublic static double calcolaArea(){

return Math.pow(lato,2);}//Programma principalepublic static void main(String[] args) {

//Dichiarazione di variabilidouble area;//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areaarea = calcolaArea();//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

8

Page 9: Paradigmi di programmazione

Osservate che la variabile area è definita all’interno del metodo main e che il metodo calcolaArea restituisce un valore double. Questo codice è migliore del precedente perché consente di utilizzare una sola variabile di classe. Si veda la dispensa Simulazione 2.

L’ideale sarebbe eliminare tutte le variabili globali. Ma è possibile? Sì, attraverso l’uso di sottoprogrammi parametrici.

Sottoprogrammi parametrici

Analizziamo il codice seguente:

import javax.swing.*;

class Quadrato {

//Sottoprogramma che calcola l'areapublic static double calcolaArea(double l){

return Math.pow(l,2);}//Programma principalepublic static void main(String[] args) {

//Dichiarazione di variabilidouble lato,area;//Acquisizione input lato = Double.parseDouble(JoptionPane.showInputDialog(“Immettere la misura del lato”));//Calcolo areaarea = calcolaArea(lato);//OutputJoptionPane.showMessageDialog(null,”Area = “+area);

} }

In questo codice non sono presenti variabili di classe ma compaiono dei parametri. I parametri sono di due tipi: formali e attuali.

I parametri formali compaiono nell’intestazione di un metodo come una sequenza di dichiarazioni di variabili separate da virgole:

public static double calcolaArea(double l)

I parametri attuali sono specificati all’atto della chiamata del metodo e consistono in una sequenza di valori, separati da virgola:

area = calcolaArea(lato);

Alla chiamata del metodo il valore contenuto nel parametro attuale viene copiato nel parametro formale corrispondente. I parametri formali devono concordare in numero, posizione e tipo con i parametri attuali.

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

9

Page 10: Paradigmi di programmazione

Quando termina l’esecuzione del metodo, tutti i parametri formali allocati in precedenza vengono deallocati. Di conseguenza il parametro formale l non dura per tutta l’esecuzione del programma ma solo per il tempo necessario all’esecuzione della funzione calcolaArea, dopodiché rilascia l’area di memoria occupata.

L’assegnazione ad un parametro formale del corrispondente valore del parametro attuale è detto passaggio di parametri per valore. Il linguaggio Java utilizza solo questo tipo di passaggio di parametri. Tuttavia, esistono anche altri metodi per passare i parametri, adottati da altri linguaggi, come il passaggio di parametri per riferimento. Esso consiste nell’assegnare al parametro formale l’indirizzo del parametro attuale e non il suo valore.Si veda la Simulazione 3 per comprendere meglio i meccanismi descritti.

Riferimenti e approfondimenti

Wikipedia, Paradigmi di programmazione, url: http://it.wikipedia.org/wiki/Paradigma_di_programmazione

Wikipedia, Programmazione imperativaurl: http://it.wikipedia.org/wiki/Programmazione_imperativa

Wikipedia, Programmazione proceduraleurl: http://it.wikipedia.org/wiki/Programmazione_procedurale

Quest'opera è stata rilasciata con licenza Creative Commons Attribution-ShareAlike 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/by-sa/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Autore: Cinzia BocchiUltimo aggiornamento: 08/08/2011

10