Risposte:
DAO
è un'astrazione della persistenza dei dati .
Repository
è un'astrazione di una collezione di oggetti .
DAO
sarebbe considerato più vicino al database, spesso incentrato sulla tabella.
Repository
sarebbe considerato più vicino al Dominio, trattando solo in Radici Aggregate.
Repository
potrebbe essere implementato usando DAO
"s", ma non faresti il contrario.
Inoltre, a Repository
è generalmente un'interfaccia più stretta. Dovrebbe essere semplicemente una collezione di oggetti, con un Get(id)
, Find(ISpecification)
, Add(Entity)
.
Un metodo simile Update
è appropriato su a DAO
, ma non su Repository
- quando si utilizza a Repository
, le modifiche alle entità verrebbero generalmente monitorate da UnitOfWork separato.
Sembra comune vedere implementazioni chiamate a Repository
che sono davvero più di a DAO
, e quindi penso che ci sia un po 'di confusione sulla differenza tra loro.
OK, penso di poter spiegare meglio cosa ho inserito nei commenti :). Quindi, fondamentalmente, puoi vedere entrambi uguali, sebbene DAO sia un modello più flessibile rispetto al repository. Se si desidera utilizzare entrambi, utilizzare il repository nei DAO. Spiegherò ciascuno di loro di seguito:
È un repository di un tipo specifico di oggetti: consente di cercare un tipo specifico di oggetti e di memorizzarli. Di solito gestirà SOLO un tipo di oggetti. Ad esempio AppleRepository
ti permetterebbe di fare AppleRepository.findAll(criteria)
o AppleRepository.save(juicyApple)
. Si noti che il repository utilizza i termini del modello di dominio (non i termini DB, nulla correlato al modo in cui i dati vengono mantenuti ovunque).
Molto probabilmente un repository memorizzerà tutti i dati nella stessa tabella, mentre il modello non lo richiede. Il fatto che gestisca solo un tipo di dati lo rende logicamente connesso a una tabella principale (se utilizzata per la persistenza del DB).
Un DAO è una classe che individua i dati per te (è principalmente un finder, ma è comunemente usato anche per archiviare i dati). Il modello non ti limita a memorizzare dati dello stesso tipo, quindi puoi facilmente avere un DAO che individua / memorizza oggetti correlati.
Ad esempio puoi facilmente avere UserDao che espone metodi come
Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)
Tutti questi sono correlati all'utente (e alla sicurezza) e possono essere specificati sotto lo stesso DAO. Questo non è il caso del repository.
Si noti che entrambi i modelli hanno davvero lo stesso significato (memorizzano i dati e astraggono l'accesso ad essi e sono entrambi espressi più vicini al modello di dominio e non contengono quasi alcun riferimento DB), ma il modo in cui vengono utilizzati può essere leggermente diverso, essendo DAO un po 'più flessibile / generico, mentre Repository è un po' più specifico e restrittivo solo per un tipo.
CarDescription
ad esempio, language_id
come chiave esterna - quindi per recuperare che dovrei fare qualcosa del genere: CarRepository.getAll(new Criteria(carOwner.id, language.id));
che mi darebbe tutte le macchine di una lingua in una lingua specifica - è che il modo giusto di farlo ?
CarRepository.findByLanguageId(language.id)
e non avresti nemmeno bisogno di scrivere il codice, devi solo definire l'interfaccia con un metodo con quel nome e Spring Data si occupa di costruire l'implementazione della classe predefinita per te. Roba piuttosto ordinata;)
findById
). E hai praticamente finito. Quello che poi fa Spring Data è, trova tutte queste interfacce che hai creato che estendono l'interfaccia del repository e crea le classi per te. Non vedrai mai quelle classi e non sarai in grado di creare nuove istanze, ma non è necessario in quanto puoi semplicemente autorizzare l'interfaccia e lasciare che Spring localizzi quell'oggetto repository.
DAO e modello di repository sono modi per implementare Data Access Layer (DAL). Quindi, iniziamo con DAL, prima.
Le applicazioni orientate agli oggetti che accedono a un database devono avere una logica per gestire l'accesso al database. Per mantenere il codice pulito e modulare, si consiglia di isolare la logica di accesso al database in un modulo separato. Nell'architettura a strati, questo modulo è DAL.
Finora non abbiamo parlato di un'implementazione particolare: solo un principio generale che mette la logica di accesso al database in un modulo separato.
Ora, come possiamo applicare questo principio? Bene, un modo noto per implementarlo, in particolare con framework come Hibernate, è il modello DAO.
Il modello DAO è un modo per generare DAL, dove in genere ogni entità di dominio ha il proprio DAO. Ad esempio, User
e UserDao
, Appointment
e AppointmentDao
, ecc. Un esempio di DAO con Hibernate: http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .
Allora qual è il modello di deposito? Come DAO, anche il modello di repository è un modo per raggiungere il DAL. Il punto principale nel modello di repository è che, dal punto di vista client / utente, dovrebbe apparire o comportarsi come una raccolta. Ciò che si intende comportandosi come una collezione non è che debba essere istanziato come Collection collection = new SomeCollection()
. Invece, significa che dovrebbe supportare operazioni come aggiungere, rimuovere, contenere, ecc. Questa è l'essenza del modello di repository.
In pratica, ad esempio nel caso dell'utilizzo di Hibernate, il modello di repository viene realizzato con DAO. Questa è un'istanza di DAL può essere allo stesso tempo un'istanza del modello DAO e del modello del repository.
Il modello di repository non è necessariamente qualcosa che si basa su DAO (come alcuni potrebbero suggerire). Se i DAO sono progettati con un'interfaccia che supporta le operazioni sopra menzionate, si tratta di un'istanza del modello di repository. Pensaci, se i DAO forniscono già una serie di operazioni simili a raccolte, allora qual è la necessità di un ulteriore livello?
Francamente, questo sembra una distinzione semantica, non una distinzione tecnica. La frase Data Access Object non si riferisce affatto a un "database". E, sebbene tu possa progettarlo come incentrato sul database, penso che la maggior parte delle persone considererebbe di farlo un difetto di progettazione.
Lo scopo del DAO è nascondere i dettagli di implementazione del meccanismo di accesso ai dati. In che modo differisce il modello di deposito? Per quanto ne so, non lo è. Dire che un repository è diverso da un DAO perché hai a che fare con / restituire una collezione di oggetti non può essere giusto; I DAO possono anche restituire raccolte di oggetti.
Tutto ciò che ho letto sul modello di repository sembra basarsi su questa distinzione: cattivo design DAO vs buon design DAO (noto anche come design pattern del repository).
Repository è un termine più astratto orientato al dominio che fa parte del Domain Driven Design, fa parte del design del tuo dominio e di un linguaggio comune, DAO è un'astrazione tecnica per la tecnologia di accesso ai dati, il repository riguarda solo la gestione di dati e fabbriche esistenti per la creazione di dati.
controlla questi link:
http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html
La differenza fondamentale è che un repository gestisce l'accesso alle radici aggregate in un aggregato, mentre DAO gestisce l'accesso alle entità. Pertanto, è comune che un repository deleghi la persistenza effettiva delle radici aggregate a un DAO. Inoltre, poiché la radice aggregata deve gestire l'accesso delle altre entità, potrebbe essere necessario delegare questo accesso ad altri DAO.
DAO fornisce astrazione su file di database / dati o qualsiasi altro meccanismo di persistenza in modo che il livello di persistenza possa essere manipolato senza conoscerne i dettagli di implementazione.
Considerando che nelle classi Repository, più classi DAO possono essere utilizzate all'interno di un singolo metodo Repository per eseguire un'operazione dal "punto di vista dell'app". Quindi, invece di utilizzare più DAO a livello di dominio, utilizzare il repository per farlo. Il repository è un livello che può contenere una logica applicativa come: Se i dati sono disponibili nella cache in memoria, recuperarli dalla cache in caso contrario, recuperare i dati dalla rete e archiviarli nella cache in memoria per il successivo recupero.
Il repository non è altro che DAO ben progettato.
Gli ORM sono centrati sulla tabella ma non DAO.
Non è necessario utilizzare diversi DAO nel repository poiché DAO stesso può fare esattamente lo stesso con repository / entità ORM o qualsiasi provider DAL, indipendentemente da dove e come viene mantenuta un'auto 1 tabella, 2 tabelle, n tabelle, mezza tabella, un servizio web, una tabella e un servizio web ecc. I servizi utilizzano diversi DAO / repository.
Il mio DAO, diciamo che CarDao si occupa solo di Car DTO, intendo, accetta solo Car DTO in input e restituisce solo auto DTO o auto DTO in output.
Quindi, proprio come Repository, DAO è in realtà un IoC, per la logica aziendale, che consente alle interfacce di persistenza di non essere intimidite da strategie o lasciti di persistenza. DAO incapsula entrambi la strategia di persistenza e fornisce l'interfaccia di persistenza relativa a domaine. Repository è solo un'altra parola per coloro che non avevano capito cosa fosse effettivamente un DAO ben definito.
Prova a scoprire se DAO o il modello di repository sono più applicabili alla seguente situazione: Immagina di voler fornire un'API di accesso ai dati uniforme per un meccanismo persistente a vari tipi di origini dati come RDBMS, LDAP, OODB, repository XML e file flat.
Fare riferimento anche ai seguenti collegamenti, se interessati:
http://www.codeinsanity.com/2008/08/repository-pattern.html
http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/
http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx
in una frase molto semplice: la differenza significativa è che i repository rappresentano raccolte, mentre i DAO sono più vicini al database, spesso essendo molto più incentrati sulle tabelle.
Nel framework di primavera, c'è un'annotazione chiamata repository e nella descrizione di questa annotazione, ci sono informazioni utili sul repository, che ritengo sia utile per questa discussione.
Indica che una classe annotata è un "repository", originariamente definito da Domain-Driven Design (Evans, 2003) come "un meccanismo per incapsulare il comportamento di archiviazione, recupero e ricerca che emula una raccolta di oggetti".
I team che implementano i tradizionali schemi Java EE come "Data Access Object" possono anche applicare questo stereotipo alle classi DAO, sebbene prima di farlo si dovrebbe prestare attenzione a capire la distinzione tra Data Access Object e repository in stile DDD. Questa annotazione è uno stereotipo per tutti gli usi e i singoli team possono restringere la loro semantica e utilizzare come appropriato.
Una classe così annotata è idonea per la traduzione di Spring DataAccessException se utilizzata in combinazione con un PersistenceExceptionTranslationPostProcessor. La classe annotata viene inoltre chiarita in merito al suo ruolo nell'architettura generale dell'applicazione ai fini di strumenti, aspetti, ecc.
IRepository
interfaccia. Vorresti che il tuo repository usasse i DAO nella sua implementazione. Ricorda, un DAO sarà un oggetto per tabella, mentre un repository dovrà quasi sempre usare più DAO per costruire una singola Entità. Se scopri che non è così, che il tuo Repository ed Entity devono solo accedere a una singola tabella, allora probabilmente stai costruendo un dominio anemico.