数据访问对象(DAO)和存储库模式之间的区别是什么?我正在开发一个应用程序,使用企业Java bean (EJB3), Hibernate ORM作为基础设施,领域驱动设计(DDD)和测试驱动开发(TDD)作为设计技术。


当前回答

存储库是更抽象的面向领域的术语,是领域驱动设计的一部分,它是领域设计的一部分,是一种公共语言,DAO是数据访问技术的技术抽象,存储库只关心管理现有数据和创建数据的工厂。

查看这些链接:

http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html

其他回答

DAO和存储库模式是实现数据访问层(DAL)的方法。让我们先从DAL开始。

访问数据库的面向对象应用程序必须具有处理数据库访问的逻辑。为了保持代码的简洁和模块化,建议将数据库访问逻辑隔离到单独的模块中。在分层体系结构中,这个模块就是DAL。

到目前为止,我们还没有讨论任何特定的实现:只讨论了将数据库访问逻辑放在单独模块中的一般原则。

现在,我们如何实现这个原则呢?实现这一点的一种已知方法是DAO模式,特别是使用Hibernate这样的框架。

DAO模式是一种生成DAL的方式,通常每个域实体都有自己的DAO。例如,User和UserDao, Appointment和AppointmentDao等。使用Hibernate的DAO示例:http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html。

那么什么是存储库模式?与DAO一样,Repository模式也是实现DAL的一种方式。Repository模式的主要观点是,从客户端/用户的角度来看,它应该看起来或行为像一个集合。行为像一个集合的意思并不是说它必须像collection collection = new SomeCollection()这样实例化。相反,它意味着它应该支持添加、删除、包含等操作。这就是Repository模式的精髓。

在实践中,例如在使用Hibernate的情况下,Repository模式是用DAO实现的。也就是说,一个DAL实例可以同时是DAO模式和Repository模式的实例。

存储库模式不一定是在DAO之上构建的(有些人可能会这样建议)。如果dao被设计为支持上述操作的接口,那么它就是Repository模式的实例。想想看,如果dao已经提供了一组类似于集合的操作,那么为什么还需要在上面再加一个层呢?

DAO是数据持久性的抽象。 存储库是对象集合的抽象。

DAO被认为更接近数据库,通常以表为中心。 存储库将被认为更接近域,只处理聚合根。

存储库可以使用DAO来实现,但您不会做相反的事情。

另外,Repository通常是一个更窄的接口。它应该是一个简单的对象集合,包含Get(id)、Find(isspec)、Add(Entity)。

像Update这样的方法适用于DAO,但不适用于Repository——当使用Repository时,对实体的更改通常由单独的UnitOfWork跟踪。

被称为Repository的实现实际上更像是一个DAO,这似乎很常见,因此我认为它们之间的区别存在一些混淆。

如果我们考虑设计模式DAO和Repository的原始定义,就会发现它们非常相似。主要的区别是字典和它们的来源(Oracle vs. Fowler)。

引用:

DAO - "separates a data resource's client interface from its data access mechanisms" and "The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets." Repository - "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." and "Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."

基于这些引用,这两种设计模式都调解了领域层和数据层之间的通信。此外,Repository与ORM相关联,而DAO则是用于从任何地方访问数据的更通用的接口。

dao可能并不总是显式地与Only DataBase相关,

它可以只是一个访问数据的接口,在这种情况下,数据可以从DB/Cache甚至REST(现在不太常见,因为我们可以很容易地在各自的REST /IPC客户端中分离它们)访问。

这种方法中的回购可以由任何ORM解决方案实现,如果底层缓存/回购发生变化,它不会被传播/影响服务/业务层。

dao可以接受/返回域类型。考虑一个学生域,关联的DAO类将是StudentDao

StudentDao {

    StudentRepository, 
    StudentCache, 

    Optional<Student> getStudent(Id){

       // Use StudentRepository/StudentCache to Talk to DD & Cache 
       // Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
   
    }

    Student updateStudent(Student){

       // Use StudentRepository/StudentCache to Talk to DD & Cache 
       // Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
   
    }

}

dao可以接受/返回子域类型。考虑一个学生域,它有子域,比如考勤/科目,它有一个DAO类StudentDao,

StudentDao {

    StudentRepository, SubjectRepository, AttendanceRepository
    StudentCache, SubjectCache, AttendanceCache

    Set<Subject> getStudentSubject(Id){

       // Use SubjectRepository/SubjectCache to Talk to DD & Cache 
       
    }

    Student addNewSubjectToStudent(ID, Subject){

       // Use SubjectRepository/SubjectCache to Talk to DD & Cache 
      
   
    }

}

DAO提供了对数据库/数据文件或任何其他持久性机制的抽象,因此,持久性层可以在不知道其实现细节的情况下进行操作。

而在Repository类中,可以在单个Repository方法中使用多个DAO类来从“应用程序角度”完成操作。因此,与其在域层使用多个DAO,不如使用存储库来完成它。 存储库是一个层,它可能包含一些应用逻辑,例如:如果数据在内存缓存中可用,那么从缓存中获取它,否则,从网络中获取数据并将其存储在内存缓存中,以便下次检索。