5

我正在阅读有关 EJB 3.0 的这篇文章,其中作者描述了一种架构,其中服务层通过实现为无状态会话 bean 的 DAO 与实体对话。

我试图理解为什么我们需要这个附加层。为什么服务层不能直接与实体对话?我想到的一个想法是 - 易于测试。我们可以通过模拟 DAO 轻松测试服务层。

这是唯一的原因,还是还有其他原因?

4

3 回答 3

4

这个想法是将业务逻辑(或服务层)与实际的持久性策略解耦。例如,您的实体可以存储在平面文件或数据库中。您应该能够在不影响业务层的情况下更改此持久性策略。

服务层通过 DAO 与实体对话

这句话有点模棱两可。在 EJB 3.0 中,业务实体是 POJO。业务层可以使用它们,数据访问层也可以使用它们。业务层直接与业务实体“对话”。但它也与数据访问层对话。数据访问层主要负责加载和保存实体。

交易分界是另一个需要处理的问题。在 EJB 3.0 中,业务层独立于所选的持久性策略来划分事务。数据访问层和业务实体应该执行业务层的事务。

我们可以通过模拟 DAO 轻松测试服务层。

是的。可以使用模拟数据访问层来测试业务层。数据访问层可以在没有业务层的情况下进行测试。同样,这很容易,因为业务实体是任何层都可以使用的 POJO。数据访问层所需的信息是通过注解提供的,注解与业务层无关,但不会从业务角度对业务实体的建模施加约束。

于 2012-04-10T08:44:45.100 回答
2

DAO是关于如何使用对象访问数据库的抽象。在 DAO 的原始实践中,首先有一个接口定义了您期望从数据库中获得的操作:

interface ModelDao {
  Model load(Long id);
  Long save(Model object);
}

可以是通用的,也可以以任何适合您设计的方式使用。除了接口的高度可测试性之外,DAO 模式还增加了另一个优势,即现在您可以使用不同的技术实现相同的 DAO 模式。随着时间的推移,您可能需要从 EJB 切换到 Spring JDBC 或任何其他更改

虽然这一切都发生了,但服务层仍然只能通过DAO 接口看到数据层。实现总是从服务层封装的。此外,它还通过mocking等机制增加了服务层的可测试性

如果服务层直接开始处理数据层,这意味着服务层变得特定于实现,这降低了模块化和关注点的耦合,除了使仅针对业务逻辑测试服务层变得更加困难之外。

最后但同样重要的是,虽然坚持最初的做法总是最好的,但这取决于你的产品/项目的规模和意图来采用这种方法。

于 2012-04-10T09:03:18.353 回答
1

我想到的一个想法是 - 易于测试

不,这不仅仅是为了便于测试 DAO 层。在这种情况下,DAO 的目的是分离关注点。

@ewernli 和 @nobeh 已经解释了 DAO 层等的目的。我想补充一下,这是解决问题的方法之一。而是在 Java 世界中,这种使用显式 DAO 层的方法已经存在了很长一段时间。有可以实现的替代方法。以 Ruby/RoR 世界中的ActiveRecord为例。

为什么服务层不能直接与实体对话?

是的,您可以设计您的应用程序,使服务层直接与实体对话。有一些人反对使用 DAO 并建议使用领域驱动设计

我个人对拥有不同层持久性的整个想法的看法有点烦人。在您指出的方法中,实体仅充当数据结构或 blob 来存储信息(getter 和 setter)。大多数时候,它们不添加业务逻辑。

于 2012-04-10T09:05:55.793 回答