Newsgroup: it.comp.java
Titolo: Visibilita' di default ed ereditarieta'

Vorrei un suggerimento su come comportarmi nella seguente situazione.
Una classe (chiamiamola Handler) deve eseguire alcune operazioni a
partire dallo stato di un oggetto. Per diminuire l'accoppiamento fra
questo oggetto e l'handler utilizzo una classe Memento che incapsula
lo stato dell'oggetto.
Essendo l'Handler definito nello stesso package del Memento ho
definito i campi di questo con visibilita' a livello di package.
Quando sono richieste le funzionalita' dell'handler e' l'oggetto
stesso che si occupa di costruire un Memento e quindi di passarlo
all'Handler.
A questo punto mi trovo nella necessita' di estendere le funzionalita'
dell'Handler.
Le funzionalita' che devo aggiungere non sono attinenti allo scopo del
package in cui e' dichiarato Handler e quindi non vorrei dichiarare
ExtendedHandler all'interno di esso.
L'ExtendedHandler utilizza un ExtendedMemento.
Purtroppo l'Extended Handler ha la necessita di accedere (leggere) i
campi del Memento originale.
L'unica soluzione che mi e' venuta in mente e' la seguente:
- dichiarare i campi del Memento come privati
- aggiungere dei metodi getter con visibilita' protected
- ridefinre i getter (richiamando semplicemente il super)
nell'ExtendedMemento allo scopo di renderli visibili
all'ExtendedHandler.
Come soluzione non mi piace molto, ma non mi e' venuto in mente di
meglio.
Qualcuno ha dei suggerimenti?
Andrea Polci

 Qualcuno ha dei suggerimenti?
Ma se usi una interfaccia invece di usare una classe (inutile IMHO) come 
Memento.
-- 
Marco "Duff" Palermo
http://www.marcoduff.com/

Devi  usare "protected"

...

Attraverso la classe memento vengono esposti alcuni dettagli
implementativi dell'oggetto e quindi non vorrei inserirli in una
interfaccia pubblica.
Penso che mi tocchi scendere maggiormente in dettaglio.
Si tratta di gestire la persistenza su DB di alcuni oggetti. Nel
memento vengono memorizzati i valori che vanno salvati nelle diverse
colonne di una tabella e altre informazioni come il nome della
tabella.
L'accesso al DB non viene fatto dall'oggetto stesso ne' dal memento ma
dall'Handler, il quale ricava tutte le informazioni per costrure
l'update o l'insert dal memento.
Poiche' una volta costruito il Memento deve essere utilizzato
solamente dall'handler, che e' definito nello stesso package, ho reso
visibili dal solo package tutti i metodi per l'accesso al contenuto
del memento, mentre sono pubblici quelli per la sua inizializzazione.
A questo punto devo estendere l'Handler per aggiungere alcune
funzionalita' che non sono strettamente di gestione della persistenza
(ma che penso sia corretto implementare nell'handler, non sto a dire
di piu' perche' dovrei scendere molto nel dettaglio dell'applicazione
che sto realizzando). Visto che non si sta piu' gestendo la sola
persistenza vorrei inserire le classi che sto creando (un handler e un
memento estesi) in un nuovo package.
Il problema e' che per svolgere i suoi compiti l'ExtendedHandler ha
bisogno di accedere alle informazioni contenute nel Memento (ad
esempio la tabella in cui memorizzare i dati), ma questo non e'
possibile poiche' esse sono visibili solo dal package in cui e'
definito.
Esiste un modo elegante per risolvere questo genere di problemi?
Andrea Polci

 Esiste un modo elegante per risolvere questo genere di problemi?
Guarda, io continuo a dire che l'interfaccia è sicuramente la cosa più 
elegante che puoi usare.
Forse ho capito male io quello che vuoi fare, ma a me sembra proprio la 
problematica di base per la quale sono state inventate le interfaccie!


 problematica di base per la quale sono state inventate le interfaccie!
Il problema dell'interfaccia e' che mi imporrebbe di dare dei metodi
pubblici per accedere a dei dettagli implementativi violando
l'incapsulamento.
A chi usa il mio oggetto non interessa (e non deve interessare) su
quali campi della tabella andranno scritti i vari valori, ne' su quale
tabella verra' memorizzato l'oggetto.
Pero' sono informazioni che interessano a chi gestisce la persistenza.
Il memento mi permette di mettere tutte queste informazioni in una
classe che e' acessibile solo dal package che si occupa di gestire la
persistenza.
Il problema sorge quando devo estendere una delle classi di questo
package come nel mio caso. Nelle classi derivate, se non sono nello
stesso package, non ho piu' la possibilita' di accedere alle
informazioni del memento.
Andrea Polci

 l'update o l'insert dal memento.
Proprio in questi giorni sto pensando un bel po' a questo tipo di cose
- in relazione ad una recente discussione sugli accessors con un
amico.
Non sono sicuro ci sia una soluzione object-oriented "buona" alla
questione. Il fatto e' che la persistenza di un oggetto e' un aspetto
che richiede, da un lato, dettagli sullo stato dell'oggetto (per
definizione); ma non e' - di per se' - un servizio offerto
dall'oggetto (nel qual caso sarebbe da implementare come suo metodo).
Un approccio e' cambiare prospettiva, e gestire la cosa esattamente
come un aspetto (se usi un linguaggio AO, direttamente; altrimenti,
uscendo dal contesto OO, e violando esplicitamente, ma in modo
controllato ed *automatico*, l'information hiding, saltando le
protezioni dell'oggetto e accedendo allo stato dell'oggetto
direttamente, alla JDO. Enfatizzo l'"automatico" perche' senno' la
cosa risulta ingestibile in tempi molto brevi).
Un altro e' quello tuo - tenare di incapsulare la cosa in un contesto
OO. Una possibilita' e' estendere sia il memento che l'entita' che lo
produce. La tua estensione nell'altro package ritorna un memento
esteso.
Il memento base avra' i suoi metodi protected, e il memento esteso
pure. Ora, come fa l'handler ad accedervi? Una possibilita' e'
estendere di nuovo il memento con un metodo che produce l'handler.
class p.C
class p.HandlerC
class p.MementoC // incapsula lo stato di C
class p.HMementoC // agisce da factory per p.HandlerC
class p1.ExtHandlerC extends p.HandlerC
class p1.ExtMementoC extends p.MementoC
class p1.HExteMementoC extends p.HMementoC // Produce p1.ExtMementoC
invece di p.MementoC
Avrai cosi' un memento specifico per produrre un certo tipo di
handler, e un altro per produrre un secondo tipo - ma l'accoppiamento
e' localizzato nell'unico metodo dei due memento "foglia".


Ho riletto tutti i tuo post, e forse ho capito meglio il problema...
Per me questo sta nella classe Handler.
Per come hai posto il problema, mi sembra che ti convenga farla 
diventare astratta, creando in questa tutte le interazioni con la classe 
Memento.
Quindi, alla fine, ti trovi la classe Memento con i dati per la 
costruzione delle query, e la classe Handler con le interazioni con 
Memento e gli scheletri per le implementazioni vere e proprie.
Spero che sia cosi, altrimenti posta parti di codice, che non ci sto 
capendo nulla!!! :D
