cerca
Dispense Tetty - Capitolo 4
modifica cronologia stampa login logout

Wiki

UniCrema


Materie per semestre

Materie per anno

Materie per laurea


Help

Uni.TettyCap4 History

Hide minor edits - Show changes to output

Changed lines 266-268 from:
[[Torna alla pagina di Programmazione degli Elaboratori -> Uni.ProgrammazioneElaboratori]]
----
[[!UniCrema
]]
to:
[[Torna alla pagina di Programmazione degli Elaboratori -> Uni.ProgrammazioneElaboratori]]
Changed line 3 from:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
to:
[[Torna alla pagina di Programmazione degli Elaboratori -> Uni.ProgrammazioneElaboratori]]
Changed line 266 from:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
to:
[[Torna alla pagina di Programmazione degli Elaboratori -> Uni.ProgrammazioneElaboratori]]
Changed lines 5-6 from:
!Programmazione orientata agli oggetti
to:
%titolo%''':: Capitolo 4: Programmazione orientata agli oggetti ::'''
Changed lines 265-267 from:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
to:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
----
[[!UniCrema
]]
June 18, 2007, at 09:00 PM by MINCULPOP - cambiato il titolo e aggiunti i link alle domande (in alto e in fondo)
Changed lines 1-3 from:
(:title Capitolo 4: Programmazione Orientata agli Oggetti:)
[[Torna alla pagina di Tetty -> Tetty]]
----
to:
(:title Dispense Tetty - Capitolo 4:)
Added lines 3-4:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
----
Added line 263:
Changed line 265 from:
[[Torna alla pagina di Tetty -> Tetty]]
to:
[[Torna alla pagina di Tetty -> Tetty]] | [[Guarda le domande sul capitolo -> TettyDom4]]
Changed lines 260-262 from:
I ''listeners'' devono implementare l'interfaccia ''XXXListener'', dove XXX è il tipo di evento a cui reagiscono (ce ne sono centinaia).
to:
I ''listeners'' devono implementare l'interfaccia ''XXXListener'', dove XXX è il tipo di evento a cui reagiscono (ce ne sono centinaia).\\\

[[#su|[-'''Torna su'''-]]]
Changed lines 21-23 from:
to:
3 [[Interfacce utente -> #c47]]
-> 3.1 Interfacce a carattere
-> 3.2 Interfacce grafiche
Added lines 213-260:
[[#c47]]
!!!3. Interfacce utente
Anche l'utente ha bisogno di interagire con un programma! Il modo con cui lo può fare è - tadam! - un' ''interfaccia utente''! Come per le interfacce delle classi, l'interfaccia utente è una lista di cose che l'utente può fare per far fare al programma quello che vuole.\\\

!!!!3.1 Interfacce a carattere
Qualcuno ne ha mai usata una? Ma certo, quando scriviamo i programmi del Laboratorio di C, e da console immettiamo i dati, abbiamo realizzato una primitiva interfaccia a carattere.\\\

Storicamente sono state le prime ad apparire, perché le più semplici da realizzare. L'utente dialoga col programma tramite il terminale, una volta c'era solo il terminale e quindi non c'era molta scelta.\\\

Ci sono due tipi di interfacce a carattere: quelle ''guidate'' e quelle ''libere''.\\\

Le interfacce '''guidate''' presentano dei menu oppure delle richieste di dati a cui si può rispondere in un solo modo. Questo è il caso delle nostre applicazioncine da laboratorio. Il programma in cui si chiedeva il nome del file da aprire era un'interfaccia guidata. Potevo fare solo quello.\\\

Le interfacce '''libere''' invece sono quelle in cui compare il famoso ''prompt'' dei programmi. Il ''prompt'' è per esempio quello che compare quando aprite la console di windows: il cursore lampeggia e attende istruzioni. Le istruzioni possono essere semplici (dir) oppure complesse (move *.exe d:\cartella) quanto si vuole. Ci sono alcune applicazioni in cui l'interfaccia libera è tanto potente da essere quasi un linguaggio di programmazione. Potete pensare alla Shell di Linux.\\\

È ovvio che le interfacce a carattere guidate non solo sono più semplici da usare, ma anche più semplici da scrivere! Quelle libere invece sono difficili da scrivere, nella misura in cui il "linguaggio" che abbiamo deciso di implementare è complesso, e nella stessa misura sono anche "difficili" da usare. Molto meglio per l'utente avanzato, che in una Shell di un qualsiasi Unix può fare in pochi secondi quello che l'utente medio di Windows ci mette 3 ore cliccando a destra e a sinistra. (Nota: per copiare dalla chiavetta faccio così: [@mount /mnt/chiavetta && cp /mnt/chiavetta/* downloads && umount /mnt/chiavetta@]. Qualcuno nota della differenza con il clicca di qua, clicca di là, cos'accadrà cos'accadrà!?:)\\
Questo tanto per dirvi che le interfacce a carattere non sono morte e non sono un ricordo del passato, anzi! Sono vive e vegete e spesso sono l'unico modo veloce per fare certe operazioni. Sono poco accattivanti, ma il computer deve innanzitutto funzionare...:)

!!!!3.2 Interfacce grafiche
Sono nate alla Xerox di Palo Alto negli anni 80. No, le finestre non le ha inventate micro$oft con windows. Anzi. Alla Xerox avevano inventato quel ridicolo oggetto chiamato ''mouse'', che muoveva un cursore sullo schermo, cliccava di qua e di là e faceva accadere cose. I dirigenti Xerox pensavano che una cosa del genere sarebbe stata poco seria: non vedevano dei rispettabili manager agitare frecce per lo schermo come in un videogioco! Fu così che dell'idea si appropriò Steve Jobs, per i suoi primi Apple.\\\

Requisito fondamentale per le interfacce grafiche è di avere un computer con... capacità grafiche! Queste capacità non sono state affatto scontate fino a metà anni 80: occorreva una costosa scheda video ed un monitor adatto. Ricordo il mio primo pc su cui girava Windows 2.1 (installato dai floppony da 5-1/4 pollici), e lo schermo era ''verde'', ad una risoluzione bassa, con qualche sfumatura di grigio naturalmente visualizzata ''verde''. La vita era difficile, ai tempi... Per la cronaca era un Olivetti M24.\\\

Le ''Graphical User Interface'', chiamate GUI, lavorano ad un livello simbolico. L'icona di un programma rappresenta un programma, il ''desktop'' è un simbolo per una scrivania di un ufficio, e così via. Si tratta di un'intuizione geniale.\\\

L'utente di una GUI è lui a determinare il flusso degli eventi: non c'è il programmino in C che funziona in un solo verso: dammi il numero di chilometri percorsi; dammi il numero di litri consumati; ecco che ti dico quanti chilometri fai con un litro. L'interazione dell'utente con gli elementi della GUI (menu, bottoni, liste...) provoca degli ''eventi'', che vanno interpretati: l'applicazione reagisce all'utente.\\\

Per gestire questa faccenda degli eventi, un sistema GUI deve avere almeno questi 3 elementi:
* Una ''coda degli eventi'', in cui tutti gli eventi generati vengono infilati come in uno stack, in attesa di essere analizzati;
* un ''dispatcher'', cioè uno smistatore di eventi, che pesca un evento dalla coda, guarda di che tipo è e lo smista al suo...
* ''gestore di eventi'': la parte di programma che gestisce l'evento.

Se clicco sul menu [@File@], genero un evento [@L'utente ha cliccato sul menu file@]. Quest'evento finisce nella coda. Il dispatcher lo prende e dice: [@Mmm, un evento di tipo menu. Adesso vedo a chi lo devo mandare...@] e quando lo trova glielo manda.\\\

Ma il concetto di ''evento'' non si limita al bottone premuto o alla finestra che scorre. Può essere di qualsiasi tipo. Per esempio, se clicco sulla voce [@Salva@] del menu [@File@], genero un evento particolare, che potrebbe chiamarsi [@L'utente vuole salvare quello che ha scritto@], e qualcuno deve occuparsi di questo evento.\\\

La OOP si presta bene alla programmazione di GUI. Le classi fondamentali da implementare sono le seguenti:
* una classe per gli '''eventi''': deve poter rappresentare tutto ciò che può succedere in un programma, e avere un'interfaccia standard;
* un '''dispatcher''', che controlla la coda degli eventi e li manda ai ''listeners'' registrati;
* alcuni '''listeners''': si tratta di classi che si ''iscrivono'' presso il registro del dispatcher e dicono: "Io mi occupo del menu file"; "Io invece del pulsante di chiusura"; "Io del bottone che dice 'Clicca qui per vincere 10.000$'";
* delle classi che invece gli eventi li generano.

Come potete vedere, questo è un ''pattern''. Perché? Perché siccome tutte le GUI funzionano così, una volta che ho individuato uno schema di lavoro (quello qui sopra) tutte le altre GUI, pur diverse, saranno tutte simili.\\\

La programmazione di GUI, come si può intuire, è di molto più complessa rispetto alla programmazione di altre interfacce a carattere.\\\

Anche JAVA offre la possibilità di scrivere programmi con GUI, e lo fa attraverso la libreria JAVA.AWT. AWT sta per ''Advanced Windowing Toolkit''. ''Toolkit'' vuol dire ''cassetta degli attrezzi''.\\
I ''listeners'' devono implementare l'interfaccia ''XXXListener'', dove XXX è il tipo di evento a cui reagiscono (ce ne sono centinaia).
Changed line 262 from:
[[Torna alla pagina di Tetty -> Tetty]]
to:
[[Torna alla pagina di Tetty -> Tetty]]
Deleted line 1:
%center bgcolor=red border='3px dotted yellow' padding=3px define=warning%
Deleted lines 4-6:
%warning%'''Warning!'''\\
Si cerca qualche anima pia che sottolinei in rosso le risposte alle domande, e magari alla fine metta anche la lista delle domande collegate al capitolo
----
Changed line 58 from:
Uno dei vantaggi dell'incapsulamento è che posso mantenere l'interfaccia, e modificarne il contenuto come voglio, senza che il resto del sistema ne soffra. Ciò permette di limitare le dipendenze tra i vari oggetti alle sole %red%interfacce, che meglio rappresentano l'idea di dato astratto.\\
to:
Uno dei vantaggi dell'incapsulamento è che posso mantenere l'interfaccia, e modificarne il contenuto come voglio, senza che il resto del sistema ne soffra. Ciò permette di limitare le dipendenze tra i vari oggetti alle sole %red%interfacce, che meglio rappresentano l'idea di dato astratto.%%\\
Changed lines 30-31 from:
La Programmazione Orientata agli Oggetti (OOP da qui in poi) rappresenta lo sviluppo delle intuizioni della programmazione strutturata, concentrandosi più sui dati da manipolare, piuttosto che sulle procedure che eseguono la manipolazione.
to:
La Programmazione Orientata agli Oggetti (OOP da qui in poi) rappresenta lo sviluppo delle intuizioni della programmazione strutturata, %red%concentrandosi più sui dati da manipolare, piuttosto che sulle procedure che eseguono la manipolazione.
Changed lines 33-34 from:
L'idea che sta alla base dell'astrazione è frammentare un sistema complesso nei suoi costituenti fondamentali, in modo da descrivere questi ultimi nel modo più semplice e preciso possibile.
to:
%red%L'idea che sta alla base dell'astrazione è frammentare un sistema complesso nei suoi componenti fondamentali, descrivendoli nel modo più semplice e preciso possibile trascurandone i dettagli non rilevanti.
Changed lines 36-37 from:
Il '''Tipo di Dato Astratto''' trascura la rappresentazione fisica del dato nella macchina: in generale ciò al programmatore non importa.\\\
to:
%red%Il '''Tipo di Dato Astratto''' è un modello che definisce un insieme di operazioni che costituiscono la sua interfaccia, e il suo dominio di applicazione è definito da assiomi e precondizioni.%% Esso trascura la rappresentazione fisica del dato nella macchina, poiché in generale ciò al programmatore non importa.\\\
Changed line 50 from:
* ''TOP'', che restituisce il dato in cima alla pila (''precondizione'': lo stack deve contenere almeno un dato);
to:
* %red%''TOP'', che restituisce il dato in cima alla pila (''precondizione'': il numero di elementi sullo stack è positivo, ovvero la pila deve contenere almeno un dato);
Changed lines 56-58 from:
Il programmatore OOP individua i ''concetti'' del suo programma, e li intuorla, incapsulandoli da qualche parte.\\\

Uno dei vantaggi dell'incapsulamento è che posso mantenere l
'interfaccia, e modificarne il contenuto come voglio, senza che il resto del sistema ne soffra. Ciò permette di limitare le dipendenze tra i vari oggetti alle sole interfacce.\\
to:
%red%Il programmatore OOP individua i ''concetti'' del suo programma, e li intuorla, incapsulandoli da qualche parte e nascondendone i dettagli implementativi.\\\

Uno dei vantaggi dell
'incapsulamento è che posso mantenere l'interfaccia, e modificarne il contenuto come voglio, senza che il resto del sistema ne soffra. Ciò permette di limitare le dipendenze tra i vari oggetti alle sole %red%interfacce, che meglio rappresentano l'idea di dato astratto.\\
Changed line 125 from:
L'Oggetto è una particolare incarnazione della Classe: come dicevo qui sopra, l'incarnazione di Dario del suo conto corrente è fatta in un modo, quella di Patty in in altro.\\
to:
L'Oggetto è una particolare incarnazione della Classe: come dicevo qui sopra, l'incarnazione di Dario del suo conto corrente è fatta in un modo, quella di Patty in in altro. \\
Added lines 130-131:
%red%Si può dire che l'idea tradizionale di struttura dati trova nell'OOP il suo corrispettivo nell'oggetto.
Changed line 161 from:
Il ''Pattern'' è un motivo, una soluzione ad un problema comune. In genere i problemi che saltano fuori durante la programmazione sono bene o male sempre quelli, cambia solo qualche dettaglio qua e là.\\
to:
%red%Il ''Pattern'' descrive un problema che si incontra comunemente nello scrivere programmi ed il nucleo della sua soluzione.%% Infatti, i problemi che saltano fuori durante la programmazione sono bene o male sempre quelli, cambia solo qualche dettaglio qua e là.\\
Changed lines 173-176 from:
I pattern servono proprio a questo, cercare di mettere su carta l'impalpabile essenza dell'esperienza, seguendo lo schema seguente:
* nome;
* descrizione del problema e contesto di soluzione;
* soluzione
to:
I pattern servono proprio a questo, cercare di mettere su carta l'impalpabile essenza dell'esperienza. %red%I suoi elementi essenziali sono:
* %red%nome;
* %red%descrizione del problema%% e contesto di soluzione;
* %red%soluzione
Changed line 179 from:
* conseguenze dell'applicazione del pattern
to:
* %red%conseguenze%% dell'applicazione del pattern
Changed lines 24-26 from:
-> 2.6 Gestione della variabilità
-> 2.7
Riusabilità in Java
to:
-> 2.6 Riusabilità in Java
Changed line 159 from:
Il ''Pattern'' è un motivo, una soluzione ad un problema comune. In genere i problemi che saltano fuori durante la programmazione sono bene o male sempre quelli, cambiano un po' qua e là.\\
to:
Il ''Pattern'' è un motivo, una soluzione ad un problema comune. In genere i problemi che saltano fuori durante la programmazione sono bene o male sempre quelli, cambia solo qualche dettaglio qua e là.\\
Changed lines 161-167 from:
* identificare bene gli oggetti
* raggrupparli in classi che dividano nel giusto modo tra proprietà della classe e proprietà dell'oggetto
* definire le interfacce
* stabilire le ''gerarchie'' tra classi e interfacce
* stabilire relazioni tra classi: questa classe comprende quella etc.

Il
trucco è di rispettare le specifiche, ma di rimanere anche abbasanza generici da poter trattare anche altri problemi simili.\\
to:
* identificare bene gli oggetti;
* raggrupparli in classi che dividano nel giusto modo proprietà della classe e proprietà dell'oggetto;
* definire le interfacce;
* stabilire le ''gerarchie'' tra classi e interfacce;
* stabilire relazioni tra classi ("''questa classe comprende quella...''", etc).

Il
trucco è rispettare le specifiche, ma rimanere anche abbasanza generici da poter trattare altri problemi simili.\\
Changed lines 170-173 from:
Le aziende di software quindi dipendono tanto dal bagaglio di conoscenze dei proprio programmatori esperti. Ma se questi se ne vanno, che fanno? Portano con sé tutto quello che sanno e non lasciano dietro niente?\\
I pattern servono proprio a questo: cercare di mettere su carta l'impalpabile essenza dell'esperienza, seguendo lo schema seguente:
* nome
* descrizione del problema e contesto
to:
Le aziende di software dipendono molto dal bagaglio di conoscenze dei proprio programmatori esperti. Ma se questi se ne vanno, cosa gli rimane? Loro portano tutto quello che sanno con sé e non lasciano dietro niente?\\
I pattern servono proprio a questo, cercare di mettere su carta l'impalpabile essenza dell'esperienza, seguendo lo schema seguente:
* nome;
* descrizione del problema e contesto di soluzione;
Changed lines 175-182 from:
-> * classi e oggetti costitutivi
-> * loro relazioni
* conseguenze dell'applicazione di questo pattern
-> * risultati
-> * vantaggi e svantaggi

Sono un po' i mattoncini di base della programmazione Bottom - Up, solo
che qui mi danno un prefabbricato intero con fondamenta e pareti già tirate su.\\\
to:
** classi e oggetti costitutivi;
** loro relazioni;
* conseguenze dell'applicazione del pattern
** risultati;
** vantaggi e svantaggi.

Concludendo, si può dire che i pattern sono un po' i mattoncini di base della programmazione ''Bottom - Up'', con la differenza
che qui mi danno un prefabbricato intero con fondamenta e pareti già tirate su.\\\
Changed lines 184-185 from:
...
to:
Mettendo insieme due idee potenti come l'incapsulamento e il pattern, si arriva al concetto di ''componente''. Un componente non è altro che un programma in grado di svolgere una data funzione, ma concepito in modo tale da funzionare in diversi ambienti ed essere combinato con altri componenti per creare applicazioni più complesse. Certo, perché questo accada i componenti non possono essere sviluppati a {-cazzo-} caso, ma devono rispettare certi standard comuni per poter essere compatibili e sviluppare così una coerente architettura di componenti (come ad esempio la ''Java Beans'').

I componenti generalizzano il compito che nei OOP svolgono gli oggetti, ovvero raggruppare una struttura dati e relative operazioni in un'entità logica autonoma, portandola alle estreme conseguenze. Un sistema complesso può infatti essere composto da diversi componenti anche scritti in linguaggi diversi, purché compatibili
.
Changed lines 192-196 from:
* che compito svolge
* come gestisce le anomalie
* come garantise la sicurezza
* come comunica con altri componenti
to:
* che compito svolge;
* come gestisce le anomalie;
* come garantise la sicurezza;
* come comunica con altri componenti.
Changed lines 208-213 from:
!!!!2.6 Gestione della variabilità
...

!!!!2.7 Riusabilità in Java
...
to:
!!!!2.6 Riusabilità in Java
Java ha tra i principali obiettivi quello di produrre codici riusabili, e lo fa - come detto all'inizio - concentrandosi sulle interfacce piuttosto che sulle implementazioni
.
Added lines 131-132:
Per concludere con un'ultima nota di terminologia, le operazioni che si possono compiere su un oggetto o su una classe di oggetti vengono chiamati ''metodi''.
Changed lines 153-155 from:
La OOP è quella che meglio supporta il riuso del codice:
* l'incapsulamento definisce bene l'interfaccia
* le librerie contengono Classi, non sottoprogrammi, col vantaggio che non posso perdere funzioni per strada, ma le ho tutte assieme alla classe come suoi metodi
to:
La OOP è quella che meglio supporta il riuso del codice, infatti:
* l'incapsulamento definisce bene l'interfaccia;
* le librerie contengono Classi, non sottoprogrammi, col vantaggio che non posso perdere funzioni per strada, ma vengono mantenute assieme ad esse come suoi metodi;
Changed lines 41-44 from:
-> * Nome
-> * Operazioni consentite
-> * Assiomi e Precondizioni
to:
** Nome
** Operazioni consentite
** Assiomi e Precondizioni
Added lines 49-54:
Altro esempio più elaborato è quello dello stack. La sua interfaccia minima è definita da:
* ''PUSH <dato>'', che aggiunge un dato in cima alla pila;
* ''TOP'', che restituisce il dato in cima alla pila (''precondizione'': lo stack deve contenere almeno un dato);
* ''DROP'', che elimina il dato in cima alla pila (ha la stessa ''precondizione'' di prima).
Un assioma potrebbero essere che "TOP non varia il numero dei dati contenuti nella pila", oppure che "se lo stack contiene ''n'' elementi, dopo l'istruzione DROP ne contiene "''n-1''".
Changed line 62 from:
Domanda: ''ma non si può fare la stessa cosa con un linguaggio strutturato? Per esempio, creo delle [@struct@], e creo delle funzioni che le manipolino''.\\
to:
Domanda: ''ma non si può fare la stessa cosa con un linguaggio strutturato? Per esempio, creo delle [@struct@], e creo delle funzioni che le manipolino?''.\\
Changed lines 119-120 from:
La ''Classe'' è il tipo di dato astratto che descrive tutti i casi particolari. Una Classe ''Conto Corrente'' descrive sia il conto presso la Banca Popolare di Lodi, che presso la Banca del Seme. E' l'ultimo gradino di un processo di astrazione:
to:
La ''Classe'' è il tipo di dato astratto che descrive tutti i casi particolari di oggetti di un certo tipo. Una Classe ''Conto Corrente'' descrive sia il conto presso la Banca Popolare di Lodi, che presso la Banca del Seme. E' l'ultimo gradino di un processo di astrazione:
Changed line 123 from:
Parto dalla realtà, e ne creo un modello. Il mio modello (la mia banca, in questo esempio) vedo che è composto da entità monadiche, i miei conti correnti. Ho tanti conti, quello di Patrizia pieno delle bustarelle della Lobby del Fil di Ferro, e quello di Dario finanziato dai Terroristi Tettamanziani per la Jihad del Pinguino, ma sono tutti simili. Quindi, astraggo ancora, e arrivo al tipo di dato astratto: la Classe ''Conto Corrente''. Applausi, prego.\\
to:
Parto dalla realtà, e ne creo un modello. Il mio modello (la mia banca, in questo esempio) vedo che è composto da entità monadiche, i miei conti correnti. Ho tanti conti, quello di [[Patrizia]] pieno delle bustarelle della Lobby del Fil di Ferro, e quello di [[Dario]] finanziato dai Terroristi Tettamanziani per la Jihad del Pinguino, ma sono tutti simili. Quindi, astraggo ancora, e arrivo al tipo di dato astratto: la Classe ''Conto Corrente''. Applausi, prego.\\
Changed lines 129-130 from:
Torniamo all'esempio delle automobili: ho creato la Classe [[126]], che ha un motore di 650 cm'^3^' e una potenza di 23 cavalli. Voglio poi implementare il Garage di [[Dario]], che in un roseo futuro ne possiede 8. Ognuna di queste 126 appartiene alla Classe 126. Quindi, tutti i miei oggetti condivideranno la cilindrata e la potenza. Ecco quindi che la cilindrata e la potenza sono dati che appartengono alla Classe, mentre la targa di ogni singolo pezzo della collezione appartiene all'oggetto, cioè all'incarnazione (in gergo OOP, istanza).
to:
Torniamo all'esempio delle automobili: ho creato la Classe [[126]], che ha un motore di 650 cm'^3^' e una potenza di 23 cavalli. Voglio poi implementare il Garage di Dario, che in un roseo futuro ne possiede 8. Ognuna di queste 126 appartiene alla Classe 126. Quindi, tutti i miei oggetti condivideranno la cilindrata e la potenza. Ecco quindi che la cilindrata e la potenza sono dati che appartengono alla Classe, mentre la targa di ogni singolo pezzo della collezione appartiene all'oggetto, cioè all'incarnazione (in gergo OOP, ''istanza'').
Changed lines 139-143 from:
Ci sono 3 approcci al riuso del codice
# Librerie di Componenti Riusabili
# Schemi trasformazionali a spettro ristretto
# Schemi trasformazionali a spettro largo
to:
Ci sono 3 approcci fondamentali al riuso del codice
# Librerie di Componenti Riusabili;
# Schemi trasformazionali a spettro ristretto;
# Schemi trasformazionali a spettro largo.
Changed line 145 from:
* o uso codice di una libreria senza modifiche (succede miliardi di volte al giorno, è comodissimo)
to:
* o uso codice di una libreria senza modificarlo (succede miliardi di volte al giorno, è comodissimo),
Changed lines 148-149 from:
Gli '''schemi trasformazionali''' fanno uso di linguaggi di descrizione di algoritmi, ad alto o basso livello, che mi generano automaticamente il codice che mi serve nel linguaggio che voglio. Per esempio, le interfacce grafiche che mi permettono di mettere insieme una finestra, coi bottoni e le linee e così via e poi mi generano il codice C++ corrispondente sono un esempio di questa roba. Il [[Tetty]] non ha specificato la differenza tra spettro ampio e ristretto, che non è importante.\\\
to:
Gli '''schemi trasformazionali''' fanno uso di linguaggi di descrizione di algoritmi, ad alto o basso livello, che generano automaticamente il codice che mi serve nel linguaggio che voglio. Ne sono un esempio le interfacce grafiche che mi permettono di mettere insieme una finestra con tutti gli annessi e connessi, generando automaticamente il codice C++ corrispondente. Il [[Tetty]] non ha specificato la differenza tra spettro ampio e ristretto, che non è importante.\\\
Changed lines 31-32 from:
La Programmazione Orientata agli Oggetti (OOP da qui in poi) rappresenta lo sviluppo delle intuizioni della progarmmazione strutturata.
to:
La Programmazione Orientata agli Oggetti (OOP da qui in poi) rappresenta lo sviluppo delle intuizioni della programmazione strutturata, concentrandosi più sui dati da manipolare, piuttosto che sulle procedure che eseguono la manipolazione.
Changed lines 34-35 from:
...
to:
L'idea che sta alla base dell'astrazione è frammentare un sistema complesso nei suoi costituenti fondamentali, in modo da descrivere questi ultimi nel modo più semplice e preciso possibile.
Changed line 6 from:
Si cerca qualche anima pia che metta un sommario a questa pagina, e sottolinei in rosso le risposte alle domande, e magari alla fine metta anche la lista delle domande collegate al capitolo
to:
Si cerca qualche anima pia che sottolinei in rosso le risposte alle domande, e magari alla fine metta anche la lista delle domande collegate al capitolo
Added lines 8-30:
[[#su]]
!Programmazione orientata agli oggetti

!!!Indice
1 [[#c41|Concetti fondamentali]]
-> 1.1 Astrazione
-> 1.2 Tipi di dati astratti
-> 1.3 Incapsulamento
-> 1.4 Esempio di incapsulamento balordo in C
-> 1.5 Classi e oggetti
2 [[#c42|Riuso del software]]
-> 2.1 Approcci al riuso del software
-> 2.2 Riuso del software e programmazione ad oggetti
-> 2.3 Pattern
-> 2.4 Componenti
-> 2.5 Programmazione orientata agli aspetti
-> 2.6 Gestione della variabilità
-> 2.7 Riusabilità in Java

----

[[#c41]]
!!!1. Concetti fondamentali
Changed lines 33-36 from:
!!!!Tipo di Dato Astratto
to:
!!!!1.1 Astrazione
...

!!!!1.2
Tipo di Dato Astratto
Changed line 49 from:
!!!!Incapsulamento
to:
!!!!1.3 Incapsulamento
Changed line 61 from:
!!!!Esempio di incapsulamento balordo in C
to:
!!!!1.4 Esempio di incapsulamento balordo in C
Changed line 112 from:
!!!!Classi e Oggetti
to:
!!!!1.5 Classi e Oggetti
Changed lines 125-129 from:
!!!!Riuso del codice
to:
[[#su|[-'''Torna su'''-]]]


[[#c42]]
!!!2.
Riuso del codice
Added line 132:
!!!!2.1 Approcci al riuso del software
Added line 144:
!!!!2.2 Riuso del software e programmazione ad oggetti
Changed lines 150-151 from:
La OOP tuttavia non basta: occorre uno '''Schema Progettuale''' = '''Patterni'''.\\
to:
!!!!2.3 Pattern
La
OOP tuttavia non basta: occorre uno '''Schema Progettuale''' = '''Pattern'''.\\
Changed lines 176-179 from:
!!!!Aspetti
to:
!!!!2.4 Componenti
...

!!!!2.5 Programmazione orientata agli aspetti
Added lines 198-206:

!!!!2.6 Gestione della variabilità
...

!!!!2.7 Riusabilità in Java
...

[[#su|[-'''Torna su'''-]]]
Added line 2:
%center bgcolor=red border='3px dotted yellow' padding=3px define=warning%
Added lines 5-7:
%warning%'''Warning!'''\\
Si cerca qualche anima pia che metta un sommario a questa pagina, e sottolinei in rosso le risposte alle domande, e magari alla fine metta anche la lista delle domande collegate al capitolo
----
Changed lines 157-159 from:
Per Java, esiste [[AspectJ -> http://www.aspectj.org]], a cui sono seguiti altri software dedicati ad altri linguaggi, come [[AspectC++ -> http://www.aspectc.org]]. In pratica, si tratta di estensioni del linguaggio di programmazione, che permettono di separare gli aspetti. Ci sono i punti di giunzione fra vari aspetti e robe così. Poi il programma prende in mano tutto ciò e scrive il programma finito in C++ o in Java o quello che è. Se devo modificare un aspetto, non vado a cercare nel codice ''generato'', ma lavoro ancora in AspectJ. Si tratta di una tecnologia molto recente, non ancora ben digerita e sviluppata.
to:
Per Java, esiste [[AspectJ -> http://www.aspectj.org]], a cui sono seguiti altri software dedicati ad altri linguaggi, come [[AspectC++ -> http://www.aspectc.org]]. In pratica, si tratta di estensioni del linguaggio di programmazione, che permettono di separare gli aspetti. Ci sono i punti di giunzione fra vari aspetti e robe così. Poi il programma prende in mano tutto ciò e scrive il programma finito in C++ o in Java o quello che è. Se devo modificare un aspetto, non vado a cercare nel codice ''generato'', ma lavoro ancora in AspectJ. Si tratta di una tecnologia molto recente, non ancora ben digerita e sviluppata.
----
[[Torna alla pagina di Tetty -> Tetty]]
Changed lines 140-141 from:
'''Warning: qui entriamo nel filosofico'''.\\\
to:
''Warning: qui entriamo nel filosofico''.\\\
Changed lines 155-157 from:
Separare gli aspetti rende il mio programma più chiaro e più manutenibile, ed è più facile avere componenti riutilizzabili.
to:
Separare gli aspetti rende il mio programma più chiaro e più manutenibile, ed è più facile avere componenti riutilizzabili.\\\

Per Java, esiste [[AspectJ -> http://www.aspectj.org]], a cui sono seguiti altri software dedicati ad altri linguaggi, come [[AspectC++ -> http://www.aspectc.org]]. In pratica, si tratta di estensioni del linguaggio di programmazione, che permettono di separare gli aspetti. Ci sono i punti di giunzione fra vari aspetti e robe così. Poi il programma prende in mano tutto ciò e scrive il programma finito in C++ o in Java o quello che è. Se devo modificare un aspetto, non vado a cercare nel codice ''generato'', ma lavoro ancora in AspectJ. Si tratta di una tecnologia molto recente, non ancora ben digerita e sviluppata
.
Changed lines 148-155 from:
Un linguaggio di programmazione può essere adatto ad esprimere bene uno di questi aspetti, ma non un altro. Nessun linguaggio ''cattura'' tutti gli aspetti. Per esempio, il C svolge bene il suo compito, ma gestire le anomalie col C è una spina nel culo, senza contare che la sicurezza di funzione come [@fscanf@] e compagnia è limitata (chi controlla che il [@char *@] passato alla [@fscanf@] sia abbastanza grande? Nessuno! e così via).
to:
Un linguaggio di programmazione può essere adatto ad esprimere bene uno di questi aspetti, ma non un altro. Nessun linguaggio ''cattura'' tutti gli aspetti. Per esempio, il C svolge bene il suo compito, ma gestire le anomalie col C è una spina nel culo, senza contare che la sicurezza di funzione come [@fscanf@] e compagnia è limitata (chi controlla che il [@char *@] passato alla [@fscanf@] sia abbastanza grande? Nessuno! e così via).\\\

Un programma presenta tutti questi aspetti inestricabilmente mischiati insieme. Provate a scriverne uno qualsiasi, anche semplice, e vedrete linee di codice che si occupano delle anomalie ([@if (Fp1 == null) ...@]) seguite da linee che si occupano della comunicazione ([@printf("Brao asen!\n");@]) e così via.\\\

Quando parlavamo della modularità, dicevamo di poter scomporre un programma complesso in blocchi funzionali. Qui è più o meno la stessa cosa: scompongo il programma in base agli aspetti.\\\

Per gestire queste cose complesse esistono dei ''linguaggi orientati agli aspetti'', che si occupano di tutto ciò. Descrivo i vari aspetti separatamente, e poi con un ''tessitore di aspetti'', detto ''weaver'', li metto insieme e compongo il mio programma.\\
Separare gli aspetti rende il mio programma più chiaro e più manutenibile, ed è più facile avere componenti riutilizzabili
.
Changed lines 143-148 from:
to:
* che compito svolge
* come gestisce le anomalie
* come garantise la sicurezza
* come comunica con altri componenti

Un linguaggio di programmazione può essere adatto ad esprimere bene uno di questi aspetti, ma non un altro. Nessun linguaggio ''cattura'' tutti gli aspetti. Per esempio, il C svolge bene il suo compito, ma gestire le anomalie col C è una spina nel culo, senza contare che la sicurezza di funzione come [@fscanf@] e compagnia è limitata (chi controlla che il [@char *@] passato alla [@fscanf@] sia abbastanza grande? Nessuno! e così via).
Changed lines 93-143 from:
Torniamo all'esempio delle automobili: ho creato la Classe [[126]], che ha un motore di 650 cm'^3^' e una potenza di 23 cavalli. Voglio poi implementare il Garage di [[Dario]], che in un roseo futuro ne possiede 8. Ognuna di queste 126 appartiene alla Classe 126. Quindi, tutti i miei oggetti condivideranno la cilindrata e la potenza. Ecco quindi che la cilindrata e la potenza sono dati che appartengono alla Classe, mentre la targa di ogni singolo pezzo della collezione appartiene all'oggetto, cioè all'incarnazione (in gergo OOP, istanza).
to:
Torniamo all'esempio delle automobili: ho creato la Classe [[126]], che ha un motore di 650 cm'^3^' e una potenza di 23 cavalli. Voglio poi implementare il Garage di [[Dario]], che in un roseo futuro ne possiede 8. Ognuna di queste 126 appartiene alla Classe 126. Quindi, tutti i miei oggetti condivideranno la cilindrata e la potenza. Ecco quindi che la cilindrata e la potenza sono dati che appartengono alla Classe, mentre la targa di ogni singolo pezzo della collezione appartiene all'oggetto, cioè all'incarnazione (in gergo OOP, istanza).

!!!!Riuso del codice
Fino ad ora ''Riuso del Codice'' ha significato il Copia e Incolla di codice scritto da altri. Riscrivere codice è costoso. Ogni anno la potenza di calcolo cresce mediamente del 20%, mentre la produttività dello sviluppo aumenta solo dell'8%. Il divario tra questi due fattori di crescita mi dice che per quanto mi sforzi, sarò sempre in perdita rispetto a quello che potrei guadagnare con l'aumento della potenza di calcolo. Ecco perché occorre far di tutto per rendere la programmazione il meno costosa possibile, e un modo per farlo è riusare il codice in modo intelligente.\\\

Ci sono 3 approcci al riuso del codice
# Librerie di Componenti Riusabili
# Schemi trasformazionali a spettro ristretto
# Schemi trasformazionali a spettro largo

Le '''librerie''' sono il sistema più usato:
* o uso codice di una libreria senza modifiche (succede miliardi di volte al giorno, è comodissimo)
* o adatto pezzi di programma al mio scopo, cioè riscrivo il minimo possibile di una libreria già fatta (si può fare anche in automatico, ma è un ramo dell'informatica ancora non ben studiato).\\\

Gli '''schemi trasformazionali''' fanno uso di linguaggi di descrizione di algoritmi, ad alto o basso livello, che mi generano automaticamente il codice che mi serve nel linguaggio che voglio. Per esempio, le interfacce grafiche che mi permettono di mettere insieme una finestra, coi bottoni e le linee e così via e poi mi generano il codice C++ corrispondente sono un esempio di questa roba. Il [[Tetty]] non ha specificato la differenza tra spettro ampio e ristretto, che non è importante.\\\

La OOP è quella che meglio supporta il riuso del codice:
* l'incapsulamento definisce bene l'interfaccia
* le librerie contengono Classi, non sottoprogrammi, col vantaggio che non posso perdere funzioni per strada, ma le ho tutte assieme alla classe come suoi metodi
* incorpora già di suo la possibilità di estendere il codice, tramite le estensioni di classe e di interfaccia.

La OOP tuttavia non basta: occorre uno '''Schema Progettuale''' = '''Patterni'''.\\
Il ''Pattern'' è un motivo, una soluzione ad un problema comune. In genere i problemi che saltano fuori durante la programmazione sono bene o male sempre quelli, cambiano un po' qua e là.\\
Per creare un pattern, seguo queste norme:
* identificare bene gli oggetti
* raggrupparli in classi che dividano nel giusto modo tra proprietà della classe e proprietà dell'oggetto
* definire le interfacce
* stabilire le ''gerarchie'' tra classi e interfacce
* stabilire relazioni tra classi: questa classe comprende quella etc.

Il trucco è di rispettare le specifiche, ma di rimanere anche abbasanza generici da poter trattare anche altri problemi simili.\\
Quando si tenta di risolvere un problema, è raro riuscire al primo colpo: si procede a tentativi. Tutti questi tentativi producono esperienza, e il progettista esperto ha un bel fagotto di esperienze e di schemi di progetto, che si possono adattare a nuove situazioni.\\\

Le aziende di software quindi dipendono tanto dal bagaglio di conoscenze dei proprio programmatori esperti. Ma se questi se ne vanno, che fanno? Portano con sé tutto quello che sanno e non lasciano dietro niente?\\
I pattern servono proprio a questo: cercare di mettere su carta l'impalpabile essenza dell'esperienza, seguendo lo schema seguente:
* nome
* descrizione del problema e contesto
* soluzione
-> * classi e oggetti costitutivi
-> * loro relazioni
* conseguenze dell'applicazione di questo pattern
-> * risultati
-> * vantaggi e svantaggi

Sono un po' i mattoncini di base della programmazione Bottom - Up, solo che qui mi danno un prefabbricato intero con fondamenta e pareti già tirate su.\\\

!!!!Aspetti
'''Warning: qui entriamo nel filosofico'''.\\\

Scrivo un programma, che fa una certa cosa. Posso dividere quello che fa e raggrupparlo in questi ''aspetti'':
Changed lines 63-65 from:
Ok. Come faccio a ''creare'' un numero complesso a partire dalla sua parte immaginaria e dalla sua parte complessa? Occorre una funzione che prenda in argomento queste cose, e le restituisca come [@void * this]. Eccola:

complex.h
to:
Ok. Come faccio a ''creare'' un numero complesso a partire dalla sua parte immaginaria e dalla sua parte complessa? Occorre una funzione che prenda in argomento queste cose, e le restituisca come [@void * this@]. Eccola:

//complex.h
Changed lines 68-70 from:
complex.c
void * newComplex(double re, double im)
{
to:
//complex.c
void * newComplex(double re, double im) {
Changed lines 76-77 from:
Figlio di puttana di un Wiki!
to:
Changed lines 78-79 from:
Quello che abbiamo sviluppato qui è una specie di anticipo della programmazione strutturata. Se un giorno decido di cambiare la rappresentazione da geometrica (quella implementata qui) ad esponenziale, devo solo ricordarmi di modificare il costruttore e le funzioni [@double re()@] etc., perché tanto il programmatore usa sempre e solo il tipo di dati [@void *@], e quindi se ne frega di come implemento io alla fine il mio bel numero complesso.\\
to:
Quello che abbiamo sviluppato qui è una specie di anticipo della programmazione strutturata. Se un giorno decido di cambiare la rappresentazione da geometrica (quella implementata qui) ad esponenziale, devo solo ricordarmi di modificare il costruttore e le funzioni [@double re@] etc., perché tanto il programmatore usa sempre e solo il tipo di dati [@void *@], e quindi se ne frega di come implemento io alla fine il mio bel numero complesso.\\\
Changed line 35 from:
// complex.h
to:
Changed line 43 from:
//complex.c
to:
Changed line 65 from:
//complex.h
to:
complex.h
Changed lines 68-69 from:
//complex.c
void * newComplex(double re, double im) {
to:
complex.c
void * newComplex(double re, double im)
{
Changed line 75 from:
return z; //il cast a void * viene fatto automaticamente dal C
to:
return z;
Changed lines 77-79 from:
Questa funzione si chiama costruttore: costruisce il tipo di dato.\\\
to:
Figlio di puttana di un Wiki!

Questa funzione si chiama costruttore: costruisce il tipo di
dato.
Changed lines 29-30 from:
Se volete vi faccio anche un esempio di programmazione pseudo incapsulata in C... ma sì dai!\\\
to:
Se volete vi faccio anche l'esempio di programmazione pseudo incapsulata in C... ma sì dai!\\\
Changed lines 38-93 from:
double mod(void * this);
to:
double mod(void * this);

Queste funzioni mi restituiscono la parte immaginaria, quella reale ed il modulo del mio numero reale. La cosa interessante è che prendono come argomento un tipo anonimo che più anonimo non si può: un puntatore a void.\\\

Poi scrivo il file [@complex.c@](notate il [@.c@] e ci metto la definizione della [@struct complex@]:
//complex.c
struct complex {
double re;
doube im;
}

I file [@.c@] in genere vengono "inclusi" solo di proposito, in genere si includono solo gli header.\\
Invece, visibili al programmatore, metto le implementazioni delle mie operazioni [@double re@] e così via:

double re(void * this) {
struct complex * z = (struct complex *)this;
return z -> re;
}

Questa funzione prende il parametro [@void * this@], lo casta a [@struct complex *@], e restituisce la parte reale di esso.\\
Quindi, il programmatore è limitato a fare una cosa del genere:

void * z;
printf("%f\n", re(z));

Ok. Come faccio a ''creare'' un numero complesso a partire dalla sua parte immaginaria e dalla sua parte complessa? Occorre una funzione che prenda in argomento queste cose, e le restituisca come [@void * this]. Eccola:

//complex.h
void * newComplex(double re, double im);

//complex.c
void * newComplex(double re, double im) {
struct complex * z;
z = (struct complex *)malloc(sizeof(struct complex));
z -> re = re;
z -> im = im;
return z; //il cast a void * viene fatto automaticamente dal C
}

Questa funzione si chiama costruttore: costruisce il tipo di dato.\\\

Quello che abbiamo sviluppato qui è una specie di anticipo della programmazione strutturata. Se un giorno decido di cambiare la rappresentazione da geometrica (quella implementata qui) ad esponenziale, devo solo ricordarmi di modificare il costruttore e le funzioni [@double re()@] etc., perché tanto il programmatore usa sempre e solo il tipo di dati [@void *@], e quindi se ne frega di come implemento io alla fine il mio bel numero complesso.\\
La OOP mi fa fare tutto ciò in modo elegante.

!!!!Classi e Oggetti
La ''Classe'' è il tipo di dato astratto che descrive tutti i casi particolari. Una Classe ''Conto Corrente'' descrive sia il conto presso la Banca Popolare di Lodi, che presso la Banca del Seme. E' l'ultimo gradino di un processo di astrazione:

Realtà -> Modello -> Oggetto -> Classe

Parto dalla realtà, e ne creo un modello. Il mio modello (la mia banca, in questo esempio) vedo che è composto da entità monadiche, i miei conti correnti. Ho tanti conti, quello di Patrizia pieno delle bustarelle della Lobby del Fil di Ferro, e quello di Dario finanziato dai Terroristi Tettamanziani per la Jihad del Pinguino, ma sono tutti simili. Quindi, astraggo ancora, e arrivo al tipo di dato astratto: la Classe ''Conto Corrente''. Applausi, prego.\\
Da notare che non ci sono regole fisse per stabilire chi è Classe e chi è Oggetto: è la pratica che ci fa capire che cosa è più comodo per noi.\\\

L'Oggetto è una particolare incarnazione della Classe: come dicevo qui sopra, l'incarnazione di Dario del suo conto corrente è fatta in un modo, quella di Patty in in altro.\\
Si può quindi già trarre una distinzione tra ciò che pertiene ad una Classe, e ciò che pertiene ad un Oggetto.\\\

Torniamo all'esempio delle automobili: ho creato la Classe [[126]], che ha un motore di 650 cm'^3^' e una potenza di 23 cavalli. Voglio poi implementare il Garage di [[Dario]], che in un roseo futuro ne possiede 8. Ognuna di queste 126 appartiene alla Classe 126. Quindi, tutti i miei oggetti condivideranno la cilindrata e la potenza. Ecco quindi che la cilindrata e la potenza sono dati che appartengono alla Classe, mentre la targa di ogni singolo pezzo della collezione appartiene all'oggetto, cioè all'incarnazione (in gergo OOP, istanza).
Added lines 32-33:
Voglio un programma che manipoli dei numeri immaginari, e devo decidere se usare la notazione geometrica o quella trigonometrica (consultare il Cariboni per i dettagli).\\\
Changed lines 19-36 from:
!!!
to:
!!!!Incapsulamento
Incapsulare significa "''intuorlare''" qualche cosa, cioè farla finire in un immaginario tuorlo di un dato astratto, e progettarne il guscio.\\
Il programmatore OOP individua i ''concetti'' del suo programma, e li intuorla, incapsulandoli da qualche parte.\\\

Uno dei vantaggi dell'incapsulamento è che posso mantenere l'interfaccia, e modificarne il contenuto come voglio, senza che il resto del sistema ne soffra. Ciò permette di limitare le dipendenze tra i vari oggetti alle sole interfacce.\\
La dipendenza tra oggetti vuol dire questo: creo il tipo di dato astratto Motore, con l'interfaccia composta da Accendi, Accelera, Molla il Gas, Spegni, e poi creo il tipo di dato astratto Automobile che incorpora il Motore. Nel momento in cui decido di cambiare il codice che esegue l'operazione Accendi, per esempio, non devo stare a modificare tutto l'ambaradan dell'automobile, perché l'incapsulamento permette di fregarmene: una volta che ho deciso che l'interfaccia del Motore è composta da Accendi, Accelera, Molla il Gas e Spegni, io programmatore di Automobile non devo sapere altro. Il programmatore di Motore farà tutti i casini che vuole, ma finché l'interfaccia non cambia, non ho problemi.\\\

Domanda: ''ma non si può fare la stessa cosa con un linguaggio strutturato? Per esempio, creo delle [@struct@], e creo delle funzioni che le manipolino''.\\
Risposta: sì, certo. Il videogioco Doom è stato programmato così. Unico problema: siccome nei linguaggi strutturati non c'è la nozione di incapsulamento, può accadere che qualcuno, senza difficoltà, si metta a cambiare le funzioni manipolatrici, oppure decida di non usarle, e tutto il mio lavoro di progettazione va a balle. L'incapsulamento invece mi dice: ''l'interfaccia è questa: da qui non si scappa'', e non si può sbagliare. Obbligo chi usa il mio codice a 1) non poter modificare il funzionamento interno (vero in parte, poi vedremo perché); 2) a usare la stessa interfaccia sempre e comunque.\\\

Se volete vi faccio anche un esempio di programmazione pseudo incapsulata in C... ma sì dai!\\\

!!!!Esempio di incapsulamento balordo in C
Nel file [@complex.h@] metto delle definizioni così:
// complex.h
double re(void * this);
double im(void * this);
double mod(void * this);
Added lines 1-19:
(:title Capitolo 4: Programmazione Orientata agli Oggetti:)
[[Torna alla pagina di Tetty -> Tetty]]
----
La Programmazione Orientata agli Oggetti (OOP da qui in poi) rappresenta lo sviluppo delle intuizioni della progarmmazione strutturata.

!!!!Tipo di Dato Astratto
Il '''Tipo di Dato Astratto''' trascura la rappresentazione fisica del dato nella macchina: in generale ciò al programmatore non importa.\\\

Ha le seguenti caratteristiche:
* Interfaccia
-> * Nome
-> * Operazioni consentite
-> * Assiomi e Precondizioni

E' come un uovo: i dettagli sono il tuorlo, nascosti al mondo, mentre ciò che è visibile (l'Interfaccia) è il guscio.\\\

Un esempio di dato astratto che usiamo tutti i giorni è il {+numero naturale+}, del quale definiamo il nome, di cui sappiamo le operazioni consentite (chiedere alla Citrini), e di cui abbiamo nozione dei suoi Assiomi e delle sue Precondizioni (eg., n + 0 != n; n * 0 = 0 e così via).

!!!