【问题标题】:DAO pattern and model objectsDAO 模式和模型对象
【发布时间】:2012-07-26 04:24:51
【问题描述】:

我查阅了很多关于 DAO 模式的信息,我明白了这一点。但我觉得大多数解释并没有说明全部故事,我的意思是你会在哪里实际使用你的 DAO。因此,例如,如果我有一个 User 类和相应的 UserDAO 可以为我保存和恢复用户,这是正确的方法:

  • 控制器创建 User 对象并将其传递给 UserDAO 以将其保存到数据库中

  • 控制器创建用户对象,并在其构造函数中用户对象调用 userDAO 以将自身保存到数据库中

  • 这是一种代码异味,您缺少一个额外的类“UserManager”,控制器将要求该类创建用户。 UserManager 负责创建用户并要求 UserDAO 保存它

我真的觉得第三个选项是最好的,因为控制器所负责的只是将请求委托给正确的模型对象。 你最喜欢的方式是什么?我在这里错过了什么吗?

【问题讨论】:

    标签: java oop design-patterns dao


    【解决方案1】:

    根据我使用 DAO 的经验,第一种方法是唯一正确的方法。原因是它的职责最清晰,产生的混乱最少(好吧,一些非常受人尊敬的程序员认为 DAO 本身就是混乱的。Adam Bien 认为原始 DAO 模式已经在 EntityManager 中实现,并且进一步的 DAO 大多是不必要的“管道” ")

    方法 2 将模型绑定到 DAO,创建“上游依赖项”。我的意思是,通常模型作为单独的包分发,并且(并且应该)不知道它们的持久性细节。与您描述的类似模式是Active Record pattern。它在 Ruby on Rails 中被广泛使用,但在 Java 中并没有以同样优雅和简单的方式实现。

    方法 3 - UserManager 的重点是什么?在您的示例中,管理器执行 2 个任务 - 它具有用户工厂的职责,并且是持久性请求的代理。如果它是一家工厂并且您需要它,您应该将其命名为UserFactory,而不要对其施加额外的任务。至于代理 - 为什么需要它?

    恕我直言,大多数名为...Manager 的课程都有异味。该名称本身表明该类没有明确的目的。每当我想给一个类命名 ...Manager 时,这都是我寻找一个更合适的名称或认真思考我的架构的信号。

    【讨论】:

    • 只是添加到这个;我通常还创建一个负责管理会话/事务的 UserServices 对象。然后我有 UserDAO,它只负责实际执行从 UserServices 调用的查询。
    • @sbrattla - 如果您使用用户事务,这绝对是有意义的。我自动假设 EJB 事务,尽管 OP 没有提到它们。下意识的:)
    • @Tom 如果您不同意 - 请详细说明
    【解决方案2】:

    对于第一种方法;恕我直言,在 DAO 对象上调用方法的控制器不是一个好的设计。控制器必须询问有关业务的“服务”级别对象。这些“服务”如何保存数据不是控制器关心的问题。

    对于第二种方法;有时您可能只想创建对象,因此构造函数和持久化任务不能像这样紧密耦合。

    最后,管理器或服务对象是分层架构的一个很好的抽象。这样,您可以将业务流分组到适当的类和方法中。

    但对于 Play,案例类的伴生对象也是用作 DAO 的良好候选对象。这些对象的单例性质使其成为一个很好的候选对象。

    case class TicketResponse(appId: String, ticket: String, ts: String)
    
    object TicketResponse{
      implicit val ticketWrites = Json.writes[TicketResponse]
    
      def save(response: TicketResponse) = {
    
        val result = DB.withConnection {
          implicit connection =>
    
            SQL("insert into tickets(ticket, appid, ts)"
              +   " values ({ticket},{appid},{ts})")
              .on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert()
        }
    
      }
    
    }
    

    【讨论】:

      【解决方案3】:

      数据访问对象 (DAO) 应更靠近应用程序的数据访问层使用。 数据访问对象实际上执行数据访问活动。所以它是数据访问层的一部分。

      DAO 之前的架构层可能因项目而异。

      控制器主要用于控制请求流。所以它们有点接近 UI。 尽管 Manager 和 Handler 是个坏主意,但我们仍然可以在控制器和 DAO 之间添加一层。因此控制器将预处理来自请求或发出的数据(数据完整性、安全性、本地化、i18n、转换为 JSON 等)。它以域对象(在本例中为用户)的形式向服务发送数据。该服务将调用此用户的某些业务逻辑或将其用于某些业务逻辑。然后它将它传递给 DAO。

      如果您支持多个客户端(如 JSP、WebServices、手持设备等),则在控制器层中包含业务逻辑并不好。

      【讨论】:

        【解决方案4】:

        假设控制器是指MVC 中的“C”,您的第三个选项是正确的方法。一般来说,控制器代码扩展或遵循框架的约定。 MVC 的理想之一是交换框架,这实际上是 Controller,应该相对容易。控制器应该只是在模型层和视图层之间来回移动数据。

        从模型的角度来看,控制器应该与 service layer - a contextual boundary 交互 - 坐在 domain model 前面。 UserManager 对象将是您认为是服务层的一部分的一个示例——即域模型的公共 API。

        【讨论】:

          【解决方案5】:

          对于典型的 web 应用程序,我更喜欢 play 框架与 play 的 JPA 和数据库实现。这种方式更有成效。

          请看这里http://www.playframework.org/documentation/1.2.5/jpa 和这里 http://www.playframework.org/documentation/1.2.5/guide1http://www.playframework.org/documentation/1.2.5/guide2

          就是这样))

          【讨论】:

            猜你喜欢
            • 2017-02-26
            • 2012-10-29
            • 2015-02-12
            • 1970-01-01
            • 2013-04-19
            • 2012-08-31
            • 2011-09-08
            • 2013-07-12
            • 1970-01-01
            相关资源
            最近更新 更多