DAO vs Repository Patterns

1. Oversikt

Implementering av repository og DAO blir ofte ansett som utskiftbare, spesielt i datasentriske apper. Dette skaper forvirring om forskjellene deres.

I denne artikkelen vil vi diskutere forskjellene mellom DAO og Repository mønstre.

2. DAO-mønster

Data Access Object Pattern, aka DAO mønster, er en abstraksjon av datapresistens og regnes som nærmere den underliggende lagringen, som ofte er bordsentrert.

Derfor, i mange tilfeller, samsvarer DAO-ene våre med databasetabeller, slik at en enklere måte å sende / hente data fra lagring på, skjuler de stygge spørsmålene.

La oss undersøke en enkel implementering av DAO-mønsteret.

2.1. Bruker

La oss først lage en grunnleggende Bruker domeneklasse:

offentlig klasse bruker {privat Lang id; privat streng brukernavn; privat streng fornavn; privat streng e-post; // getters og setters}

2.2. UserDao

Deretter lager vi UserDao grensesnitt som gir enkle CRUD-operasjoner for Bruker domene:

offentlig grensesnitt UserDao {void create (brukerbruker); Brukerleset (Lang id); ugyldig oppdatering (brukerbruker); ugyldig sletting (String brukernavn); }

2.3. UserDaoImpl

Til slutt lager vi UserDaoImpl klasse som implementerer UserDao grensesnitt:

offentlig klasse UserDaoImpl implementerer UserDao {private final EntityManager entityManager; @ Overstyr offentlig tomrom opprette (brukerbruker) {entityManager.persist (bruker); } @ Override public User read (long id) {return entityManager.find (User.class, id); } // ...}

Her, for enkelhets skyld, har vi brukt JPA EntityManager grensesnitt for å samhandle med underliggende lagring og gi en datatilgangsmekanisme for Bruker domene.

3. Depotmønster

I henhold til Eric Evans 'bok Domenedrevet design, den "Repository er en mekanisme for innkapsling av lagring, henting og søkeatferd, som etterligner en samling objekter."

Likeledes ifølge Mønstre av Enterprise Application Architecture, den “Formidler mellom domenet og datakartingslagene ved hjelp av et samlingsliknende grensesnitt for tilgang til domeneobjekter.”

Med andre ord håndterer et depot også data og skjuler spørsmål som ligner på DAO. Imidlertid sitter den på et høyere nivå, nærmere forretningslogikken til en app.

Derfor kan et depot bruke en DAO til å hente data fra databasen og fylle ut et domeneobjekt. Eller det kan klargjøre dataene fra et domeneobjekt og sende dem til et lagringssystem ved hjelp av en DAO for utholdenhet.

La oss undersøke en enkel implementering av depotmønsteret for Bruker domene.

3.1. UserRepository

La oss først lage UserRepository grensesnitt:

offentlig grensesnitt UserRepository {User get (Long id); void add (brukerbruker); ugyldig oppdatering (brukerbruker); ugyldig fjerne (brukerbruker); }

Her har vi lagt til noen vanlige metoder som , legge til, Oppdater, og fjerne å jobbe med samling av objekter.

3.2. UserRepositoryImpl

Deretter lager vi UserRepositoryImpl klasse som gir en implementering av UserRepository grensesnitt:

offentlig klasse UserRepositoryImpl implementerer UserRepository {private UserDaoImpl userDaoImpl; @Override public User get (Long id) {User user = userDaoImpl.read (id); retur bruker; } @Override public void add (Brukerbruker) {userDaoImpl.create (bruker); } // ...}

Her har vi brukt UserDaoImpl for å sende / hente data fra databasen.

Så langt kan vi si at implementeringene av DAO og repository ser veldig like ut fordi Bruker klasse er et anemisk domene. Og et depot er bare et lag over datatilgangslaget (DAO).

Imidlertid virker DAO som en perfekt kandidat for å få tilgang til dataene, og et depot er en ideell måte å implementere en forretningsbruk.

4. Datamaskinmønster med flere DAOer

For å forstå den siste uttalelsen, la oss forbedre vår Bruker domene for å håndtere et forretningsbruk.

Tenk deg at vi vil lage en sosial medieprofil for en bruker ved å samle Twitter-tweets, Facebook-innlegg og mer.

4.1. kvitring

Først skal vi lage kvitring klasse med noen få egenskaper som inneholder tweetinformasjonen:

offentlig klasse Tweet {private String email; privat streng tweetText; privat Dato dato Opprettet; // getters og setters}

4.2. TweetDao og TweetDaoImpl

Så, i likhet med UserDao, lager vi TweetDao grensesnitt som gjør det mulig å hente tweets:

offentlig grensesnitt TweetDao {List fetchTweets (streng e-post); }

På samme måte lager vi TweetDaoImpl klasse som gir implementering av fetchTweets metode:

offentlig klasse TweetDaoImpl implementerer TweetDao {@Override public List fetchTweets (String email) {List tweets = new ArrayList (); // ring Twitter API og forbered Tweets for retur av objektet; }}

Her vil vi ringe Twitter APIer for å hente alle tweets av en bruker ved hjelp av e-posten sin.

Så i dette tilfellet gir en DAO en datatilgangsmekanisme ved bruk av tredjeparts APIer.

4.3. Forbedre Bruker Domene

Sist, la oss lage UserSocialMedia underklasse av vår Bruker klasse for å føre en liste over kvitring gjenstander:

offentlig klasse UserSocialMedia utvider bruker {private List tweets; // getters og setters}

Her, vår UserSocialMedia klasse er et komplekst domene som inneholder egenskapene til Bruker domene også.

4.4. UserRepositoryImpl

Nå oppgraderer vi vår UserRepositoryImpl klasse for å gi en Bruker domeneobjekt sammen med en liste over tweets:

offentlig klasse UserRepositoryImpl implementerer UserRepository {private UserDaoImpl userDaoImpl; privat TweetDaoImpl tweetDaoImpl; @Override public User get (Long id) {UserSocialMedia user = (UserSocialMedia) userDaoImpl.read (id); Liste tweets = tweetDaoImpl.fetchTweets (user.getEmail ()); user.setTweets (tweets); retur bruker; }}

Her, den UserRepositoryImpl trekker ut brukerdata ved hjelp av UserDaoImpl og brukerens tweets ved hjelp av TweetDaoImpl.

Deretter samler det begge settene med informasjon og gir et domeneobjekt av UserSocialMedia klasse som er nyttig for vårt forretningsbruk. Derfor, et depot er avhengig av DAO for tilgang til data fra forskjellige kilder.

På samme måte kan vi forbedre vår Bruker domene for å holde en liste over Facebook-innlegg.

5. Sammenligning av de to mønstrene

Nå som vi har sett nyansene i DAO og Repository-mønstrene, la oss oppsummere forskjellene deres:

  • DAO er en abstraksjon av datapresistens. Et depot er imidlertid en abstraksjon av en samling objekter
  • DAO er et konsept på lavere nivå, nærmere lagringssystemene. Repository er imidlertid et konsept på høyere nivå, nærmere Domain-objektene
  • DAO fungerer som et datakartings- / tilgangslag, og skjuler stygge spørsmål. Et depot er imidlertid et lag mellom domener og datatilgangslag, som skjuler kompleksiteten i å samle data og forbereder et domeneobjekt
  • DAO kan ikke implementeres ved hjelp av et depot. Et depot kan imidlertid bruke en DAO for å få tilgang til underliggende lagring

Også, hvis vi har et anemisk domene, vil depotet bare være en DAO.

I tillegg depotmønsteret oppmuntrer til et domenedrevet design, som også gir en enkel forståelse av datastrukturen for ikke-tekniske teammedlemmer.

6. Konklusjon

I denne artikkelen undersøkte vi forskjeller mellom DAO og Repository mønstre.

Først undersøkte vi en grunnleggende implementering av DAO-mønsteret. Deretter så vi en lignende implementering ved hjelp av Repository-mønsteret.

Til slutt så vi på et depot som bruker flere DAO-er, og forbedret mulighetene til et domene for å løse et forretningsbruk.

Derfor kan vi konkludere med at depotmønsteret viser en bedre tilnærming når en app går fra å være datasentrisk til forretningsorientert.

Som vanlig er alle kodeimplementeringene tilgjengelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found