【问题标题】:What is the best practice for service-dao pattern?服务道模式的最佳实践是什么?
【发布时间】:2013-07-12 11:03:56
【问题描述】:

让我们考虑一个简单的用户插入操作。我的 Spring 相关课程是 UserControllerUserServiceUserServiceImplUserDAOUserDAOImpl

在控制器端我调用userService.insert(new User()),在userService.insert() 方法中我调用userDAO.insert(user)。我认为这种模式存在方法重复。

有没有办法避免方法重复?可能是我的编码有问题。我等待你的回复,经验......

提前谢谢...

【问题讨论】:

    标签: spring service duplication genericdao


    【解决方案1】:

    对于我的项目,我使用这些服务和 DAO 层。 我不知道这是否是最佳做法。

    这是一个示例创建操作级别:

    [View Layer]
      * Simple HTML form or AJAX request
          |
          | User submits create form. Browser sends POST data
          | to controller.
          |
    [User Controller]
      * Authentication and authorization. @Security annotations can be for method security.
      * Controller tries to bind POST data to UserCreateForm. If can't Validation exception occurs.
      * Validates bind data according to validation annotations. @Required ...
          |
          | (UserCreateForm) is POJO class which has validation annotations.
          | It is similar but different from domain objects.
          |
    [User Controller]
      * Logs errors via Logging API (logback, slf4j, log4j ...)
      * Copies form values from UserCreateForm to User domain object
      * Calls service methods.
      * Passes messages and model objects to desired view page.
          |
          | (User) is POJO class. called domain object, contains ORM annotations if using JPA
          | or hibernate. It is similar but different from form/command objects. It can be
          | generated automatically by tools (IDE, hibernate tools ...)
          |
    [UserService & UserServiceImpl]
      * Calls multiple DAO methods in one transaction. If an error occurs. rolls back.
      * Contains business logic
      * Doesn't know the database technology.
          |
          | (User) domain object.
          |
    [UserDAO & HibernateUserDAOImpl || JpaUserDAOImpl || OracleJdbcDAOImpl ...]
      * DAO layer knows the persistence technology
      * Operations are atomic
    

    【讨论】:

      【解决方案2】:

      我认为这不是重复,我认为您使用了非常糟糕的名称(这使它看起来像重复)。

      Service 方法“创建”一个用户,DAO 方法“插入”或“保存”它。

      现在您看到“创建”和“插入”是两个不同的操作,具有不同的范围和不同的抽象级别。所以没有重复。

      【讨论】:

      • 是方法的唯一问题名称吗?让我们这样想…… X 实体只有 2 个字段; id、name 和我们需要简单的 CRUD 屏幕。在 backed 你只需要保存、更新、删除、查询 X Entity。为此,如果我使用 XService 和 XDAO,XService 只会模仿/复制 XDAO 方法,对吧?
      • 问题不在于名称本身,问题在于方法的作用:在您的情况下,服务方法创建一个实体,DAO 方法保存它 - 这是两个相关但不同的事情.
      【解决方案3】:

      您概述的内容看起来不错,并且适合业务服务模式的许多实现。可能引起您困惑的是,描述方法/功能的语言通常在每一层之间有所不同。例如,“插入”是一个更多的数据持久性术语,而业务/服务层想要“创建”一个用户。差异的原因是通常在概念上存在差异。在服务层“创建”一个用户只是一个“对象”,一个“用户”,而在 DAO 层,它实际上是几个步骤; 1. 创建“用户”,2. 在不同的表中创建他们的“地址”,3. 将他们添加到任何安全组。

      所以在您的情况下,您实际上可能是一对一的,在很多情况下,业务层 1 等同于许多 DAO 交互。

      【讨论】:

      • 是的,在某些服务方法中存在不同的 DAO 交互步骤,但我的 70 种服务方法只有一行,例如 xDAO.saveOrUpdate() 或 xDAO.delete() 等...所以我问自己为什么我不在那个 %70 服务方法中直接使用 DAO 方法。你怎么看?
      • 直接暴露底层 DAO(例如,从 Controller 直接调用)不一定是坏事。这取决于您的用例、应用程序的复杂性和您的“未来”计划。就个人而言,我喜欢中间的“服务”层的抽象,因为它给了我未来“成长”的空间(执行更多的操作,而不仅仅是 DAO 的方向)并支持可测试性等。这可以像接口一样有争议> 实现论点,“如果我永远不会做比 x 更多的事情,为什么要创建一个接口?”
      【解决方案4】:

      除了提及名称混淆之外,您描述的结构是一个很好的起点。根据复杂性,您可以将接口类排除在外,最终得到三个类。如果您的应用程序很小(到中等),我认为这是一种合法的方法,即使它不是最佳实践。一旦你发现有很多依赖项并且你需要某种 api 包来为你的应用程序的一部分引入一个接口,只要它不是整个应用程序,用 spring 很容易引入它。

      您必须记住的另一件事是,您不需要为每个用例增加这个完整的类链。广义的 SimpleCrudDao 和 SimpleEntityService 非常好。然后,一旦这个 SimpleEntityService 不够用,您就可以开始创建特定的,例如具有 createUserAndTransferEntitiesAndUpdateWhatsoever 方法的 UserService。

      【讨论】:

      • 其实我用的是你的解决方案;使用 SimpleEntityService,我在控制器端执行简单的 CRUD 操作,如果需要 n 步解决方案,我将创建一个特殊的服务。我只是想确定它是否合法:) 感谢您的回答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      相关资源
      最近更新 更多