26

正如我在标题中提到的,我很想知道您(作为经验丰富的开发人员)对使用 DAO 模式的看法,特别是在 Web 应用程序中。您发现了哪些优势,您不喜欢使用它的哪些后果?

4

8 回答 8

26

我看到的 DAO 的问题是它们通常一直处理完整的对象。这会产生完全不需要的开销,而简单查询则不存在这些开销。例如,如果要根据数据库引用数据创建下拉列表,DAO 用户可能会简单地说:“给我获取此表的对象集合,其中 y 按 z 排序”。然后,该数据在下拉列表中使用,但通常仅用于键/值组合,忽略检索和映射的对象中的所有其他内容(创建的数据、最后更新它的用户、它是否处于活动状态等) . 即使这种按摩发生在 DAO 调用附近,并且对象在检索时没有被存储(通常情况并非如此,不幸的是,对象通常被包装在 ac:forEach (JSP) 中并迭代以产生下拉),

现在,这并不是说不能将 DAO 设计为检索参考数据的 Map - 它当然可以。但通常它们用于完整的对象映射,这并不是一直需要的。保存时这是一种优势,但在检索数据时,IMO 是一种劣势——当然,你得到了所有的数据——但通常你并不需要所有的数据,它只会浪费内存、带宽和时间。

于 2009-11-17T14:48:23.893 回答
14

注意:您可能会发现其他缺点,但这里是我的经验的快速列表

优点:

  • 检索对象的常用调用。
  • 一旦你设置了通用的创建/读取/更新/删除流程,就可以为其他 DAO 重复通用布局。
  • 它还整合了代码的持久性特定部分可以去哪里。将业务逻辑与代码的其他组件分开。

缺点:

  • 这不是有史以来最灵活的事情。
  • 如果您想延迟加载一些子对象,那么您将不得不将 DAO 与其他层混合,或者在尝试检索延迟对象时采取预防措施。
  • 如果您手写 DAO,那么代码可能会变得乏味和重复。
于 2009-11-17T11:41:34.530 回答
7

使用 DAO 设计模式的好处

DAO 或数据访问对象设计模式是抽象和封装面向对象原则的一个很好的例子。它分离持久性逻辑是一个单独的层,称为数据访问层,它使应用程序能够安全地对持久性机制的变化做出反应。例如,如果您从基于文件的持久性机制转移到数据库,您的更改将仅限于数据访问层,不会影响服务层或域对象。数据访问对象或 DAO 模式在 Java 应用程序中几乎是标准的,无论是核心 Java、Web 应用程序还是企业应用程序。以下是在 Java 应用程序中使用 DAO 模式的更多好处:

在此处输入图像描述

  1. DAO 设计模式还保持应用程序不同部分之间的低耦合。通过使用 DAO 设计模式,您的视图层完全独立于 DAO 层,只有服务层对其具有依赖关系,这也是通过使用 DAO 接口抽象出来的。

  2. DAO 设计模式允许 JUnit 测试运行得更快,因为它允许创建 Mock 并避免连接到数据库来运行测试。它改进了测试,因为使用 Mock 对象编写测试很容易,而不是使用数据库进行集成测试。在任何问题的情况下,在运行单元测试时,您只需要检查代码而不是数据库。还可以屏蔽数据库连接和环境问题。

  3. 由于DAO模式是基于接口的,它还提倡面向对象的设计原则“为接口编程而不是实现”,从而产生灵活和高质量的代码。

于 2016-03-02T11:04:11.103 回答
4

DAO 模式的力量在于它们允许您为实际存储系统创建一个很好的抽象层。它们提供了一个更加面向对象的持久层视图,并在域和实际执行数据访问的代码(直接 JDBC、持久性框架、ORM 甚至 JPA)之间进行了清晰的分离。

如果我不得不引用一个弱点,好吧,我会说它是另一层......但我想这是不将你的代码绑定到底层持久性 API 所付出的代价。

于 2009-11-17T11:38:01.507 回答
3

我们已经看到了将 DAO 模式引入我们的实现的一些真正好处。这主要是由于数据库接口和实现之间的明确分离。我们观察到以下好处:

  • 实际数据库访问实现的抽象将数据访问策略与用户业务逻辑分开。这使我们能够为初始项目阶段选择短期(Spring JDBC 模板)实施策略,并可以选择在以后迁移到 IBATIS 或 Hibernate。(我们目前无法做出选择。)
  • 这种分离引入了显着的可测试性优势,因为可以在单元测试中模拟整个数据访问实现。(这可能是最大的好处)
  • 将它与 Spring 结合起来,我们可以将任何 DB 实现注入到我们选择的系统中(尽管这可能更多地说明了 DI 而不是 DAO 模式)。

我们遇到的一个问题,这可能是由于我们缺乏清晰的设计,是“倾向于”重用从数据库发布的数据值对象作为架构中后续抽象层之间的传输对象。经过一些痛苦后,我们的解决方案是每层都有一个值对象(即不在后续架构层中重用数据库值对象)。

于 2009-11-17T11:59:14.207 回答
2

你在考虑什么替代方案?

似乎很明显,将持久性责任放在表示层以外的地方通常是好的,仅从责任清晰和重用的论点来看。我本能地采用三层方法:演示、服务、持久性。承认我已经这样做了很长时间,以至于我无法举出不这样做所遭受的痛苦的证据。对我来说,拥有一个理解持久性机制的单层必须简化测试、简化维护并提供良好的关注点分离,这似乎是“显而易见的”。

所以这就留下了如何做持久层的问题。我的默认假设是使用 JPA(或类似框架)。我确实认为这是 DAO 的一个复杂示例。

所以我看到了 DAO 的两个成本。首先你需要投资你的程序结构,它的设计。对于琐碎的情况,这可能感觉有点矫枉过正。其次,如果您使用为您实现 DAO 的框架,则存在学习曲线。与直接编写 JDBC 代码相比,这是另一项投资。

于 2009-11-17T11:56:27.657 回答
2

优点:抽象分离。
缺点:样板代码(感谢上帝提供代码生成器/模板和 ORM)。

于 2009-11-17T11:59:22.770 回答
2

专业版

  • 数据库表的单点定义 - 对象属性映射
  • DAO 实现对其他存储类型的透明可能性
  • 开发一个所有DAO都遵循的接口模式
  • 为 DAO 开发一个或多或少标准的 JUnit 测试类,以提高测试覆盖率
  • 完全控制细节
  • 没有由于过于通用的解决方案而导致性能损失

CON

  • 比使用最新框架更“性感”
  • 开发人员无法发明自己的轮子(可能是 PRO :-))

与大多数开发模式一样,使用 DAO 需要一些时间来适应。经验带来了更健壮的代码和知道事情为什么工作的开发人员的好处,而不仅仅是看起来如此。最后一点对我来说是最大的优势。

警告,根据您的情况,使用持久性框架可能是编写自己的 DAO 的一个很好的替代方案。

于 2009-11-17T12:03:23.000 回答