拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 DAO与repository模式

DAO与repository模式

白鹭 - 2021-11-24 731 0 0

1.概述

通常,Repository和DAO的实现被认为是可互换的,尤其是在以数据为中心的应用程序中。这引起了他们之间差异的困惑。

在本文中,我们将讨论DAO和repository模式之间的区别。

2. DAO模式

数据访问对像模式(也称为DAO模式是数据持久性的抽象,被认为更接近于以表为中心的基础存储

因此,在许多情况下,我们的DAO与数据库表匹配,从而提供了一种更直接的方式来从存储发送/检索数据,从而隐藏了难看的查询。

让我们研究一下DAO模式的简单实现。

2.1。 User

首先,让我们创建一个基本的User域类:

public class User {

 private Long id;

 private String userName;

 private String firstName;

 private String email;



 // getters and setters

 }

2.2。 UserDao

然后,我们将创建UserDao接口,该接口为User域提供简单的CRUD操作:

public interface UserDao {

 void create(User user);

 User read(Long id);

 void update(User user);

 void delete(String userName);

 }

2.3。 UserDaoImpl

最后,我们将创建实现UserDao接口的UserDaoImpl类:

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);

 }



 // ...

 }

在这里,为简单起见,我们使用了JPA EntityManager接口与基础存储进行交互,并为User域提供了一种数据访问机制。

3.Repository模式

根据Eric Evans的《 Domain-Driven Design 》一书“Repository是一种封装存储,检索和搜索行为的机制,它模仿对象的集合。”

同样,根据Patterns of Enterprise Application Architecture它使用类似集合的接口访问域对象,在域和数据映射层之间进行中介”

换句话说,repository还处理数据并隐藏类似于DAO的查询。但是,它处于更高的层次,更接近应用程序的业务逻辑。

因此,repository 可以使用DAO从数据库中获取数据并填充域对象。或者,它可以从域对象准备数据,然后使用DAO将其发送到存储系统以实现持久性。

让我们检查一下User域的Repository模式的简单实现。

3.1。 UserRepository

首先,让我们创建UserRepository接口:

public interface UserRepository {

 User get(Long id);

 void add(User user);

 void update(User user);

 void remove(User user);

 }

在这里,我们添加了一些通用方法,例如getaddupdateremove以处理对象集合。

3.2。 UserRepositoryImpl

然后,我们将创建UserRepositoryImpl类,提供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);

 }



 // ...

 }

在这里,我们使用了UserDaoImpl从数据库添加/检索数据。

到目前为止,我们可以说DAO和存储库的实现看起来非常相似,因为User类是贫血领域。而且,repository只是数据访问层(DAO)之上的另一层。

但是,DAO似乎是访问数据的理想选择,而repository是实现业务用例的理想方式

4.具有多个DAO的存储库模式

为了清楚地理解最后一条语句,让我们增强User域以处理业务用例。

想象一下,我们想通过汇总用户的Twitter推文,Facebook帖子等来准备用户的社交媒体资料。

4.1。 Tweet

首先,我们将创建Tweet类,其中包含一些用于保存tweet信息的属性:

public class Tweet {

 private String email;

 private String tweetText;

 private Date dateCreated;



 // getters and setters

 }

4.2。 TweetDaoTweetDaoImpl

然后,类似于UserDao ,我们将创建TweetDao接口,该接口允许获取推文:

public interface TweetDao {

 List<Tweet> fetchTweets(String email);

 }

同样,我们将创建TweetDaoImpl类,该类提供fetchTweets方法的实现:

public class TweetDaoImpl implements TweetDao {

 @Override

 public List<Tweet> fetchTweets(String email) {

 List<Tweet> tweets = new ArrayList<Tweet>();



 //call Twitter API and prepare Tweet object



 return tweets;

 }

 }

在这里,我们将调用Twitter API,以使用户使用其电子邮件获取所有推文。

因此,在这种情况下,DAO使用第三方API提供了一种数据访问机制。

4.3。增强User

最后,让我们创建User类的UserSocialMedia子类,以保留Tweet对象的列表:

public class UserSocialMedia extends User {

 private List<Tweet> tweets;



 // getters and setters

 }

在这里,我们的UserSocialMedia类是一个复杂域,也包含User域的属性。

4.4。 UserRepositoryImpl

现在,我们将升级UserRepositoryImpl类,以提供一个User域对像以及一条推文列表:

public class UserRepositoryImpl implements UserRepository {

 private UserDaoImpl userDaoImpl;

 private TweetDaoImpl tweetDaoImpl;



 @Override

 public User get(Long id) {

 UserSocialMedia user = (UserSocialMedia) userDaoImpl.read(id);



 List<Tweet> tweets = tweetDaoImpl.fetchTweets(user.getEmail());

 user.setTweets(tweets);



 return user;

 }

 }

在这里, UserRepositoryImpl使用提取用户数据UserDaoImpl使用和用户的鸣叫TweetDaoImpl.

然后,它将汇总这两组信息并提供UserSocialMedia类的域对象,该类对UserSocialMedia对于我们的业务用例非常方便。因此,repository依赖于DAO来访问来自各种来源的数据

同样,我们可以增强我们的User域,以保留Facebook帖子列表。

5.比较两种模式

现在,我们已经了解了DAO和repository模式的细微差别,让我们总结一下它们的区别:

  • DAO是数据持久性的抽象。但是,repository是对象集合的抽象
  • DAO是一个较低层的概念,更接近于存储系统。但是repository是一个更高级的概念,更接近于域对象
  • DAO充当数据映射/访问层,隐藏了难看的查询。但是,repository是域和数据访问层之间的一层,隐藏了整理数据和准备域对象的复杂性
  • DAO不能使用存储库来实现。但是,repository可以使用DAO访问基础存储

另外,如果我们有一个贫血域,则repository将只是DAO。

此外,repository模式鼓励域驱动的设计,也使非技术团队成员也容易理解数据结构

六,结论

在本文中,我们探讨了DAO和repository模式之间的差异。

首先,我们研究了DAO模式的基本实现。然后,我们看到了使用存储库模式的类似实现。

最后,我们研究了使用多个DAO的存储库,该存储库增强了域解决业务用例的能力。

因此,我们可以得出结论,当应用程序从以数据为中心转向面向业务时,存储库模式证明是一种更好的方法。

像往常一样,所有代码实现都可以在GitHub上获得

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *