Newsgroup: it.comp.java
Titolo: Ereditarietà, interfaccie e quant'altro ...

Cercherò di essere sintetico:
sto realizzando una piccola API per un particolare protocollo di rete. Una
delle astrazioni indispensabili è quella necessaria alla creazione di un
server che accetti connessioni e le gestica secondo il protocollo.
Cio che mi piacerebbe fare è dare la possibilità a chi utilizzerà l'API di
poter scegliere se istanziare un server "semplice" o dotarlo di funzionalità
quali sicurezza della connessione (SSL), autenticazione (tramite
certificati) del peer che richiede la connessione, ecc.
La mia idea è quella di rendere queste funzionalità indipendenti, in modo da
poter essere combinate a piacere. Ad esempio si può volere utilizzare un
server con connessione sicura ma senza autenticazione se si lavora
all'interno di una rete privata, oppure entrambe se l'accesso è consentito
anche dall'esterno.
Veniamo al punto:
allo stato attuale ho realizzato un classe Server "semplice" e dovrei
estenderla con le funzionalità di cui sopra. Ma come?
Utilizzando l'ereditarietà perderei la possibilità di combinare a piacimento
le varie funzionalità, a meno di non derivare un numero di classi uguale a
tutti le combinazioni possibili, soluzione realizzabile ma certo non
"elegante".
La mia idea è quella di imitare il meccanismo dell'I/O di Java, permettendo
all'utilizzatore dell'API di impilare le varie funzionalità richieste (ie
ServerConAutenticazione(ServerSicuro(ServerSemplice))) ).
Come devo implementare i vari componenti perché ciò sia realizzabile?
E' sufficiente creare un'interfaccia Server implementata da tutte le
varianti?
thanks

varianti?
Quello che cerchi di realizzare e' il pattern Decorator, per
riuscirci, devi avere : una classe astratta di partenza (Server],
selezioni quelle operazioni che dovranno essere successivamente
"decorate", ovviamente dovranno essere specificate nel Server,
altrimenti il tutto non funziona. Partendo da questa classe base
astratta, puoi creare delle classi concrete, ad esempio
ServerSemplice, che saranno le classi che potrai scegliere come
partenza per la costruzione di una sorta di catena di ereditarieta' a
run-time (e' quello che volevi no?). Infine ereditando sempre dalla
classe Server, crei una classe astratta, che sara' padre di tutte le
classi concrete "Decoratrici", questa classe oltre che a estendere
Server, ne compone uno! Ora, definendo i "Decoratori" concreti, che
vengono inizializzati con un oggetto di classe Server (attenzione, tu
lo vedi semplicemente come un Server, ma potrebbe essere gia'
arbitrariamente decorato), quando devi definire i servizi di questo
server decorato, avrai gia' a disposizione le funzionalita'
dell'oggetto server che componi, a questo punto, non dovrai fare altro
che aggiungere le features che il tuo decoratore implementa, prima o
dopo aver chiamato il metodo del server che componi (un po' come fare
super.metodo();)
Cioe', ammettiamo che nel Server hai definito un servizio
operazione(), hai delle implementazioni concrete di Server, che
definiscono questo servizio, e devi creare un decoratore che estende
l'abstract decorator -> nel costruttore ti e' stato passato un oggetto
di classe Server (server), ora dovrai fare l'overriding (occhio alla
signature, purtroppo non puoi modificarla!) del metodo operazione,
allora farai una cosa del tipo
public TypeReturn operazione()
{    // Fai le operazioni che vuoi prima
     return = server.operazione();
     // Fal le operazioni che vuoi dopo
     return myReturn // Ritorna quello che vuoi
}
In questo modo, durante la costruzione del tuo  oggetto, dovrai
istanziare un server base (ex ServerSemplice), e poi passarlo a tutti
i decoratori che vuoi :
server =  new ServerSicuro( new ServerAutenticato( new
ServerSemplice(param))));
Quello che risulta lo puoi trattare a sua volta come Server,
limitandoti ai metodi in esso definiti, oppure lo puoi trattare come
server specifico! Il decorator e' una delle architetture piu' eleganti
che abbia mai visto.
Spero di essere stato chiaro, scusa ma non e' molto facile da spiegare
a parole, se vuoi maggiori info scrivimi in maniera privata, che
magari ti mando qualche diagramma UML, o qualche cosa di scritto da
me. Comunque per problemi di questo tipo, c'e' un'area di prossima
apertura (spero oggi) sul sito di RedAngel (
www.redangel.it
) dove
discuteremo in maniera interativa sulla realizzazione dal punto di
vista architetturale dei progetti (tu presenti il tuo progetto, la
comunita discute su come sarebbe possibile risolverlo nella maniera
ottimale, dal punto di vista architetturale). Se ti va vieni a
trovarci per questo o per problemi futuri.
Ciao
				Gabriele "SunGray" Lana

 Gabriele "SunGray" Lana

(sicuro, semplice, ...) da una classe astratta
Hai una classe astratta dove definisci tutti i metodi
che dovranno essere realizzati nelle varie maniere
"decorate"; immaginiamo che il metodo si chiami
operazione(), questo lo definisci nella classe astratta,
che tu chiami AbstractServer, da questo ereditano due
"tipi" di classi, i server concreti ex ServerSemplice
(AbstractServer e' solo l'astrazione, non viene istanziato),
e l'astrazione decoratore (AbstractDecorator), che come 
ti dicevo possiede una istanza di un generico AbstractServer.
Da quest'ultimo, derivi tutti i decoratori che vuoi, questi 
decoratori, implementano il metodo decoratore sfruttando
le capacita' dell'AbstractServer che possiedono
cioe' nel decoratore hai il metodo operazione
public TypeReturn operazione()
{	// Qui va il codice specifico del decoratore, se vuoi
	server.operazione() // richiami le potenzialita' del
                                        // server che conosci
            // Qui va il codice specifico del decoratore, se vuoi
	return // Il risultato congiunto dell'elaborazione fatta
            // dal server (che puo' essere decorato o no), e
            // del decoratore
}
Spero che tu abbia capito
			Gabriele "SunGray" Lana