Newsgroup: it.comp.java
Titolo: Interfacce

Scusate, qualcuno potrebbe spiegarmi l'effetto pratico delle interfacce? 
Ho studiato l'utilità nel caso, ad esempio, dell'intefaccia Comparable 
della libreiria standard, che permette di risparmiare di creare copie di 
altre classi, facendo in modo di poterle riutilizzare in vari casi 
diverse. Quel caso l'ho capito. Però rimando un pò confuso rispetto a 
questo che ho studiato sulle solite dispense del mio prof. Scrive una 
classe che definisce il comportamente di un ADT come uno stack, creando 
prima una interfaccia che chiama Container, che contiene le firme di due 
metodi applicabili a dei contenitori (makeEmpty() e isEmpty(), una per 
svuotare l'ADT e l'altro per determinare se è vuoto). Poi definisce una 
interfaccia, che estende Container, che contiene i metodi propri dello 
stack, quindi push(), pop() e top().
Il concetto di questi ADT mi è piuttosto chiaro, ma non capisco il 
perchè di queste interfacce. Qual'è l'effetto pratico in questo caso? 
Non esiste. Anche non avendolo non avrei comunque utilizzato tutto allo 
stesso modo?
Grazie mille e grazie per la vostra pazienza.
Luca

 stesso modo?
Esiste, esiste, hai invertito la dipendenza fra il client ed il server.
Vai a vedere l'OCP (Open Closed Principle) ed il DIP (Dependency 
Inversion Principle) sul sito di Robert Martin (ad esempio ci sono dei 
paper su 
www.objectmentor.com
) e tutto ti sara' chiaro
uL

 Esiste, esiste, hai invertito la dipendenza fra il client ed il server.
Client e server? Cosa centrano in questo caso?
Grazie.
Luca

 Scusate, qualcuno potrebbe spiegarmi l'effetto pratico delle interfacce? 
http://xoomer.virgilio.it/csadun/javafaq.html#d1-16
-- 
You dont know what to do when you dont know what you're doing.
http://space.tin.it/computer/csadun

 
http://xoomer.virgilio.it/csadun/javafaq.html#d1-16
Grazie per il link. Era esattamente quella la mia domanda. Però giuro 
che non ho capito. In genere non sono particolarmente duro, ma queste 
interfacce sono sicuramente il concetto più difficile di java fino a 
questo punto.
L'esempio fatto dal mio libro è ok, ci sono arrivato, il problema sta 
più che altro nel caso che ho cercato di spiegare nel primo messaggio. 
Il fatto è che anche non scrivendo l'interfaccia, ed evitando ovviamente 
di scrivere implements nomeinfterfaccia, la classe (cioè l'ADT) funziona 
perfettamente. Ora, visto questo, non capisco l'utilità in questo caso.
Grazie cmq del link e della pazienza.
Luca

 l'utilit… in questo caso. 
Occhio che "funziona perfettamente" non e' sempre un 
criterio rilevante
:-) Per esempio, un programma funziona perfettamente se e' 
scritto in
assembly, senza classi, oggetti o marchingegni vari. Per 
dire, se tutto
quel che devi fare e' scrivere "hello world" sullo schermo, 
un
caricamento di registri seguito da una system call basta e 
avanza.
Perche' allora esistono classi, oggetti e marchingegni vari?
Perche' rendono piu' semplice costrtuire e controllare 
programmi
complessi. 
Analogamente, per renderti pienamente conto dell'utilita' 
delle
interfacce, devi affrontare sistemi complessi.
Un interfaccia disaccoppia la definizione (*) di un ruolo 
dalla sua
implementazione. Concretamente, definisce un *tipo* che si 
puo' usare 
ovunque useresti l'implementazione diretta (tranne 
ovviamente che per la
creazione): passaggio di parametri, invocazione di metodi, 
cast,
assegnamento, eccetera. 
(*) "definizione" entro certi limiti - un'interfaccia e' 
decisamente
meno potente di un ADT speficato algebricamente, per esempio 
I benefici sono molti ed estremamente rilevanti. Eccone 
alcuni:
 - sei guidato a definire il sistema in termini di ruoli (il 
perche'
 questo e' buona cosa lo lascio ad un'altra volta :-) 
astratti invece 
che di implementazioni;
 - puoi usare un'implementazione "scarsa" iniziale e 
modificarla
successivamente senza "rompere" il sistema (sia per 
compilazione che
per esecuzione)
 - separi piu' chiaramente l'interfaccia pubblica rispetto
 all'implementazione privata - puoi usare nomi evocativi e
 chiarificatori :-) - puoi cambiare l'implementazione sotto 
il naso del
 sistema senza che si rompa - e cambiarla una volta sola 
senza dover cercare nel codice decine di riferimenti alla 
tua classe di implementazione.
 - puoi definire ereditarieta' di ruoli, indipendente 
rispetto ad
 ereditarieta' di implementazioni. Come sempre, 
l'ereditarieta' va usata
 con parsimonia, ma talvolta e' utile. 
 eccetera.
Prendi il tuo stack. Se hai un'interfaccia Stack, puoi 
iniziare con una
classe SempliceStack che mantiene i valori in memoria - da 
qualche parte
avrai un stack = new SempliceStack(), ma tutto il resto del 
codice
usera' Stack; dopo un po', la vuoi cambiare con 
un'implementazione
GrandeStack che mantiene i valori su un file (e quindi e' 
piu' lenta, ma
gestisce stack molto piu' grandi): tutto quello che devi 
fare e'
cambiare la new - il resto del codice non si tocca. 
E' giusto un esempio, ma dovrebbe portarti sulla strada 
giusta. :)


 Grazie mille e grazie per la vostra pazienza.
Prego.
- Dario

 Grazie.
L'oggetto che chiede qualcosa e' il client, l'altro e' il server.
Hai letto l'articolo sull'inversione di dipendenza (DIP)?
uL