Premessa
Lo scopo principale di questa guida è quello di fornire una panoramica sulla tecnica di programmazione più diffusa e consolidata nel mondo dello sviluppo applicativo: La Programmazione ad Oggetti (Object Oriented Programming, da cui l’acronimo OOP, che utilizzeremo frequentemente nel corso della guida).
Non si richiedono particolari conoscenze pregresse nel mondo della programmazione per poter leggere le pagine che seguono, in quanto gli argomenti trattati vengono esaminati partendo da nozioni decisamente basilari.
Pertanto la guida è rivolta sia a coloro che non hanno mai utilizzato alcun linguaggio di programmazione “ad Oggetti” sia a coloro che hanno già conoscenza o esperienza in tale settore. Questi ultimi potranno approfittare della guida per chiarire meglio alcuni concetti che spesso vengono fraintesi o che sono talvolta fonte di confusione.
Una cosa importante da non trascurare per i tanti programmatori con conoscenza di linguaggi procedurali come il Visual Basic (fino alla versione 6.0, per lo meno) è di evitare fortemente di utilizzare il modus operandi e le regole implementative apprese con tale linguaggio, in quanto potrebbero rendere più arduo l’apprendimento dei concetti che governano il mondo della programmazione ad oggetti.
Introduzione e cenni storici
La Programmazione ad Oggetti rappresenta, senza dubbio, il modello di programmazione più diffuso ed utilizzato degli ultimi dieci anni.
Le vecchie metodologie come la programmazione strutturata e procedurale, in auge negli anni settanta, sono state lentamente ma inesorabilmente superate a causa degli innumerevoli vantaggi che sono derivati dall’utilizzo del nuovo paradigma di sviluppo.
Un esempio, ben noto a tanti programmatori, è rappresentato dalla profonda trasformazione che ha subito il Visual Basic nell’ultima versione rilasciata dalla Microsoft (Visual Basic .NET) che lo vede finalmente catalogato come un linguaggio ad Oggetti a tutti gli effetti.
Eppure, contrariamente a quanto si possa pensare, le origini della Programmazione ad Oggetti sono abbastanza remote: i primi linguaggi “ad oggetti” furono il SIMULA I e il SIMULA 67, sviluppati da Ole-Johan Dahl e Kristen Nygaard nei primi anni ’60 presso il Norwegian Computing Center.
Entrambi questi linguaggi adottavano già parecchie delle peculiarità che sono oggi tra i capisaldi della programmazione ad oggetti, come ad esempio le classi, le sottoclassi e le funzioni virtuali ma, a dispetto dell’importanza storica, tali linguaggi non riscossero particolare successo.
Negli anni ’70 fu introdotto il linguaggio SmallTalk, considerato da molti il primo vero linguaggio ad oggetti “puro”. Lo SmallTalk fu sviluppato in due periodi successivi: inizialmente da Alan Kay, ricercatore dell’università dello Utah e successivamente fu ripreso da Adele Goldberg e Daniel Ingalls, entrambi ricercatori allo Xerox Park di Palo Alto, in California.
Ma, ancora una volta, il grande successo tardò ad arrivare. Probabilmente, la ragione di ciò era da ricercare nel fatto che questo linguaggio (come il Simula) era considerato, per lo più, uno strumento destinato alla ricerca e allo studio più che allo sviluppo.
A questo si aggiunga che negli anni ’70 il linguaggio C riscuoteva enorme successo grazie alle sue potenzialità e, soprattutto, al fatto che il famoso sistema operativo Unix (ancora oggi fortemente usato) fosse stato scritto utilizzando proprio tale linguaggio.
Fu, insomma, necessario attendere gli anni ’80 con l’avvento del linguaggio ADA per assistere alla definitiva consacrazione della programmazione ad oggetti come modello da utilizzare. Probabilmente la vera svolta fu rappresentata dall’avvento del C++, creato da Bjarne Stroustrup.
Tra i più noti linguaggi di programmazione ad oggetti, citiamo il C++, Java, Delphi, C# e, come detto, il Visual Basic .NET.
Tecniche di Programmazione
Si è precedentemente accennato a “vecchie” metodologie di programmazione e a come queste siano state lentamente ma inesorabilmente messe da parte con la diffusione dell’OOP. In questo paragrafo verranno descritte brevemente tali metodologie al fine di comprendere meglio le differenze con la programmazione ad oggetti.
Programmazione Non Strutturata
Con la programmazione non strutturata il programma è costituito da un unico blocco di codice detto “main” dentro il quale vengono manipolati i dati in maniera totalmente sequenziale.
È importante notare che tutti i dati sono rappresentati soltanto da variabili di tipo globale, ovvero visibili da ogni parte del programma ed allocate in memoria per tutto il tempo che il programma stesso rimane in esecuzione.
È facile capire che un simile contesto è fortemente limitato e pieno di svantaggi. Ad esempio, sarà facile incappare in spezzoni di codice ridondanti o ripetuti che non faranno altro che rendere presto ingestibile ed “illeggibile” il codice, causando oltretutto un enorme spreco di risorse di sistema.
Nella figura seguente, viene rappresentata graficamente l’architettura di questo tipo di paradigma di sviluppo.
Programmazione Procedurale
Un notevole passo in avanti, rispetto alla Programmazione Non Strutturata, venne fatto con l’avvento della Programmazione Procedurale. I programmatori in Visual Basic 5.0 o 6.0 sapranno certamente di cosa si sta parlando (anche se il Visual Basic utilizza anche il paradigma di Programmazione Modulare, descritta nel successivo paragrafo).
Il concetto base qui è quello di raggruppare i pezzi di programma ripetuti in porzioni di codice utilizzabili e richiamabili ogni volta che se ne presenti l’esigenza: nascevano le Procedure.
Ogni procedura può essere vista come un sottoprogramma che svolge una ben determinata funzione (ad esempio, il calcolo della radice quadrata di un numero) e che è visibile e richiamabile dal resto del codice.
Inoltre ogni procedura ha la capacità di poter utilizzare uno o più parametri che ne consentono una maggiore duttilità. Anche il flusso del programma è decisamente diverso rispetto a quello visto nella programmazione non strutturata: infatti, il main continua ad esistere ma al suo interno appaiono soltanto le invocazioni alle procedure definite nel programma.
Quando una procedura ha terminato il suo compito il controllo ritorna nuovamente al main (o alla procedura che ne ha effettuato l’invocazione) che esegue una nuova chiamata ad un’altra procedura. fino alla terminazione del programma. Un semplice schema può facilitare la comprensione di tale concetto:
Il grande vantaggio della programmazione procedurale, rispetto alla precedente non strutturata consiste in un notevole abbattimento del numero di errori, che deriva dal fatto che se una procedura è corretta allora vi è la certezza che essa restituirà ad ogni invocazione dei risultati corretti in output.
Programmazione Modulare
La programmazione modulare rappresenta un’ ulteriore conquista. Sorgeva l’esigenza di poter riutilizzare le procedure messe a disposizione da un programma in modo che anche altri programmi ne potessero trarre vantaggio.
Così, l’idea fu quella di raggruppare le procedure aventi un dominio comune (ad esempio, procedure che eseguissero operazioni matematiche) in moduli separati.
Quando sentiamo parlare di librerie di programmi, in sostanza si fa riferimento proprio a moduli di codice indipendenti che ben si prestano ad essere inglobati in svariati programmi.
Il risultato, dunque, adesso è che un singolo programma non è più costituito da un solo file (in cui è presente il main e tutte le procedure) ma da diversi moduli (uno per il main e tanti altri quanti sono i moduli a cui il programma fa riferimento).
È importante, inoltre, dire che i singoli moduli possono contenere anche dei dati propri che, in congiunzione ai dati del main, vengono utilizzati all’interno delle procedure in essi contenute.
Programmazione ad Oggetti
La programmazione procedurale/modulare ha rappresentato il punto di riferimento nello sviluppo applicativo per tanti anni. Gradualmente ma inevitabilmente però, man mano che gli orizzonti della programmazione diventavano sempre più ampi, si andarono evidenziando i limiti di tale metodologia.
In particolare, un programma procedurale mal si prestava a realizzare il concetto di “Componente Software”, ovvero di un prodotto in grado di garantire le caratteristiche di riusabilità, modificabilità e manutenibilità.
Una delle cause di tale limite è da ricercare sicuramente nel fatto che esiste un evidente scollamento tra i dati e le strutture di controllo che agiscono su di essi; in altre parole i moduli risultano avere un approccio orientato alla procedura piuttosto che ai dati.
Con l’avvento della programmazione ad oggetti (i cui concetti saranno dettagliati a partire dal prossimo capitolo) questi limiti vennero superati. Contrariamente alle tecniche fin qui descritte, il paradigma OOP è basato sul fatto che esiste una serie di oggetti che interagiscono vicendevolmente, scambiandosi messaggi ma mantenendo ognuno il proprio stato ed i propri dati. Graficamente:
La programmazione ad oggetti, naturalmente, pur cambiando radicalmente l’approccio mentale all’analisi progettuale non ha fatto a meno dei vantaggi derivanti dall’uso dei moduli. Al contrario, tale tecnica è stata ulteriormente raffinata avvalendosi delle potenzialità offerte dalla programmazione ad oggetti.









