|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
[JAVA] Ora il DAO è considerato anti-pattern?
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: May 2009
Messaggi: 129
|
Diciamo che ci sono correnti di pensiero diverse a riguardo e che,leggendo l'articolo che hai postato,mi trovo completamente in disaccordo con l'autore:
Sicuramente un modulo DAO,con la nascita degli applicativi ORM,perde un pochino del suo significato rispetto ai tempi in cui si utilizzava sql puro nei moduli software. Il perchè sta nel fatto che un ORM (come ad esempio Hibernate,TopLink,JPA etc) astrae dalle istruzioni di basso livello relative alle operazioni che si effettuano su db. Se prima si utilizzava un dao inserire un record in una tabella attraverso l'operazione "INSERT into ...."(che può dipendere dallo specifico database) , lo stesso dao ora utilizzerbbe l'astrazione fornita dall'orm utilizzato,qualcosa del tipo: ORMHandler.insert(domain),che già astrare dallo specifico db sottostante. Il DAO nasceva proprio con l'idea di isolare i moduli software che avevano la responsabilità di accedere in lettura/scrittura al DB,in modo da rendere piu flessibile e manutenibili le applicazioni,seprando la logica di business dalla logica di accesso ai dati (che può essere fortemente accoppiata con la specifico db). Un software ORM deresponsabilizza lo sviluppatore da questa astrazione. Tuttavia a, mio modo di vedere il pattern DAO rimane comunque un importante pattern di cui tenere conto in fase di design del software (soprattutto se il software sarà di grandi dimensioni e verrà toccato da piu sviluppatori),in quanto,ogni modulo software deve avere una sua responsabilità ben precisa. 1. Utilizzando i Dao si ha una maggiore MODULARITA' dell'applicativo: 1a) Modularità implica Riusabilità: Se nella mia applicazione scrivo un DAO che recupera l'utente dato l'username,potrò riutilizzare lo stesso modulo ovunque mi possa servire all'interno dell'applicazione,senza riscrivere codice. 2a) Modularità implica Manutenibilità: Se nella mia applicazione dovrò cambiare il comportamento del modulo DAO che si occupare di recupere l'utente tramite l'username,a parità di interfaccia,dovrò cambiare esclusivamente il modulo DAO,e non tutte le parti dell'applicativo che lo utilizzano. Immagina di non avere utilizzato i dao e che devi andare a trovare e cambiare in tutta l'applicazione quelle porzioni di codice di cui è cambiato il significato....un inferno.... 3a) Manutenibiità e Riusabilità implicano Efficienza. A fronte di un tempo leggermente maggiore in fase di sviluppo dovuto alla creazione dell'infrastruttura dei moduli DAO,ci si guadagna largamente quando sarà il tempo di manutenere o ampliare. E ti assicuro che è prassi comune! Ciao Ultima modifica di javacomelava : 07-02-2013 alle 16:24. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Effettivamente i conti tornano, c'è un po' di più di overload dovuto agli strati di SW, ma rimane tutto + gestibile.
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Quote:
Delle interfaccie per le caratteristiche dell'oggetto come
, delle implementazioni alle interfaccie
, DAO astratto in funzione dei Generics Codice:
public abstract class AbstractDao<T> {
protected abstract String actualClass();
...
// routine code
}
Codice:
public class PersonDao extends AbstractDao<Person> {
@Override
protected String actualClass() {
return PersonImpl.class.getName();
}
}
bisognava per forza usare le interfaccie?
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. Ultima modifica di Matrixbob : 20-02-2013 alle 17:10. |
|
|
|
|
|
|
#5 |
|
Member
Iscritto dal: May 2009
Messaggi: 129
|
Assolutamente si,le operazioni comuni per l'accesso ai dati vengono generalizzate in una classe astratta,che tutti i dao specifici andaranno ad estendere,proprio come nell'esempio che hai trovato:
Codice:
public abstract class AbstractDao<T>{
// Qui tutte le operazioni generiche (inser,update,findByPk) //etc.etc.
}
public interface IUserDao
{
// Le operazioni specifiche su un "User" che una specifica //implementazione dovrà rispettare
// Es.: Una query che restituisca tutti gli utenti di una città
}
public class UserDao extends AbstractDao implements IUserDao
{
//Implementazione delle operazioni specifiche su un "User":
// Es.: Una query che restituisca tutti gli utenti di una città
}
L'idea è quella che OGNI STRATO APPLICATIVO DEVE COMUNICARE CON LO STRATO APPLICATIVO SOTTOSTANTE ESCLUSIVAMENTE TRAMITE INTERFACCE (Pattern LAYER). Perchè questo? Perchè cosi facendo uno strato applicativo CONOSCE solo la definizione dei servizi esposti dallo strato sottostante disinteressandosi delle reali implementazioni (e quindi disaccoppiandosi da queste). |
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Quote:
infatti la mia domanda era specifica dell'esempio trovato (esmpio DAO). Quindi l'esempio avrebbe funzionato anche con il codice fortemente dipendente. Ovvio che le interaccie servano a disaccoppiare, infatti mi pare che la'mbiente business JEE si basi su interfaccie proprio per questo motivo. Correct?
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. |
|
|
|
|
|
|
#7 |
|
Member
Iscritto dal: May 2009
Messaggi: 129
|
Da un punto di vista meramente tecnico,potresi scrivere tutto il codice in una classe,a prescindere.
Ci sono in gioco due concetti diversi: 1. Come progettare un sistema (Design patterns in generale e nel nostro caso il pattern DAO). 2. Che tecncologie utilizzare per implementare il sistema progettato. (J2EE,quindi EJB etc etc) Nulla vieta,da un punto di vista esclusivamente tecnico,che si possa utilizzare la piattaforma J2EE senza un mimimo di progetazione. Inutile dire che nemmeno un pazzo si sognerbbe di sviluppare un sistema destinato all'"enterprise" (e che quindi deve garantire diversi standard di affidabilità performance etc come può essere una bamca) senza basarsi su regole di progettazione basilari(vedi design patterns). |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Forse è il DTO ad essere un AntiPattern adesso?
Io in verità non ho mai incontrato in 15 mesi di programmazione Java un DTO e non so bene cosa siano, ma dalla definizione Wikipedia sembrano degli strumenti per valorizzare gli oggetti della mia Applicazione. Sapreste dirmi di + al riguardo?
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. |
|
|
|
|
|
#9 | |||
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Provo a rispondermi da solo riportando uno snip da un thread su StackOverFlow che secondo me fila come discorso.
Quote:
Quote:
Quote:
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. Ultima modifica di Matrixbob : 06-04-2013 alle 16:01. |
|||
|
|
|
|
|
#10 |
|
Member
Iscritto dal: May 2009
Messaggi: 129
|
Un DTO è una classe java semplicissima,utilizzata per trasportare i dati attraverso i layer applicativi dell'applicazione.
Segue la struttura STANDARD JavaBean,cioe: 1. Costruttore di Default 2. Getters & Setters per ogni proprietà 3. Possibilità di implementare Serializable Codice:
public class UserDTO
{
private String nome;
public String getNome()
{
return this.nome;
}
public void setNome(String nome)
{
this.nome = nome;
}
}
Prima degli ejb 3.0 erano un must in quanto gli ejb di tipo Entity (ovvero gli ejb che mappavano il dominio applicativo),dovevano implementare tutta una serie di interfaccie,contenenendo internamente tutta una serie di logiche infrastrutturali e non,che prescindevano dalla natura di contenitore di dati della classe stessa. Quindi non potevano essere usati ANCHE come classi per trasportarsi i dati tra un livello e l'altro dell'applicazione. Da qui la nascita di questi oggetti semplicissimi,detti DTO,con la funzione specifica di fare da semplici wrapper di dati. Con il rilascio della specifica EJB 3.0,agli ejb di tipo entity (e in generale a tutti i tipi di ejb) sono stati nettamente semplificati. Ora un ejb di tipo entity non è niente altro che un JavaBean (semplice classe con proprietà,getters e setters) con delle annotazioni particolari,che rendono la classe GESTIBILE dal motore di persistenza scelto (di solito jpa,ma anche hibernate etc). Per specifica,un entity ejb,ha un particolare ciclo di vita (http://sqltech.cl/doc/oas10gR31/web....ndejbs003.htm). Quando una entity si trova in stato DETACHED (cioè,non è piu gestito dal mtore di persistenza) la specifica dice che questo può essere considerato alla stregua di una normalissima classe JavaBean. Teoricamente quindi potrebbero essere utilizzate le Entity per trasportare i dati tra i vari livelli applicativi. Questo è il motivo per cui qualcuno parla ora dei DTO come antipattern. Per me questa strategia è assolutamente sbagliata,per almeno due motivi principali,che provo a spiegarti: 1. Utilizzare le entity come oggetto di scambio tra i layer applicativi introduce una dipendenza forte tra i layer stessi. Esempio: L'applicazione è divisa nei tre classici layer: Web - Business(Services) - Persistence(Dao) . Se tra tutti i layer vengono scambiati gli stessi oggetti,significa che tutti i layer applicativi dipendono da queesti ultimi. Questo è male in quanto eventuali modifiche non saranno localizzate in un solo punto,ma spalmate su tutto lo stack architetturale. 2. Le sole entity potrebbero non bastare a modellare i dati dei quali si desidera usufruire Esempio: Si vogliono mostare nel layer WEB una seire di dati. Questa serie di dati potrebbero essere rappresentati da piu entity in correlazione tra loro,e non da una signola entity. Che succede? Dovrai necessariamente costuirti un oggetto Wrapper (toh...un dto che wrappa entity) che wrappi tutte le entità proprietarie di quei dati. Questa non è una cosa bella,in quanto trascinarsi oggetti compositi tra i layer,che contegnono anche dati che in realtà non ti servono per quella data funzionalità,introduce un overhead non sempre trascurabile (gli oggetti java sono pesanti...). Immagina se poi stai progettando un sistema dove i dati devono viaggiare in remoto(business esposto tramite webservices,oggi è prassi). Brutta soluzione davvero. L'idea di base è quella di costruirsi DTO appositi che vanno a rappresentare solo le informazioni che una data funzionalità si presuppone di recuperare. Hai bisogno dei dati A,B,C che a livello di dominio (e quindi di entity) sono rappresentate dalle entiy 1,2,3 ? Perchè trascinarsi tutto dietro? Si crea un DTO WrapperDTO con le sole proprietà A,B,C. Il business avrà la responsabilità di recuparare le enitity (tramite i dao) lavorarle e infine copiare SOLO I DATI CHE SERVONO nel DTO,che infine verrà restituio al layer piu alto. Di solito il business restituisce DTO e utilizza i DAO per recuperare i dati. I DAO lavorano solo con le entity. Ultima modifica di javacomelava : 08-04-2013 alle 11:13. |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jul 2001
Messaggi: 9947
|
Scusami, abbi pazienza sono un po' testone.
Vorrei provare a capire 2 cose. 1] Supponiamo di avere un DAO che implementi questa interfaccia. Codice:
public interface IMovieDAO {
public Movie getMovie(String id);
public void getStars(String title);
public List<Movie> getMovies(String sql);
public List<Movie> getAllMovies();
public void insertMovie(Movie m);
public void updateMovie(Movie m);
public void deleteMovie(String id);
public void deleteAllMovies();
}
Codice:
public class Movie {
private Long id;
private String title;
private Date releaseDate;
/* costruttori */
public Movie() {
super();
}
public Movie(String title) {
this();
this.title = title;
}
/* getter e setter */
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
@Override
public String toString() {
return "Movie [id=" + id + ", title=" + title + ", releaseDate=" + releaseDate + "]";
}
}
2] Tu che differenza fai tra le seguenti locuzioni: VO - POJO - JavaBean? Per me sono tutte la stesa cosa, secondo i 3 principi fondamentali di Java: Incapsulamente ... ...
__________________
Aiuta la ricerca col tuo PC: >>Calcolo distribuito BOINC.Italy: unisciti anche tu<< Più largo è il sorriso, più affilato è il coltello. |
|
|
|
|
|
#12 |
|
Member
Iscritto dal: May 2009
Messaggi: 129
|
Parto dal presupposto che l'oggetto Movie sia una Entity (un ejb di tipo entity per la precisione).
Se il dao è utilizzato da un servizio che ha la responsabilità di resituire un "Movie" allora il DTO restiituito dal servizio sarà un oggetto MovieDTO identico all'entity Movie,che possiede solo i dati che tu vuoi far restituire dal servizio. Esempio: Nel business esponi un servizio: Codice:
public MovieDTO loadMovieById(int movieId); Mettiamo caso che tu debba sviluppare un servizio che restituisca tutti i titoli dei Movie e il relativo nome del regista. Hai due entity ( magari in relazione tra loro): Movie e Director. Quale entity tiri su? Movie? non basta Director? non basta Necessiti per forza di un oggetto composito che come minimo wrappi entrambe le entity. Anche creando questo oggetto composito,tireresti su un mondo di dati che al servizio non servono! Inoltre andresti a sviluppare logiche ingarbugliatissime per wrappare! L'idea è quella di farsi un oggetto proprio,contenente solo i dati necessari. In questo caso ad esempio potrebbe essere: Codice:
MovieInfoDTO
{
private String movieName;
private String directorName;
}
Codice:
public MovieInfoDTO loadMovieWithDirectorInfoById(int id)
{
// recupera il movie tramie il relativo Dao
....
// recupera il Director del Movie tramite il relativo Dao (o direttamente tramite la relazione con il movie)
....
// Copia le info necessarie dalle entity Movie e Director nel DTO da restituire
}
1. PERFORMANCE: I servizi caricheranno SOLO ed ESCLUSIVAMENTE i DATI che il client si aspetta 2. DISACCOPPIAMENTO: I layer ad alto livello non dipenderanno dai layer di basso livello (dao e relative entity) 3. Estrema facilità nelle logiche di wrapping: Devi solo copiare i dati che desideri dalle entity ai dto,senza inventarti chissa quali strutture dati per cercare di caricare dati compositi (presi da piu entity) VO (Value Object) sono oggetti particolari (un pò wrapper e pò di business) relativi ad un altro stile architetturale,piu orientato al dominio,denominato DDD (Domanin Driven Design).Seguono standard di sviluppo precisi. Evitali,anche perchè non avrebbero senso in un contesto architetturale non orientato al dominio. Io,personalmente,odio il ddd con tutto me stesso. L'esperienza mi ha insegnato a tenermi lontano da questo obbrobrio. POJO: Plain Old Java Object. Per definizione sono oggetti java semplicissimi,senza uno STANDARD STRETTO DA SEGUIRE per lo sviluppo.Non estendono ne implementano interfacce/classi particolari ne posseggono annotazioni. Sono quindi oggetti "CROSS APPLICATION,CROSS FRAMEWORK",teoricamente compatibili e portabili su ogni sistema. JavaBean: (e qui ricadono i nostri DTO). Praticamente sono dei POJO la cui struttura è RIGOROSAMENTE DEFINITA: Posseggono proprietà e relativi Getters & Setters ,con costruttore di default. Se una di questa condizioni viene a mancare allora jnon si può parlare di JavaBean. P.S.: Mi rendo conto comunque che la maggior parte delle cose che sto esponendo possano sembrare solo "pippe filosodofiche" di non facile e immediata comprensione. Inizialmente il mio consiglio è di seguire questi principi anche senza vederne direttamente l'utilità. Appena di addentrerai nello sviluppo di sistemi leggermente piu complessi esclamerai: "Grazie a DIO,mi sono fatte le pippe filosofiche". D'altra parte,se esistono ci sarà un perchè. Ultima modifica di javacomelava : 10-04-2013 alle 15:32. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:43.



















