giovedì 19 luglio 2012

Appunti OOP: Paradigmi di programmazione

In questi appunti si analizza il supporto minimo richiesto ai linguaggi di programmazione per i vari paradigmi di programmazione

  • Procedurale
  • Modulare
  • Tipo di Dato Astratto
  • Orientata agli oggetti
evidenziando come ognuno sia naturale evoluzione dell'altro.

Programmazione procedurale

In principio fu l'algoritmo, ossia la sequenza ordinata e finita di passi atti a risolvere un problema. Ma al crescere dei programmi, gli algoritmi si presentavano ed intrecciavano più e più volte divenendo di difficile gestione e comprensione. L'algoritmo, sempre più esteso e complesso, induce la nascita della programmazione procedurale il cui paradigma è:
Si definiscano le procedure desiderate; si utilizzino gli algoritmi migliori.
Il supporto di tale paradigma è dato dalle funzioni, capaci di accettare degli argomenti e restituire valori.
Le funzioni, o procedure, consentono di mettere ordine in un dedalo di algoritmi.

Programmazione modulare

Al crescere dei programmi, le funzioni iniziano ad operare su dati sempre più complessi. Lo sviluppo del dato provoca la nascita di funzioni specializzate in operazioni su uno specifico dato. Occorre quindi mettere ordine in questo proliferare di dati e funzioni. Il dato resta nascosto, poiché non necessario a funzioni incapaci di gestirlo, e le funzioni capaci di gestire il dato sono raggruppate in un modulo di gestione. Nasce la programmazione modulare il cui paradigma è:
Si decida quali moduli si desiderano; si suddivida il programma in modo che i dati siano nascosti nei moduli.
Il modulo è l'insieme di dati (nascosti) e funzioni/procedure che lavorano su tali dati supportato dai linguaggi procedurali tramite la compilazione di unità separate e dai linguaggi orientati agli oggetti tramite le classi.

Tipo di Dato Astratto

Il modulo ha così permesso d'implementare per certi aspetti un tipo, centralizzando in se le funzioni applicabili al tipo tramite la manipolazione del dato nascosto (incapsulamento). Nel caso in cui siano necessari più dati di un tipo definito dal modulo, è possibile fare in modo che il modulo accentri in se tutti i dati di quel tipo e definisca la funzioni atte ad operare su una specifica istanza, piuttosto che attendere di ottenere una struttura dati su cui operare. Si arriva così all'astrazione dei dati, per cui:
Si decida quali tipi di desiderano; si fornisca un insieme completo di operazioni per ogni tipo.
L'astrazione dei dati porta alla definizione di tipi definiti dall'utente, la cui semantica è definita dall'interfaccia ossia dall'insieme delle funzioni che operano sull'implementazione interna del dato. Se da un lato la programmazione modulare consente l'astrazione dei dati, dall'altro la programmazione orientata agli oggetti la supporta. Con consentire s'intende il permettere il paradigma con fatica e abilità personale, mentre il supportare significa permettere il paradigma tramite costrutti del linguaggio tali da renderne l'implementazione semplice, sicura ed efficiente.

Programmazione orientata agli oggetti 

Il dato, sempre più complesso, è stato quindi organizzato in tipi per mezzo dell'astrazione dei dati. Ma cosa accade quando occorre definire due tipi simili pur avendo ciascuno delle specificità? Con la programmazione modulare occorre riscrivere integralmente il modulo, o fare in modo che il modulo sia capace di distinguere tutte le possibili casistiche. Un linguaggio dotato di costrutti utili a esprimere tale distinzione è un linguaggio che supporta la programmazione orientata agli oggetti:
Si determinino quali classi si desiderano; si fornisca un insieme completo delle operazioni di ogni classe; si renda esplicito ciò che hanno in comune mediante l'ereditarietà.
In altre parole il requisito minimo per un linguaggio che supporti la programmazione orientata agli oggetti è, oltre a consentire tipo di dato astratto, permettere l'ereditarietà tramite specifici costrutti.