Newsgroup: it.comp.java
Titolo: Domanda filosofica (lungo)

Innanzitutto vi avverto che il post e' un po' lungo (me ne scuso) e la
domanda riguarda in qualche modo la filosofia di programmazione a
oggetti (senza esagerare pero'!).
Ringrazio in anticipo chi vorra' prendere parte alla discussione.
Vorrei porvi una domanda su quale sia secondo voi il modo migliore di
integrare in Java l'interfaccia utente con le strutture dati in
un'applicazione in cui vi siano classi che rappresentano i documenti o
comunque particolari oggetti o strutture dati e finestre con le quali
devono interagire.
Vi faccio un esempio, ma la cosa e' del tutto generale. Supponiamo di
avere una struttura di classi che rappresenta informazioni, con i metodi
che agiscono su di loro.
Per esempio, sto scrivendo un programmino per disegnare grafici di
funzioni, e ho una struttura di classi che rappresentano funzioni, in
due o tre variabili, in coordinate cartesiane, polari eccetera, con i
metodi per calcolarle, integrarle eccetera, tutte derivate da una classe
base astratta e via via specializzate.
Ad ogni oggetto deve essere associata una finestra, nella quale la
funzione deve essere disegnata, e che deve preoccuparsi di reagire agli
eventi.
Se fossi in C++, partirei sparato con l'ereditarieta' multipla, ma in
Java non si puo' fare, percio' vedo le seguenti soluzioni:
1) Vi sono le classi che rappresentano i documenti dell'applicazione,
con la loro gerarchia. Vi sono poi le classi che servono a
visualizzarle, derivate da qualche finestra di Swing.
Ogni finestra mantiene una reference all'oggetto legato ad essa, in modo
da poter invocare metodi. Eventualmente, l'oggetto puo' avere necessita'
di mantenere anch'esso una reference alla finestra che gli "appartiene".
Vantaggio: tengo separate il + possibile le strutture dati
dall'interfaccia utente.
Svantaggio: devo tenere puntatori che possono non essere aggiornati
bene. Si possono creare relazioni di utilizzo anche complicate. Se ogni
documento va mantenuto in una lista dei documenti aperti, devo
preoccuparmi di tenerle sincronizzate e far si' per es. che alla
chiusura del documento sia rimossa dalla lista dei documenti anche la
classe corrispondente.
2) Le strutture dati vengono fuse con l'interfaccia utente e il loro
codice inglobato. Ad esempio, se ho una classe che rappresenta un
documento di testo faccio si' che derivi direttamente da JInternalFrame
e inserisco in questa classe anche le strutture necessarie alla
memorizzazione e elaborazione dei dati.
Oppure, se per es. ho qualcosa da memorizzare in un albero e anche da
visualizzare con un JTree, utilizzo direttamente il JTree, e i nodi
dell'albero mi derivano direttamente da uno dei nodi del JTree (come
DefaultMutableTreeNode), anziche' tenere due strutture separate come un
albero puro per i dati e un JTree per visualizzarlo.
Vantaggi: ho una stretta corrispondenza fra le strutture dati e gli
elementi dell'interfaccia utente che li visualizzano, riduco il numero
delle classi e delle relazioni di utilizzo, quando distruggo un elemento
dell'interfaccia utente distruggo anche la struttura dati
corrispondente.
Svantaggi: non posso creare gerarchie sulle strutture dati, perche' le
classi devono ereditare necessariamente da un componente
dell'interfaccia utente. Devo duplicare il codice. Le classi sono piu'
incasinate, perche' mischiano le istruzioni per la grafica con quelle
per la gestione dei dati. Il progetto e' meno estendibile.
Voi che approccio usate o usereste?
Personalmente, ho sempre usato il primo approccio, ma questo mi ha
creato non pochi problemi. Provate a fare un albero e un JTree che ne
visualizzi e gestisca i nodi quando queste sono due strutture separate!
Io e un mio amico l'abbiamo fatto (x la cronaca i nodi dell'albero
rappresentavano i livelli di un Data Flow Diagram, e attraverso il JTree
era possibile visualizzare la gerarchia e cancellare o modificare
livelli) e ci siamo ammazzati per tenere il tutto sincronizzato.
D'altra parte, credo che il secondo approccio limiti molto
l'orientamento agli oggetti del programma, dato che si deve ereditare
sempre da qualche componente di Swing (o AWT).
Che ne pensate?
-- 
Tommaso Paba
Togli ".no-spam." per rispondere (se c'e')
http://spazioweb.inwind.it/pabasoftware

 di mantenere anch'esso una reference alla finestra che gli "appartiene".
Questo cercherei di evitarlo come la peste (all'inizio credevo che fosse
impossibile, poi ho scoperto che con una progettazione adeguata non lo è),
perché è proprio questa la causa dell'ingrovigliamento di relazioni di cui
ti lamenti.
Cerca di implementare, nelle classi che manipolano le strutture dati, dei
metodi che forniscano alle classi grafiche le informazioni sufficienti
affinché esse le possano disegnare. In questo modo dovresti riuscire a fare
in modo che le classi con le strutture ignorino l'esistenza delle istanze
grafiche, ottenendo così una chiarezza e leggibilità delle relazioni davvero
notevole.
Poi, si sa, tra il dire e il fare c'è di mezzo il mare...
Fammi sapere come procede il tuo lavoro! Io ho imparato da abbastanza poco
la programmazione OO, e sono molto desideroso di approfondire le mie
conoscenze...
Grazie mille per avermi dato la possibilità di riflettere un po' su un tema
così interessante.
Ciao!
Davide

devono interagire.
Un approccio valido e' il cosiddetto pattern Model View Controller
(nonostante non tutti siano d'accordo, vedi una serie di articoli su
JavaWorld che propone un altro approccio per realizzare GUI per
applicazioni ad oggetti).
Molto sinteticamente, il Model sono i dati, la View e' la gui, il
controller e' il "collante" tra model e view attraverso il meccanismo
del callback. Il vantaggio principale e' che programmando
esclusivamente rispettando le interfacce del Model e della View si
ottiene una forte separazione tra dati e gui, tanto che e' possibile
per esempio cambiare quest'ultima (o anche passare ad una interfaccia
non grafica) senza toccare il resto del codice. Inoltre, la struttura
del programma diventa piu' chiara essendo ben definiti i ruoli delle
varie parti.
Qualche giorno fa avevo postato un link a un tutorial molto semplice
ed efficace (ora non ce l'ho sotto mano, se interessa lo recupero..)
Da notare che anche Swing si basa in largamente sul MVC (vedi JTable e
TableModel ecc. ecc).
Ciao,
 P.
+++ Boing Boom Tschak

[...]
Ah, e poi dicono che usare Java non e' educativo! :)
1) e' la strada da seguire. E' il modo *migliore* nella maggioranza delle 
situazioni, a prescindere dal fatto che tu stia usando Java, C++ o pincopallo. 
Per una discussione ragionevolmente apporofondita cfr. il solito [Gamma 
et.al
], 
"Design Patterns" - dove MVC e' discusso nella prefazione. 
Non capisco come mai tu abbia problemi con le classi di Swing, che sono pensate 
esattamente in quel modo.
-- 
God is Real, unless declared Integer.
ObjectZone - 
http://space.tin.it/computer/csadun

 posto i miei stessi dubbi e li abbia risolti...
Eccolo (ovviamente ce ne sono tanti, ma questo e' particolarmente chiaro
e sintetico):
http://www.cs.rice.edu/~cork/newBook/node90.html