Dao和Repository,你还傻傻分不清吗?

DAO到底有没有必要?

        贫血模型中的DAO或领域模型中的Repository到底有没有必要?有人认为DAO或者说Repository是充血模型的大敌,对此我无论如何也不赞同。DAO或Repository是负责持久化逻辑的,如果取消掉DAO或Repository,将持久化逻辑直接写入到model对象中,势必造成model对象承担不必要的职责。虽然现在的ORM框架已经做得很好了,持久化逻辑还是需要大量的代码,持久化逻辑的掺入会使model中的业务逻辑变得模糊。允许去掉DAO的一个必要条件就是Java的的持久化框架必须足够先进,持久化逻辑的引入不会干扰业务逻辑,我认为这在很长一段时间内将无法做到。在rails中能够将DAO去掉的原因就是rail中实现持久化逻辑的代码很简洁直观,这也与ruby的表达能力强有关系。DAO的另外一个好处隔离数据库,这可以支持多个数据库,甚至可以支持文件存储。基于DAO的这些优点,我认为,即使将来Java的持久化框架做得足够优秀,使用DAO将持久化逻辑从业务逻辑中分离开来还是十分必要的,况且它们本身就应该分离。

        争论的焦点到了DAO上,确实,实践中很多项目最终实施DDD的结果就是把所有的DAO重命名为Repository。但是我认为DAO和Repository很像,但是不是一个东西,因为它们出发点不同。

为什么要有DAO?
        因为之前,很早之前,我们对于框架中立性还很受用。DAO给了我们可以随时把Hibernate换成ibatis的幻觉,所以我们要有一个地方隔离了框架。
        而且DAO集中了所有的查询,方便了性能调优人员。同时也鼓励了查询的重用,同样方便了调优。

为什么要有Repository?
        在我看来,与其说Publication Repository,不如说Publications。Repository是一个集合对象,它封装了集合的逻辑。因为它具有封装性,所以它应该负责保持这个集合的状态,比如拒绝一些非法的的修改。Repository的入口是聚合根。

Java代码 

  1. class PublicationRepository {  
  2.   public void save(Publication pub) {  
  3.    if (hasSameName(pub)) {  
  4.      throw new InvalidPublicationException();  
  5.    }  
  6.    dao.save(pub);  
  7.   }  
  8. }  


        另外,Repository只应该负责Aggregate Root。对于被Aggregate的对象,应该用Navigation,也就是在关系之间游走来获取。所以不是所有的查询都必须由Repository来完成,比如说:

Java代码 

  1. class Contact {  
  2.   private List<ContactNote> contactNotes = new ArrayList<ContactNote>();  
  3.   public void contactedBy(User accountManager, DateTime time){  
  4.     ContactNote contactNote = new ContactNote(this, accountManager, time);  
  5.     if (isDuplicated(contactNote)) {  
  6.       throw new InvalidContactNote();  
  7.     }  
  8.     contactNotes.add(contactNote);  
  9.   }  
  10.   private boolean isDuplicated(ContactNote contactNote) {  
  11.     // 查询contactNotes  
  12.     return xxx;  
  13.   }  
  14. }  


        现状是,对象之间的关联不可查询导致了,很多这样的查询必须通过xxxDao,xxxRepository来完成。其实它们都不应该插手。

        理想情况下,只有业务开始的时候用repository加载对象,在结束的时候用repository把对象存储回去,中间都是领域对象在互相作用。而DAO,可以以Generic Query Builder的形式存在,不过和它之前被发明出来的意图已经不是一个东西了。

        DAO原本的作用就是隔离数据库的影响,没有业务逻辑。而Repository更抽象,从概念上来说是一个可以全局访问的集合,从这个意义上来讲对你所举Publication Repository,使用add(Publication pub)作为方法签名要更好一些。Repository也负责保持完整对象的完整性,PublicationRepository的例子也说明了这一点,另外一个例子,但从数据库重建一个对象时,由于外部原因,对象已经变得不完整,将它恢复为一个完整的对象或者直接抛异常也是Repostory的责任,它可以将这种保证对象完整性的责任委托给别的对象(如Factory)。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Repository层和DAO的区别在于,Repository层是Spring框架中的一种设计模式,它是对DAO层的进一步封装和抽象,提供了更高层次的抽象和更加灵活的查询方式,同时也可以与其他框架集成。而DAO层则是数据访问层,主要负责与数据库进行交互,进行数据的增删改查等操作。因此,Repository层更加注重业务逻辑的处理和数据的封装,而DAO层则更加注重数据的访问和操作。 ### 回答2: Repository层和DAO(Data Access Object)在软件开发领域被广泛运用,是持久化层的两个概念。它们的主要区别在于: 1. 设计层面:DAO与具体的数据源进行交互,可以理解为对数据源的封装,同时负责数据访问和数据持久化的任务。而Repository层则更加高层抽象,不仅要负责对数据源的操作,还要对操作结果进行解释和加工,是对DAO层的进一步封装。 2. 对象层面:在设计模式上,DAO层通常为实体类提供单纯的数据访问,而在Repository层中实体类的处理则更加复杂,包括实体类与其他模型之间的转换等。 3. 维护层面:在Repository层中,可以通过重写方法、缓存等方法提高代码的复用性,这样就不需要在DAO层中管理重复代码的复杂性。同时在对于实体类的维护,也更加具有优越性。 综上所述,虽然DAORepository层都是持久化层的两个概念,但是它们在设计、实现、维护等方面都存在很大的差异。DAO层主要负责对应数据源的CURD操作,它更加偏向于数据访问和持久化。而Repository层则更加注重领域对象的逻辑操作,给予了更高层的抽象和更多的功能,扩展了对于软件面向对象的处理能力,但是Repository层的复杂性更高,需要在实际设计中结合项目的特点和开发人员的经验进行选择。 ### 回答3: Repository层和Dao层是很多应用程序中常用的两种设计模式,在由Java语言开发的Web应用程序中,他们主要用来处理数据持久层和数据库操作。 Repo是Repository的缩写,是指存储库。Repository层是一种抽象的接口层,负责数据持久化存储和查询,承担了所有的与数据存储相关的工作,也是应用程序与持久化框架之间的中间件。它对上层提供统一的接口方法,封装了Dao层,而内部实现则可以采用不同的框架(如MyBatis和Hibernate)。 Dao是Data Access Object的缩写,直译为数据访问对象,他的主要任务是封装数据库的访问,Dao对象提供了一系列的接口,用于对数据的增、删、改、查等操作。Dao层对于上层提供了一种对数据的存储和查询的持久化方法的抽象,但和Repository层不同的是,Dao着重于数据访问的实现,而不是业务逻辑的处理。 Repository层是面向领域模型的,它关注整个领域的需求,而不是单一的数据库操作,通过统一接口、多种实现的方式,将增删改查等数据访问方法封装在一个类中,从而调用起来更加方便,更加规范。一般而言,Repository是同时面向服务层和持久层的。 而Dao层专注于对数据的访问操作,它具有更加细粒度的操作,适用于面向更多的特定需求和数据访问的需求。Dao与JDBC非常类似,它们都是对数据层的操作进行抽象,Dao层将JDBC数据处理的功能封装为一个实现通用数据访问接口的类,屏蔽了数据访问细节,Facade层可以调用Dao层做数据访问,而无需直接操作JDBC。 综上所述,Repository层和Dao层都是数据持久化的方法,二者的区别在于,Repository层是对Dao层的进一步封装,用来将不同的数据源拼合成一个大的Repository接口,并且为其提供统一的接口方式,而Dao层则是对数据的访问和操作的抽象。个人认为,在设计应用程序时,应该根据具体的需求,选择不同的持久层接口,因此在开发过程中,RepositoryDao都有自己适用的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值