Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DAO模式和模型对象_Java_Oop_Design Patterns_Dao - Fatal编程技术网

Java DAO模式和模型对象

Java DAO模式和模型对象,java,oop,design-patterns,dao,Java,Oop,Design Patterns,Dao,我查阅了很多关于DAO模式的信息,我明白了它的意思。但我觉得大多数解释并不能说明全部情况,我的意思是,你到底会在哪里使用你的刀。例如,如果我有一个用户类和一个相应的UserDAO,可以为我保存和恢复用户,这是正确的方法: 控制器创建用户对象并将其传递给UserDAO以将其保存到数据库 控制器创建用户对象,用户对象在其构造函数中调用userDAO以将自身保存到数据库中 这是一种代码味道,您缺少一个额外的类“UserManager”,控制器将要求它创建用户。UserManager负责创建用户并要求

我查阅了很多关于DAO模式的信息,我明白了它的意思。但我觉得大多数解释并不能说明全部情况,我的意思是,你到底会在哪里使用你的刀。例如,如果我有一个用户类和一个相应的UserDAO,可以为我保存和恢复用户,这是正确的方法:

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

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

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

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

对于典型的webapp,我更喜欢使用play的JPA和数据库实现的play框架。这是一种更有效的方式

请看这里 这里呢 及


就这样)根据我使用DAOs的经验,第一种方法是唯一正确的方法。原因是它的责任最明确,产生的混乱最少(好吧,一些非常受尊敬的程序员认为DAO本身就是混乱。Adam Bien认为原来的DAO模式已经在
EntityManager
中实现了,而更多的DAO基本上是不必要的“管道”)

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

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

我想大多数名为
…Manager
的类都有气味。该名称本身表明该类没有明确的用途。每当我想给一个类命名时,
…Manager
,这对我来说就是一个信号,让我找到一个更合适的名称,或者认真思考我的体系结构。

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

DAO之前的架构层在项目中可能会有所不同

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


如果您支持多个客户端,如JSP、Web服务、手持设备等,那么在控制器层使用业务逻辑是不好的。

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


从模型的角度来看,控制器应该与坐在模型前面的-,进行交互。“代码”>用户管理器< /Cord>对象将是一个您将考虑服务层的一部分的示例,即域模型的公共API。

< P>第一种方法;总之,控制器在DAO对象上调用方法不是一个好的设计。控制器必须询问有关业务的“服务”级别对象。控制器不关心这些“服务”如何持久化数据

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

最后,管理器或服务对象是分层体系结构的良好抽象。通过这种方式,您可以将业务流分组到适当的类和方法中

但对于Play,case类的伴生对象也是一个很好的候选对象,可以用作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()
    }

  }

}

再加上这个,;我通常还会创建一个UserServices对象,负责管理会话/事务。然后我有一个UserDAO,它只负责实际执行从UserServices调用的查询。@sbratla-如果您使用的是用户事务,这肯定是有意义的。我自动假设EJB事务,尽管OP没有提到它们。膝跳:)@Tom如果你不同意,请详细说明