DAO vs opbevaringsmønstre

1. Oversigt

Ofte betragtes implementeringerne af arkivet og DAO som udskiftelige, især i datacentriske apps. Dette skaber forvirring om deres forskelle.

I denne artikel vil vi diskutere forskellene mellem DAO og Repository mønstre.

2. DAO mønster

Dataadgangsobjektmønsteret, aka DAO mønster, er en abstraktion af data persistens og betragtes tættere på den underliggende lagring, som ofte er tabel-centreret.

Derfor matcher vores DAO'er i mange tilfælde databasetabeller, hvilket giver en mere ligetil måde at sende / hente data fra lageret, skjule de grimme forespørgsler.

Lad os undersøge en simpel implementering af DAO-mønsteret.

2.1. Bruger

Lad os først oprette en grundlæggende Bruger domæne klasse:

offentlig klasse bruger {privat Lang id; private streng brugernavn; privat streng fornavn; privat streng e-mail; // getters og setters}

2.2. UserDao

Derefter opretter vi UserDao interface, der giver enkle CRUD-operationer til Bruger domæne:

offentlig grænseflade UserDao {ugyldig oprette (brugerbruger); Brugerlæst (Lang id); ugyldig opdatering (brugerbruger); ugyldig sletning (streng brugernavn); }

2.3. UserDaoImpl

Til sidst opretter vi UserDaoImpl klasse, der implementerer UserDao grænseflade:

offentlig klasse UserDaoImpl implementerer UserDao {private final EntityManager entityManager; @ Overstyr offentlig tomrum oprette (brugerbruger) {entityManager.persist (bruger); } @ Override offentlig bruger læst (lang id) {return entityManager.find (User.class, id); } // ...}

Her har vi for enkelheds skyld brugt JPA EntityManager interface til at interagere med underliggende lagring og give en dataadgangsmekanisme til Bruger domæne.

3. Depotmønster

I henhold til Eric Evans 'bog Domain-Driven Design, det "Arkiv er en mekanisme til indkapsling af opbevaring, hentning og søgeadfærd, som efterligner en samling objekter."

Ligeledes ifølge Mønstre af Enterprise Application Architecture, det "Formidler mellem domænet og lagring af datakort ved hjælp af en samlingslignende grænseflade til at få adgang til domæneobjekter."

Med andre ord behandler et arkiv også data og skjuler forespørgsler svarende til DAO. Det sidder dog på et højere niveau tættere på en apps forretningslogik.

Derfor kan et arkiv bruge en DAO til at hente data fra databasen og udfylde et domæneobjekt. Eller det kan forberede dataene fra et domæneobjekt og sende dem til et lagersystem ved hjælp af en DAO til persistens.

Lad os undersøge en simpel implementering af arkivet mønster til Bruger domæne.

3.1. UserRepository

Lad os først oprette UserRepository grænseflade:

offentlig grænseflade UserRepository {User get (Long id); void add (brugerbruger); ugyldig opdatering (brugerbruger); annullere fjernelse (brugerbruger); }

Her har vi tilføjet et par almindelige metoder som , tilføje, opdateringog fjerne at arbejde med indsamlingen af ​​objekter.

3.2. UserRepositoryImpl

Derefter opretter vi UserRepositoryImpl klasse, der giver en implementering af UserRepository grænseflade:

offentlig klasse UserRepositoryImpl implementerer UserRepository {private UserDaoImpl userDaoImpl; @Override public User get (Long id) {User user = userDaoImpl.read (id); tilbagevendende bruger } @ Overstyr offentlig ugyldig tilføj (brugerbruger) {userDaoImpl.create (bruger); } // ...}

Her har vi brugt UserDaoImpl at sende / hente data fra databasen.

Indtil videre kan vi sige, at implementeringerne af DAO og repository ser meget ens ud, fordi Bruger klasse er et anæmisk domæne. Og et lager er bare et andet lag over dataadgangslaget (DAO).

DAO synes imidlertid at være en perfekt kandidat til at få adgang til dataene, og et arkiv er en ideel måde at implementere en forretningsanvendelse på.

4. Depotmønster med flere DAO'er

For at forstå den sidste erklæring klart, lad os forbedre vores Bruger domæne til at håndtere en forretningsbrugssag.

Forestil dig, at vi vil forberede en social medieprofil for en bruger ved at samle hans Twitter-tweets, Facebook-indlæg og mere.

4.1. Tweet

Først opretter vi Tweet klasse med et par egenskaber, der indeholder tweetoplysningerne:

offentlig klasse Tweet {privat streng-e-mail; privat streng tweetText; privat Dato dato Oprettet; // getters og setters}

4.2. TweetDao og TweetDaoImpl

Derefter svarer til UserDao, vi opretter TweetDao interface der tillader hentning af tweets:

offentlig grænseflade TweetDao {Liste fetchTweets (streng e-mail); }

Ligeledes opretter vi TweetDaoImpl klasse, der giver implementeringen af fetchTweets metode:

offentlig klasse TweetDaoImpl implementerer TweetDao {@ Override offentlig liste fetchTweets (String email) {List tweets = new ArrayList (); // ring til Twitter API og forbered tweets til returnering af Tweet-objekt; }}

Her kalder vi Twitter API'er for at hente alle tweets af en bruger ved hjælp af hans e-mail.

Så i dette tilfælde leverer en DAO en dataadgangsmekanisme ved hjælp af tredjeparts-API'er.

4.3. Forbedre Bruger Domæne

Lad os sidst oprette UserSocialMedia underklasse af vores Bruger klasse for at føre en liste over Tweet genstande:

offentlig klasse UserSocialMedia udvider bruger {private List tweets; // getters og setters}

Her, vores UserSocialMedia klasse er et komplekst domæne, der indeholder egenskaberne for Bruger domæne også.

4.4. UserRepositoryImpl

Nu opgraderer vi vores UserRepositoryImpl klasse til at give en Bruger domæneobjekt sammen med en liste over tweets:

offentlig klasse UserRepositoryImpl implementerer UserRepository {privat 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); tilbagevendende bruger }}

Her, den UserRepositoryImpl udtrækker brugerdata ved hjælp af UserDaoImpl og brugerens tweets ved hjælp af TweetDaoImpl.

Derefter samler det begge sæt information og giver et domæneobjekt af UserSocialMedia klasse, der er praktisk til vores forretningsbrug. Derfor, et lager er afhængigt af DAO'er for at få adgang til data fra forskellige kilder.

På samme måde kan vi forbedre vores Bruger domæne for at holde en liste over Facebook-indlæg.

5. Sammenligning af de to mønstre

Nu hvor vi har set nuancerne i DAO og Repository mønstre, lad os sammenfatte deres forskelle:

  • DAO er en abstraktion af data persistens. Et lager er imidlertid en abstraktion af en samling objekter
  • DAO er et lavere niveau koncept tættere på lagringssystemerne. Repository er dog et koncept på højere niveau tættere på domæneobjekterne
  • DAO fungerer som et data kortlægning / adgang lag, skjule grimme forespørgsler. Et lager er dog et lag mellem domæner og dataadgangslag, der skjuler kompleksiteten ved at samle data og forberede et domæneobjekt
  • DAO kan ikke implementeres ved hjælp af et lager. Et lager kan dog bruge en DAO til at få adgang til underliggende lager

Også, hvis vi har et anæmisk domæne, vil lageret kun være en DAO.

Derudover depotmønsteret tilskynder til et domænestyret design, der også giver en let forståelse af datastrukturen for ikke-tekniske teammedlemmer.

6. Konklusion

I denne artikel undersøgte vi forskelle mellem DAO og Repository mønstre.

Først undersøgte vi en grundlæggende implementering af DAO-mønsteret. Derefter så vi en lignende implementering ved hjælp af repository-mønsteret.

Til sidst kiggede vi på et lager, der udnyttede flere DAO'er, hvilket forbedrede et domænes kapacitet til at løse et forretningsbrug.

Derfor kan vi konkludere, at repository-mønsteret viser en bedre tilgang, når en app bevæger sig fra at være data-centreret til forretningsorienteret.

Som normalt er alle kodeimplementeringer tilgængelige på GitHub.


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