Java 道与服务?

Java 道与服务?,java,spring,dao,Java,Spring,Dao,我总是面临这样一个问题:我无法真正想到服务对象封装了许多DAO方法 我的意思是,对于我的servlet,有时使用单个DAO方法就足够了,例如addUser(User params) 更好的做法是——用服务对象封装DAO方法,并始终只使用服务对象,即使这实际上意味着单个服务方法调用单个DAO方法或将它们的使用混合在一起(一些方法来自服务对象,一些方法来自servlet上下文中的DAO)-这意味着我在控制器中有自动连接的DAO和服务对象 如果我开始在同一个地方同时使用DAO和服务对象,它会混淆逻辑?

我总是面临这样一个问题:我无法真正想到服务对象封装了许多DAO方法

我的意思是,对于我的servlet,有时使用单个DAO方法就足够了,例如addUser(User params)

更好的做法是——用服务对象封装DAO方法,并始终只使用服务对象,即使这实际上意味着单个服务方法调用单个DAO方法或将它们的使用混合在一起(一些方法来自服务对象,一些方法来自servlet上下文中的DAO)-这意味着我在控制器中有自动连接的DAO和服务对象


如果我开始在同一个地方同时使用DAO和服务对象,它会混淆逻辑?

我认为这取决于具体情况。如果没有DAO会导致混合业务逻辑和数据访问逻辑,那么最好使用单独的类

但是,如果您的DAO是“虚拟”的,并且只调用EntityManager方法,那么您可能可以在服务对象中直接使用它。这样做的目的是让类具有并且易于扩展和测试。你不应该为了它而创建图层


如果您想保持一个可重用的服务层,我可能不会直接从您的控制器使用DAO。如果DAO没有意义,我宁愿在服务层使用EntityManager(或您正在使用的任何持久性策略)。

我个人通常在服务中封装DAO调用

这允许我使用AOP/etc使所有服务都具有事务性,并在这些服务中使用非事务性DAO方法


对于琐碎的服务,这是一个额外的“层”,但IMO提供了一个用途(并且可以使用某种类型的代码生成来生成它)。不过,我很少在服务中只包含DAO功能。

我使用的系统在某一点上采用了“控制器不能与DAO交互!”的设计理念,并为每个组件创建了服务层。正如您所描述的,大多数服务只是简单地委托给DAO。我反对这种哲学有两个原因

一个是古老的“你不需要它”。除非你需要,否则不要实施。仅仅因为你预见到了一些原因,需要一个额外的间接层来做一些额外的逻辑,所以你不确定你是否需要它。当你最终需要它时,你可能会发现你的期望与你之前所相信的并不相符。您将获得额外的成本,因为现在您必须对两个类而不是一个进行单元测试,而且您需要在两个位置而不是一个位置添加方法的情况并不少见

第二个问题是,到底什么是服务?当我为我的领域建模时,我试着用面向对象的术语来思考。存在用户,因此用户类是有意义的。存在新闻项,因此NewsItem类是有意义的。但我甚至不知道用户服务应该做什么。是否包含用户的“业务逻辑”?不,这就是用户类的用途


如果您需要对“外部世界”维护一个严格的API,那么我可以看到有一个保持不变的额外层。但在所有其他情况下,您都不需要它。

视情况而定。分离DAO和服务层的原因通常是:

  • 技术约束(参见其他答案中的AOP事务)
  • 体系结构约束(服务层和DAO之间的DTOs@Entities转换)
  • 历史(X年来就是这样做的)
  • 美观(仅从视图层访问一个层)
使用Java EE 6(JBoss AS 7),我没有这些负担:

  • 没有AOP-@无状态和@Transactional处理事务
  • 没有DTO-我使用从JPA到视图层的@Entities
  • 不在乎历史
  • 与美学相比,我更喜欢简洁/更少的代码
所以我有DAO层中的大多数方法。 对于某些情况,更复杂的操作,我创建一个服务bean,并可能使用一个

我的经验法则是,方法是否应该进入服务bean:

  • 如果它使用多个DAO(显然)
  • 如果它执行多个实体管理器调用
  • 如果实现可能会改变,例如,在JPQL中完成搜索与Hibernate搜索与ElasticSearch

  • 如果它是虚拟的,你是什么意思?我想应该是这样的?DAO必须尽可能简单和虚拟?如果您制作了复杂的DAO,那么很可能您已经将内部的业务逻辑弄混了?如果您有一个DAO,它只调用EntityManager的方法,那么您为什么需要这个DAO?为什么不直接使用EntityManager?例如,如果我想使用criteria API构建一个查询,我会使用DAO,这可能需要很多行,我不想与我的业务逻辑混淆。我感觉我在谈论不同的事情,我正在考虑这样一个案例:我们有DAO,它有一些访问db的方法。我们有服务对象单一方法,它只使用来自这个DAO的单一方法来执行它的工作。当我们可以直接使用DAO方法时,在服务对象中创建只使用单个DAO方法的单个方法是否可行。你说的是同一件事吗?我有很多“EntityManager”方法。我想我们谈论的是同一件事:)我仍然不喜欢直接从控制器调用DAO的想法(这就是我所理解的)。我宁愿从服务中使用EntityManager,而不是将DAO公开给上层。是的,没错!我需要检查一下。:-)您的问题:“为什么需要DAO?”因为EntityManager使用DAO方法?你的实体经理是什么?(我还没有使用ORM框架,我对设计模式不是很熟悉,是不是来自这些领域?)。按照您的逻辑,应该首先从servlet而不是ha触发查询