Service 和 DAO 之间的关系应该是一对一还是一对多?
Posted
技术标签:
【中文标题】Service 和 DAO 之间的关系应该是一对一还是一对多?【英文标题】:Should the relationship between a Service and DAO be one to one or one to many? 【发布时间】:2011-06-14 21:28:56 【问题描述】:引发这个问题的代码是我公司代码库中的一个服务,其中包含四个不同的 DAO。直到我看到这个服务已经与属于一个完全不同的服务的方法混为一谈,我才想太多。在这个 Service 中创建这些无根据的方法的原因仅仅是因为所需的 DAO 是这个 Service 类的私有成员。
这是开发人员的不当行为,还是在大多数情况下每个服务类拥有多个 DAO 是错误的?
注意:我注意到每个服务类拥有多个 DAO 似乎是合理的,只要它们都包含在同一个数据库中。但是拥有来自多个数据库的 DAO 似乎可能会导致问题。
【问题讨论】:
【参考方案1】:我认为每个服务类有多个 DAO 没有错。多年前我第一次开始做 Web 开发时,我有一个服务一个 DAO,因为这似乎是最合乎逻辑和最直接的方法。然后,我开始看到提供不同服务的 DAO 之间存在类似 API 的问题。因此,我的“不成熟”解决方案是将这些通用 API 推广到某些父 DAO 以由这些 DAO 继承。随着项目的发展,继承已经到了没有任何意义的地步,因为在我的情况下,80% 的子 DAO 需要该 API,但 20% 不需要,但它们仍然从同一个父级继承DAO,因为它们共享其他类似的 API。你看到这里的问题了吗?我的意思是,在Java中,你只能从一个父级继承,所以我最终在父级DAO中填充了“可能”被“大多数”DAO使用的API,这首先完全违反了继承原则。
现在,我所有的 DAO 类都有特定的职责/任务。一个 DAO 可以调用另一个 DAO(例如,大多数 DAO 使用 LoggingDAO 来记录用户操作)。通过这种方式,DAO 不再提供一个服务于特定服务的 DAO,而是提供了可能使该服务受益的操作列表。服务将“使用”任何 DAO 来完成任务。
希望这个解释有所帮助。
【讨论】:
确实如此。就我而言,我认为我正在处理开发人员的不当行为,即人们根据其 DAO 字段而不是基于服务的意图将东西推入服务中。 啊,继承和子类型多态性的问题......抛开这些,很好的轶事;-) 在我看来,Service 提供了一组特定的服务来处理一些用户操作。这些服务可能会也可能不会使用 DAO 来完成工作。另一方面,DAO 提供 Service 和数据库之间的通信,但它不应该知道用户请求的全部内容。如果开发人员将这两者混合在一起,那么我认为拥有服务和 DAO 没有意义,因为您可以将它们全部组合在一起,这非常糟糕,因为您无法重用大量代码。 :) @pst:继承对我来说曾经是最无聊的事情,直到事情失控。这个故事的寓意是尽可能选择组合而不是继承,它也使单元测试变得更加容易。 :) 网上一个人的看法:EntityManager 接口本身是处理持久层的完美抽象。绝大多数与已经抽象的 EM 冗余的“DAO”只是阻塞了许多应用程序,只是“我们的应用程序具有良好的分层架构,就像书中所说的那样”温暖模糊 :)【参考方案2】:只要拆分 DAO 有意义,一对多就可以了。
我能想到拆分 DAO 的几个原因:
不同的数据库。如果您正在处理一个帐户和一个销售数据库,您可能希望将 DAO 分成一个 SalesDAO 和一个 AccountingDAO。这将使维护更容易。 重复使用。您可能有一些方法可以在多个地方重复使用,将它们分开可以更好地重复使用。【讨论】:
【参考方案3】:在我工作的一家公司,他们有一个很好的设计,服务称为控制器,控制器可以调用另一层,我不记得了,但那会调用 DAO。
所以,他们有一个可以调用多个 DAO 的访问级别,以便执行更高阶的功能,因此,如果您要执行命令,可能需要调用多个表,并且可能需要调用多个系统,所以控制器会调用doOrder
方法。
这是一个不错的设计,因为它保持了良好的分离感,并使单元测试更简单,因为您可以测试每一层。
如果您的服务能够调用多个 DAO,那么单元测试可能会更难,因为您会使服务层更加复杂。
因此,当您设计层时,请考虑创建新层以简化设计是否有意义,这可能会发现错误或防止错误。
更新:
缺少的层是协调器,规则是每个协调器处理一个 DAO,并且可以进行任何需要的转换,但业务逻辑在控制器中。因此,协调员可以与任何其他协调员交谈以获取信息,而这些协调员将前往 DAO。
【讨论】:
但是,如果您创建了一个委托类来调用多个 DAO,那么您实际上将负担转移到了这个委托身上。如果使用多个 DAO 调用测试服务很难,那么对委托类进行单元测试不是同样困难吗? @limc - 我意识到其余的规则和名称,实际上更简单。使用了 Spring,所以你可以交换模拟层,所以如果你想测试控制器,你可以模拟出协调器。【参考方案4】:http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
DAO 的数量完全取决于底层资源!
【讨论】:
以上是关于Service 和 DAO 之间的关系应该是一对一还是一对多?的主要内容,如果未能解决你的问题,请参考以下文章
Presentation、Service 和 DAO 层关系
Action、Dao、DaoImpl、Service、ServiceImpl各自的作用是啥 他们之间有啥关系
Dao层到底是做啥的?service和Dao层有啥关系?说得具体一些。
请问java项目 里的DAO,model,service, IMPL 是啥意思,以及有啥关系