Java 使用DAO模式的利弊
正如我在标题中提到的,我很想知道您(作为经验丰富的开发人员)对DAO模式的使用有何看法,特别是在web应用程序中。您发现了哪些优点,以及使用DAO的哪些后果是您不喜欢的?DAO模式的力量在于,它们允许您创建实际存储系统的良好抽象层。它们提供了一个更面向对象的持久层视图,并且在域和实际执行数据访问的代码(直接的JDBC、持久性框架、ORM甚至JPA)之间实现了清晰的分离 如果我必须指出一个弱点,那么,我会说这是另一层。。。但我想这是不将代码绑定到底层持久性API的代价。注意:您可能会发现其他缺点,但下面是我的经验中的一个快速列表 优点:Java 使用DAO模式的利弊,java,sql,web-applications,dao,architectural-patterns,Java,Sql,Web Applications,Dao,Architectural Patterns,正如我在标题中提到的,我很想知道您(作为经验丰富的开发人员)对DAO模式的使用有何看法,特别是在web应用程序中。您发现了哪些优点,以及使用DAO的哪些后果是您不喜欢的?DAO模式的力量在于,它们允许您创建实际存储系统的良好抽象层。它们提供了一个更面向对象的持久层视图,并且在域和实际执行数据访问的代码(直接的JDBC、持久性框架、ORM甚至JPA)之间实现了清晰的分离 如果我必须指出一个弱点,那么,我会说这是另一层。。。但我想这是不将代码绑定到底层持久性API的代价。注意:您可能会发现其他缺点,
- 检索对象的常见调用。
- 一旦有了常规创建/读取/更新/删除流集,就可以为其他DAO重复常规布局。
- 它还整合了代码中持久性特定部分的位置。 将业务逻辑与代码的其他组件分离。
- 这不是有史以来最灵活的事情。
- 如果要延迟加载某些子对象,则必须将DAO与其他层混合,或者在尝试检索延迟对象时采取预防措施。
- 如果您手工编写DAO,那么代码可能会变得乏味和重复。
- 实际数据库访问实现的抽象将数据访问策略与用户业务逻辑分离。这使我们能够为初始项目阶段选择一个短期(SpringJDBC模板)实现策略,并在以后选择迁移到IBATIS或Hibernate。(这是我们目前无法做出的选择。)
- 这种分离带来了显著的可测试性好处,因为可以在单元测试中模拟整个数据访问实现。(这可能是最大的好处)
- 结合Spring,我们可以将任何DB实现注入到我们选择的系统中(尽管这可能比DAO模式更能说明DI)
- DB表-对象属性映射的单点定义
- DAO实现对其他存储类型的透明可能性
- 开发DAO所遵循的接口模式
- 为DAO开发一个或多或少的标准JUnit测试类可以获得更好的测试覆盖率
- 完全控制细节
- 不会因过于通用的解决方案而导致性能损失
- 比使用最新的框架更不“性感”
- 开发人员无法发明自己的轮子(可能是专业人士:-)
- 您在考虑什么替代方案
很明显,将持久性的责任放在表示层之外的某个地方通常是好的,仅仅从责任的清晰性和重用的角度来看。我本能地选择了三层方法:表示、服务和持久性。坦白说,这么长时间以来我一直这样做,以至于我无法预测不这样做所带来的痛苦。在我看来,拥有一个理解持久性机制的单一层必须简化测试、简化维护并提供良好的关注点分离,这似乎是“显而易见的”
这就留下了一个问题,即到底如何做持久层。我的默认假设是使用JPA(或类似的框架)。我确实认为这是一个复杂的DAO示例
所以我看到了DAO的两个成本。首先,你需要投资于你的程序结构,它的设计。对于一些琐碎的案例,这可能会让人感觉有些过分。第二,如果您使用一个为您实现DAO的框架,那么会有一个学习曲线。与直接编写JDBC代码相比,这是另一项投资 我们已经看到了在实现中引入DAO模式的一些实际好处。这主要是由于数据库接口和实现之间的明确分离。我们观察到以下好处:
我们遇到的一个问题,这可能是由于我们缺乏清晰的设计,“倾向于”重用数据库中发布的数据值对象作为体系结构中后续抽象层之间的传输对象。经过一番努力之后,我们的解决方案是在每一层中都有一个值对象(即,不要在后续的体系结构层中重用数据库值对象)。Pro:抽象分离。
缺点:样板代码(感谢上帝提供了代码生成器/模板和ORM)。PRO
注意,根据您的情况,使用持久性框架可能是编写您自己的DAO的一个很好的替代方案。我所看到的DAO的问题是,它们通常总是处理完整的对象。这会产生完全不必要的开销,而这在简单查询中是不存在的。例如,如果要从数据库引用数据创建一个下拉列表,DAO用户可以简单地说:“获取该表的对象集合,其中y按z排序”。然后,该数据将在下拉列表中使用,但通常仅用于键/值组合,忽略检索和映射的对象中的所有其他内容(创建的数据、更新数据的最后用户、数据是否处于活动状态等)。即使此消息发生在DAO调用附近,并且对象在检索时不会被存储(通常为n)