创建服务层和DAO层(接口+实现)或仅实现

Posted

技术标签:

【中文标题】创建服务层和DAO层(接口+实现)或仅实现【英文标题】:Creating Service layer and DAO layer (interface+implementation) or implementation only 【发布时间】:2011-12-28 14:36:47 【问题描述】:

我对创建service层和DAO层的结构感到困惑: 在某些示例中,我看到有些人为服务和 DAO 创建 interface+implementation,而在其他示例中,我看到人们在 DAO 扩展 AbstractDao 时创建 implementation only 类包含这些 DAO 的 通用方法,所以我很困惑要做什么,为什么要选择这个解决方案或另一个解决方案,以及最佳实践是什么(常用) 请指教。

【问题讨论】:

【参考方案1】:

我建议为服务和 DAO 创建接口。很多时候,您想在使用此服务的代码的单元测试中模拟服务。 例如,当您使用某些 Spring 代理(例如用于事务)时,Spring 也会强制您使用接口。所以你应该有一个服务接口。

DAO 更多是内部部分,但我总是尝试为它们使用接口来简化测试。

【讨论】:

请您提供更多详细信息,包括示例和参考资料,因为我需要方便一些同事。【参考方案2】:

我更喜欢接口+实现,原因如下:

接口变成合同:它们告诉您可以调用什么,只要结果符合预期,您就不必担心其实现。 您可以创建接口的可自定义实现而不破坏同一接口的其他实现(通常在编写单元测试时很有用)。自定义仅实现的类可能会带来比您容易注意到的更多错误。 它创建了一个可以记录的框架。

实现的子类用于创建符合接口契约的业务/应用程序逻辑。

【讨论】:

如果 DAO 扩展了包含用于 CRUD 操作的通用方法的 BasicDao,那么接口会很重要,因为我可以覆盖 BasicDao 中的通用方法吗? 您可以覆盖该方法,但方法签名将是相同的。本质上,用户不会知道该方法是子类的,而是只对从 Service/DAO 返回的数据感兴趣。 所以如果使用带有DAO的通用AbstractDao类,最好也使用接口。 最好。有些人在 Cassandra 表上使用 DAO,这根本不需要任何数据库连接(例如 Thrift 连接)。接口“隐藏”了所有这些无关紧要的东西。【参考方案3】:

我只完成了服务层的实现,没有打扰接口(除非我必须这样做)。我可能应该开始编写接口,但到目前为止没有问题。我在没有模拟服务层的情况下进行单元测试。

另外,我没有 DAO 层,因为我使用的是 hibernate,这似乎有点矫枉过正。我的很多推理都是基于这个博客,eloquently written by Bozho。

我认为是quite debatable(是否有 DAO 和休眠),但是我对我的决定很满意,我传入厚域对象,然后调用休眠会话。 dao 层上的每个方法实际上只有一行(session.persist(mObject) 或类似的)。

我听到的一个反对意见是,dao 层可以让以后更容易更改/删除 orm。我不确定是否首先花费在对 dao 层进行编码的时间加上对更改进行编码的时间,是否会少于在没有 dao 层的情况下单独对更改进行编码。我从来没有在我工作过的任何地方改变 ORM 技术,所以风险很小。

【讨论】:

所以你直接使用服务层里面的hibernate方法? 我也会这样做。从实现开始,并在出现多个实现时引入接口。但是,如果一开始服务应该对许多客户端可见-那么接口引入似乎是合理的。【参考方案4】:

从我的角度来看,当您说 Service 时,您应该有接口,如果您不能提供或不会提供,那么您就没有服务和消费者之间的合同,它不再是服务,你可以叫它任何东西

【讨论】:

【参考方案5】:

使用接口+实现是为了实现松耦合。您可以灵活地轻松更改或切换实现,而无需对代码进行重大更改。

想一想您使用 Hibernate 进行持久性(DAO 层)的场景,您需要为此切换到 JPA 或 iBatis 或任何其他 ORM。

如果您使用接口,您可以简单地编写一个特定于 JPA 的实现并“插入”它来代替 Hibernate。服务代码保持不变。

【讨论】:

如果我使用一个包含用于 CRUD 操作的通用方法的 AbstractDao 并且所有 DAO 都扩展了 AbstractDao 我猜这比使用 daos 接口就足够了,或者我需要扩展 BasicDao并同时实现接口?【参考方案6】:

interface+implementation 模型的另一个论点是,Java 本身支持接口的代理,而为实现创建代理需要使用诸如 cglib 之类的库。并且这个代理对于事务支持等是必要的。

【讨论】:

【参考方案7】:

查看我关于“fastcode”的帖子,这是一个 eclipse-spring 插件,可从您的 DAO 生成服务层。奇迹般有效。 generate service /dao layer for GWT/Spring/Hibernate/PostgreSQL

【讨论】:

以上是关于创建服务层和DAO层(接口+实现)或仅实现的主要内容,如果未能解决你的问题,请参考以下文章

DAO层Service层Controller层和view层

微服务迁移记:公共层接口层和实现层搭建

泛型 Dao、服务层和多个匹配的 bean

DAO 层应该如何实现?一张表 DAO 还是多表 DAO?

Service层和Controller层的开发

服务层和 dao 层中的事务性