Un programmatore nel corpo di un fumettaro.

sabato 9 gennaio 2010

Programmazione Orientata agli Oggetti Lez. 1

Corso poco professionale su come affrontare l'ostico mondo dell'OOP (Object Oriented Programming).

Il nome OOP lascia poco alla fantasia: "Programmazione Orientata agli Oggetti", quindi è abbastanza scontato che tutto ruoti attorno agli "Oggetti".
Cosa è un "Oggetto"?

Un Oggetto è una istanza di una "Classe", una Classe è la definizione di un insieme di variabili e funzioni che in OOP prendono il nome di "attributi" e "metodi".

Dato che il corso è poco professionale prenderò ad esempio uno di quei robot da cucina che tagliano, sminuzzano, impastano ecc.
Un robot da cucina è un Oggetto. Un manuale che spieghi come costruirlo e usarlo sarebbe la sua Classe.
Il robot ha la funzione "triturare" (il metodo) da usare con una data "velocità " (l'attributo).




Nell'OOP ci si avvale di tre proprietà principali:
Incapsulamento,
Ereditarietà,
Polimorfismo.

Incapsulamento
L'incapsulamento è la proprietà per cui un Oggetto contiene al suo interno, incapsula, sia gli attributi che i metodi. Alcuni di questi metodi sono accessibili dall'esterno, altri sono utilizzati solo dall'oggetto stesso e quindi invisibili, inoltre un oggetto ben progettato non rende accessibile i suoi attributi in maniera diretta ma solo attraverso dei metodi appositi.
Il nostro robot ha tanti metodi invisibili, noi non sappiamo cosa faccia girare la lama, come funzioni il blocco sicurezza ecc. sappiamo solo "triturare" perché è il metodo reso disponibile all'esterno. L'attributo "velocità" non è accessibile direttamente ma solo tramite la manopola apposita, quindi un altro metodo visibile che ci permette di modificare l'attributo "velocità". Altri attributi saranno nascosti come la "tensione elettrica", la "frizione", ecc.

Ereditarietà.
L'ereditarietà permette alle Classi di poter essere "derivate", cioè trasformate affinché vengano aggiunti nuovi metodi e/o attributi. I metodi aggiunti possono essere totalmente nuovi o sostituirne di esistenti (polimorfismo).
Il produttore del nostro robot potrebbe produrne uno identico al nostro ma con una lama aggiuntiva per "affettare", quindi avrebbe un nuovo metodo "affettare". La Classe del nostro robot è detta Classe Base, la nuova si chiama Classe Derivata.

Polimorfismo.
Con il polimorfismo una Classe Derivata può sostituire uno o più metodi della Classe Base con equivalenti con diversa implementazione.
Il nuovo robot derivato oltre ad affettare potrebbe avere una lama per "triturare" più affilata che trita più finemente, si avrebbe quindi lo stresso metodo "triturare" ma con un risultato diverso.

Uso di classi e oggetti.
Ora che abbiamo una bella infarinatura di Classi e Oggetti possiamo entrare nel dettaglio del loro uso.
Immaginiamo di dover preparare una torta!

Per fare la torta useremo alcune classi, le deriveremo e le metteremo in relazione tra loro.
Esaminiamo la ricetta:

Ingredienti:
4 uova
400gr farina
300gr zucchero
50gr burro

Preparazione:
Montare a neve 4 albumi di uovo.
Impastare gli albumi a neve con la farina e lo zucchero.
Imburrare una teglia.
Versare l'impasto nella teglia.
Infornare e cuocere per 45 minuti a 150gradi.

Dalla ricetta si evince che avremo bisogno di un frustino elettrico per montare gli albumi.
Un robot per impastare zucchero, farina e uova montate.
Una teglia da imburrare in cui verseremo l'impasto.
Un forno dove inserire la teglia e cuocere la torta.

Nota: con "intero" intendiamo un numero intero.

Classe FrustinoBase: è un frustino utile per montare le uova.
Ha come metodi accessibili:
impostaVelocità(intero),
impostaUova(intero),
monta() restituisce le uova montate.
Ha come attributi:
intero velocità,
intero quantità
Gli attributi non sono accessibili se non con i metodi "impostaXXX".

Classe RobotBase:  è il nostro robot di partenza che sa solo triturare.
Ha come metodi accessibili:
impostaVelocità(intero),
impostaQuantità(intero),
tritura().
Ha come attributi:
intero velocità,
intero quantità
Gli attributi non sono accessibili se non con i metodi "impostaXXX".

Dobbiamo impastare la farina con lo zucchero e le uova montate con il frustino. Per questa attività il robot non va bene e ha bisogno di essere potenziato, così lo deriviamo.

Classe RobotImpastatore derivato da RobotBase: è un robot da cucina che impasta.
Aggiungiamo i metodi pubblici:
impostaFarina(intero)
impostaZucchero(intero)
impostaUova(UovaMontate)
impasta() restituisce un Impasto.
Aggiungiamo nuovi attributi:
intero farina;
intero zucchero;
UovaMontate uovaMontate;

Classe TegliaBase: è una teglia.
Ha come metodi accessibili:
impostaImpasto(Impasto),
impostaBurro(intero),
imburra().
Ha come attributi:
intero burro,
Impasto impasto
Gli attributi non sono accessibili se non con i metodi "impostaXXX".

Classe FornoBase: è un forno.
Ha come metodi accessibili:
impostaTemperatura(intero),
impostaMinuti(intero),
inforna(TegliaBase),
cuociTorta() restituisce una torta.
Ha come attributi:
intero temperatura,
intero minuti
Gli attributi non sono accessibili se non con i metodi "impostaXXX".

Useremo anche due classi contenitore:
Classe UovaMontate e Classe Impasto sono classi che non è necessario approfondire perché ininfluenti, le dichiariamo solo per mantenere l'esempio concreto, UovaMontate conterrebbe le uova, Impasto conterrebbe UovaMontate, farina e zucchero.

Ora che abbiamo dichiarato i nostri utensili andiamo ad usarli.

Preparazione della torta

Iniziamo con il montare il bianco dell'uovo a neve:
Creiamo l'Oggetto FrustinoBase che monta solo le uova:

FrustinoBase mioFrustino.
Ora ho il mio oggetto frustino e posso usarlo per montare le uova.

Poiché gli oggetti incapsulano metodi e attributi ci vorrà un sistema per identificarli come appartenenti all'oggetto specificato, useremo il nome dell'oggetto seguito da un punto ".".

Metto quattro albumi nella ciotola del frustino:
mioFrustino.impostaUova(4);
Imposto la velocità a 3:
mioFrustino.impostaVelocità(3);
Monto le uova:
UovaMontate uovaMontate = mioFrustino.monta();

Abbiamo montato le uova.
Ora impastiamo:
Creiamo il robot impastatore:
RobotImpastatore mioImpastatore;
Aggiungiamo gli ingredienti:
mioImpastatore.impostaFarina(400);
mioImpastatore.impostaZucchero(300);
mioImpastatore.impostaUova(uovaMontate);

Ora selezioniamo la velocità e impastiamo:
mioImpastatore.impostaVelocità(2);
Impasto impasto = mioImpastatore.impasta();


Prendiamo la teglia e imburriamola:
TegliaBase miaTeglia;
miaTeglia.impostaBurro(50);
miaTeglia.imburra();

Versiamo l'impasto nella teglia:
miaTeglia.impostaImpasto(impasto);

Ora prepariamo il forno:
FornoBase mioForno;
mioForno.inforna(miaTeglia);
mioForno.impostaTemperatura(160);
mioForno.impostaMinuti(45);

Cuociamo:
Torta torta = mioForno.cuociTorta();

La torta è pronta.
Riepiloghiamo il flusso delle operazioni:

FrustinoBase mioFrustino;
mioFrustino.impostaUova(4);
mioFrustino.impostaVelocità(3);
UovaMontate uovaMontate = mioFrustino.monta();

RobotImpastatore mioImpastatore;
mioImpastatore.impostaFarina(400);
mioImpastatore.impostaZucchero(300);
mioImpastatore.impostaUova(uovaMontate);
mioImpastatore.impostaVelocità(2);
Impasto impasto = mioImpastatore.impasta();

TegliaBase miaTeglia;
miaTeglia.impostaBurro(50);
miaTeglia.imburra();
miaTeglia.impostaImpasto(impasto);

FornoBase mioForno;
mioForno.inforna(miaTeglia);
mioForno.impostaTemperatura(160);
mioForno.impostaMinuti(45);
Torta torta = mioForno.cuociTorta();


Avrete notato che alcuni oggetti ne usano altri, tipo il forno che usa la teglia, questo perché una Classe crea un nuovo tipo di dato e gli oggetti di questa Classe saranno dei dati, ricordiamo che un oggetto incapsula metodi ed attributi, quindi dati.

Per ora ci fermiamo, abbiamo imparato le basi e siamo già riusciti a fare una torta, incredibile.


Creative Commons License
Questa opera è pubblicata sotto una Licenza Creative Commons.