使用DAO模式的利弊

正如我在标题中提到的,我很想知道你(经验丰富的开发人员)对DAO模式的使用有何看法,特别是在Web应用程序中。 你发现了什么样的优势以及它的使用带来了什么后果?

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

现在,这并不是说DAO不能被设计为检索参考数据的映射 – 它当然可以。 但通常它们用于完整的对象映射,这不是一直需要的。 保存时它是一种优势,但IMO在检索数据时是一个弱点 – 当然,你得到所有这些 – 但通常你不需要全部,而且它只会浪费内存,带宽和时间。

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

优点:

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

缺点:

  • 它不是最灵活的东西。
  • 如果您想延迟加载一些子对象,那么您将不得不将DAO与其他层混合或在尝试检索惰性对象时采取预防措施。
  • 如果您手写DAO,那么代码可能会变得乏味和重复。

使用DAO设计模式的好处

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

在此处输入图像描述

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

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

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

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

如果我不得不引用一个弱点,那么,我会说它是另一层…但我想这是为了不将代码绑定到底层持久性API而付出的代价。

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

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

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

PRO

  • DB表的单点定义 – 对象属性映射
  • DAO实现到其他存储类型的透明可能性
  • 开发所有DAO遵循的界面模式
  • 为DAO开发一个或多或少的标准JUnit测试类可以获得更好的测试覆盖率
  • 完全控制细节
  • 由于过于通用的解决方案而没有性能损失

CON

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

与大多数开发模式一样,使用DAO需要一些时间来习惯。 随着经验的到来,更强大的代码和开发人员可以了解事情的原因,而不仅仅是看起来如此。 最后一点对我来说是最大的优势。

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

您还在考虑哪种替代方案?

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

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

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

亲:抽象分离。
Con:样板代码(感谢上帝代码生成器/模板和ORM)。

Interesting Posts