Newsgroup: it.comp.java
Titolo: command pattern

Non ho ben capito l'utilità di questo pattern che ha un metodo execute senza 
parametri che esegue l'azione.
Se sto sviluppando un'applicazione con le servlet o le action di struts, 
secondo voi è utile inserire questo ulteriore strato tra i DAO e le Action 
(o servlet)? Non ne esce un doppione?! 


Ciao Alberto,
Il pattern Command risulta molto utile quando vuoi che un'unità di 
lavoro venga eseguita in modo indipendente dal chiamante.
Personalmente ho modellato il sistema in questo modo:
Classi Action  chiamano un BusinessDelegate (una facade)
Il BD espone metodi per l'usecase corrente. Esegue controlli sui 
parametri. Diciamo che assume il ruolo di direttore d'orchestra dello 
usecase.
il BD chiama uno o più ApplicationService che consistono in commands che 
prendono parametri dai costruttori.
Gli AS diventano così unità di lavoro riutilizzabile (eseguono codice 
business possono o meno chiamare DAO).
Ogni AS è costituito da 0 o più AS.
Action 1---1 BD ---n AS ----n DAO
A mio parere la action non devono ne fare logica di business ne tanto 
meno chiamare i DAO. Le action sono da vedere come client, richiedono 
dei servizi al sistema.
Se cambi la presentazione tutte le action sono da rifare. (Ad esempio 
connetti tramite gui via rmi all'applicazione per gestire il backend).
Invece modellato come sopra crei una separazione dalla vista e dal 
controller del sistema.
Spero di esserti stato di aiuto.
Ciao kimbuba.

Altra domanda sempre sul genere.
Sto usando hibernate con il pattern session-per-request (spero si chiami 
così), ovvero ho un filtro su ogni richiesta che chiude la sessione corrente 
di hibernate, ed esegue il commit delle possibili transazioni.
I dao hanno un costruttore vuoto  che inizia la transazione (che farà il 
commit nel filter).
Non mi é chiaro invece dove mettere i rollback. Sui command che farò vero?


Ciao Alberto.
Io le transazioni le apro a livello DAO quando sono in scrittura.
Il filtro servlet mi chiude solo la sessione (è safe anche se non è 
stata aperta)
La commit lo faccio a livello di BD, questo infatti da bravo direttore 
d'orchestra decide quali AS eseguire e committa. Se viene lanciata 
un'eccezione sotto (che venga da AS oppure DAO) il BD rolla indietro.
A questo punto ad esempio puoi creare un metodo privato da chiamare dal BD:
private Object executeOnTransaction(ApplicationService as){
	Object result = null
	try{
		result = as.execute();
		HibernateUtil.commit()
	}catch(Exception e){
		HibernateUtil.rollBack();
		log.error(e);		
	}
	return result;
}
ed uno analogo ma senza transazione per AS semplici.
(il codice è sommario in realtà io ho usato l'AOP per gestire i rollback 
ed i commit e le eccezioni varie ma non è obbligatorio usarlo)
Metterli nei command invece cambia il significato. Gli AS sono unità di 
lavoro indipendenti ma flessibili quindi se il BD carica due AS entrambe 
si auto-committeranno cambiando il significato dato dalla loro composizione.
le caso di prima io farei:
class IlMioUseCaseBD{
	public Object doSomething(Object param){
		ApplicationService as = new CalcolaQualcosa(param);
		Object result = as.execute(); //non in transazione in 								questo caso.
		return executeOnTransaction(new SalvaQualcosa(result));
	}
}
La action:
execute:
String param = request.getParam(.....);
IlMioUseCaseBD bd = new IlMioUseCaseBD();
Object result = bd.doSomething(param);
reponse.setAttribute(.....);
In questo modo vedi che le unità di business sono solo nei AS. la action
non conosce niente si occupa solo dei parametri.
Il BD invece per quel metodo sa che deve prendere due AS e combinarli.
Nota che però se quel metodo risulta utile anche ad altri considera di
creare un'altro AS con quelle funzionalità così che possa essere risusato.
Il BD non deve essere riusato invece è specifico a quel particolare Usecase.
Fammi sapre cosa ne pensi.
Ciao,
Kimbuba.