DAO vs Pola Repositori

1. Ikhtisar

Seringkali, implementasi repositori dan DAO dianggap dapat dipertukarkan, terutama dalam aplikasi yang berpusat pada data. Ini menciptakan kebingungan tentang perbedaan mereka.

Pada artikel ini, kita akan membahas perbedaan antara DAO dan pola Repositori.

2. Pola DAO

Pola Objek Akses Data, alias Pola DAO , adalah abstraksi dari persistensi data dan dianggap lebih dekat ke penyimpanan yang mendasarinya, yang sering kali berpusat pada tabel .

Oleh karena itu, dalam banyak kasus, DAO kami cocok dengan tabel database, memungkinkan cara yang lebih mudah untuk mengirim / mengambil data dari penyimpanan, menyembunyikan kueri jelek.

Mari kita periksa implementasi sederhana dari pola DAO.

2.1. Pengguna

Pertama, mari buat kelas domain Pengguna dasar :

public class User { private Long id; private String userName; private String firstName; private String email; // getters and setters }

2.2. User Dao

Kemudian, kita akan membuat antarmuka UserDao yang menyediakan operasi CRUD sederhana untuk domain User :

public interface UserDao { void create(User user); User read(Long id); void update(User user); void delete(String userName); }

2.3. User DaoImpl

Terakhir, kita akan membuat kelas UserDaoImpl yang mengimplementasikan antarmuka UserDao :

public class UserDaoImpl implements UserDao { private final EntityManager entityManager; @Override public void create(User user) { entityManager.persist(user); } @Override public User read(long id) { return entityManager.find(User.class, id); } // ... }

Di sini, untuk kesederhanaan, kami telah menggunakan antarmuka JPA EntityManager untuk berinteraksi dengan penyimpanan yang mendasari dan menyediakan mekanisme akses data untuk domain Pengguna .

3. Pola Repositori

Sesuai dengan buku Eric Evans, Domain-Driven Design , "repositori adalah mekanisme untuk merangkum penyimpanan, pengambilan, dan perilaku penelusuran, yang mengemulasi kumpulan objek."

Demikian pula, menurut Patterns of Enterprise Application Architecture , "memediasi antara domain dan lapisan pemetaan data menggunakan antarmuka seperti koleksi untuk mengakses objek domain".

Dengan kata lain, repositori juga menangani data dan menyembunyikan kueri yang mirip dengan DAO. Namun, itu berada pada level yang lebih tinggi, lebih dekat dengan logika bisnis sebuah aplikasi.

Akibatnya, repositori bisa menggunakan DAO untuk mengambil data dari database dan mengisi objek domain. Atau, dapat menyiapkan data dari objek domain dan mengirimkannya ke sistem penyimpanan menggunakan DAO untuk persistensi.

Mari kita periksa implementasi sederhana dari pola Repositori untuk domain Pengguna .

3.1. UserRepository

Pertama, mari buat antarmuka UserRepository :

public interface UserRepository { User get(Long id); void add(User user); void update(User user); void remove(User user); }

Di sini, kami telah menambahkan beberapa metode umum seperti get , add , update , dan remove untuk bekerja dengan kumpulan objek.

3.2. UserRepositoryImpl

Kemudian, kita akan membuat kelas UserRepositoryImpl yang menyediakan implementasi antarmuka UserRepository :

public class UserRepositoryImpl implements UserRepository { private UserDaoImpl userDaoImpl; @Override public User get(Long id) { User user = userDaoImpl.read(id); return user; } @Override public void add(User user) { userDaoImpl.create(user); } // ... }

Di sini, kami telah menggunakan UserDaoImpl untuk mengirim / mengambil data dari database.

Sejauh ini, kita dapat mengatakan bahwa implementasi DAO dan repositori terlihat sangat mirip karena kelas User merupakan domain anemia. Dan, repositori hanyalah lapisan lain di atas lapisan akses data (DAO).

Namun, DAO tampaknya kandidat yang tepat untuk mengakses data, dan repositori adalah cara ideal untuk mengimplementasikan kasus penggunaan bisnis .

4. Pola Repositori Dengan Beberapa DAO

Untuk memahami dengan jelas pernyataan terakhir, mari tingkatkan domain Pengguna kami untuk menangani kasus penggunaan bisnis.

Bayangkan kita ingin menyiapkan profil media sosial pengguna dengan menggabungkan tweet Twitter, postingan Facebook, dan lainnya.

4.1. Menciak

Pertama, kami akan membuat kelas Tweet dengan beberapa properti yang menyimpan informasi tweet:

public class Tweet { private String email; private String tweetText; private Date dateCreated; // getters and setters }

4.2. TweetDao and TweetDaoImpl

Then, similar to the UserDao, we'll create the TweetDao interface that allows fetching tweets:

public interface TweetDao { List fetchTweets(String email); }

Likewise, we'll create the TweetDaoImpl class that provides the implementation of the fetchTweets method:

public class TweetDaoImpl implements TweetDao { @Override public List fetchTweets(String email) { List tweets = new ArrayList(); //call Twitter API and prepare Tweet object return tweets; } }

Here, we'll call Twitter APIs to fetch all tweets by a user using his email.

So, in this case, a DAO provides a data access mechanism using third-party APIs.

4.3. Enhance User Domain

Last, let's create the UserSocialMedia subclass of our User class to keep a list of the Tweet objects:

public class UserSocialMedia extends User { private List tweets; // getters and setters }

Here, our UserSocialMedia class is a complex domain containing the properties of the User domain too.

4.4. UserRepositoryImpl

Now, we'll upgrade our UserRepositoryImpl class to provide a User domain object along with a list of tweets:

public class UserRepositoryImpl implements UserRepository { private UserDaoImpl userDaoImpl; private TweetDaoImpl tweetDaoImpl; @Override public User get(Long id) { UserSocialMedia user = (UserSocialMedia) userDaoImpl.read(id); List tweets = tweetDaoImpl.fetchTweets(user.getEmail()); user.setTweets(tweets); return user; } }

Here, the UserRepositoryImpl extracts user data using the UserDaoImpl and user's tweets using the TweetDaoImpl.

Then, it aggregates both sets of information and provides a domain object of the UserSocialMedia class that is handy for our business use-case. Therefore, a repository relies on DAOs for accessing data from various sources.

Similarly, we can enhance our User domain to keep a list of Facebook posts.

5. Comparing the Two Patterns

Now that we've seen the nuances of the DAO and Repository patterns, let's summarize their differences:

  • DAO is an abstraction of data persistence. However, a repository is an abstraction of a collection of objects
  • DAO is a lower-level concept, closer to the storage systems. However, Repository is a higher-level concept, closer to the Domain objects
  • DAO works as a data mapping/access layer, hiding ugly queries. However, a repository is a layer between domains and data access layers, hiding the complexity of collating data and preparing a domain object
  • DAO can't be implemented using a repository. However, a repository can use a DAO for accessing underlying storage

Also, if we have an anemic domain, the repository will be just a DAO.

Additionally, the repository pattern encourages a domain-driven design, providing an easy understanding of the data structure for non-technical team members, too.

6. Conclusion

In this article, we explored differences between DAO and Repository patterns.

First, we examined a basic implementation of the DAO pattern. Then, we saw a similar implementation using the Repository pattern.

Last, we looked at a Repository utilizing multiple DAOs, enhancing the capabilities of a domain to solve a business use-case.

Therefore, we can conclude that the Repository pattern proves a better approach when an app moves from being data-centric to business-oriented.

As usual, all the code implementations are available over on GitHub.