在MVC中,应从Controller或Model调用DAO


14

我已经看到了很多反对直接从Controller类调用DAO以及从Model类调用DAO的争论。事实上,我个人觉得如果我们遵循MVC模式,则控制器不应与DAO耦合,而应与Model类耦合应该从内部调用DAO,而控制器应该调用模型类。为什么,我们可以将模型类与Web应用程序分离开来,并公开各种功能,例如REST服务使用我们的模型类。

如果我们在控制器中编写DAO调用,REST服务将无法重用功能,对吗?我总结了以下两种方法。

方法1

  public class CustomerController extends HttpServlet {

    proctected void doPost(....)  {

            Customer customer = new Customer("xxxxx","23",1);
            new CustomerDAO().save(customer);

    }


 }

方法#2

  public class CustomerController extends HttpServlet {

    proctected void doPost(....)  {

            Customer customer = new Customer("xxxxx","23",1);
            customer.save(customer);

    }


 }

 public class Customer {

   ...........

   private void save(Customer customer){

        new CustomerDAO().save(customer);

   }

}

注意 -

这是Model的定义:

模型:模型管理应用程序域的行为和数据,响应关于其状态信息的请求(通常是从视图),并响应更改状态的指令(通常是从控制器)。

在事件驱动的系统中,模型会在信息更改时通知观察者(通常是视图),以便观察者可以做出反应。

我需要专家意见,因为我发现许多使用#1或#2,那是哪个?


1
控制器应加载模型中的所有内容并将其传递给视图。
jgauffin 2012年

您是第二种建议方法吗?

1
“控制器可以将命令发送到其关联的视图,以更改模型的视图表示(例如,通过滚动文档)。它可以将命令发送到模型,以更新模型的状态(例如,编辑文档)。” .. emm ..在哪里说,控制器应该提取数据或将其传递?
mefisto

Answers:


31

我认为,您必须区分MVC模式和3层体系结构。总结一下:

3层架构:

  • 数据:持久数据;
  • 服务:应用程序的逻辑部分;
  • 演示文稿:HMI,Web服务...

MVC模式发生在上述架构的表示层中(对于Webapp):

  • 数据:...;
  • 服务:...;
  • 介绍:
    • 控制器:拦截HTTP请求并返回HTTP响应;
    • 模型:存储要显示/处理的数据;
    • 视图:组织输出/显示。

典型 HTTP请求的生命周期:

  1. 用户发送HTTP请求;
  2. 控制器拦截它;
  3. 控制器调用适当的服务;
  4. 服务调用适当的dao,该dao返回一些持久化的数据(例如);
  5. 服务处理数据,并将数据返回给控制器;
  6. 控制器将数据存储在适当的模型中并调用适当的视图;
  7. 该视图将使用模型的数据实例化,并作为HTTP响应返回。

1
您所说的“典型HTTP请求的生命周期”不是MVC。DAO只是一个对象,它促进了域逻辑和持久性之间的交互/转换。它不是活动记录的其他名称。还..因为模型已经成为演示的一部分了?
mefisto

1
@teresko 1)是的,它是MVC,但在3层体系结构内。如果没有,为什么?2)你是对的,我编辑过。3)由于整个MVC模式都发生在表示层中。典型示例:Spring MVC,其模型只是包含键值对的Map。SpringFuse也做出了这个选择。
sp00m 2012年

2
我必须在这里同意@ sp00m ...他对典型HTTP请求的描述对于MVC Web应用程序是准确的,并且他将模型(作为MVC中的“ M”)作为表示层的一部分的定位也正确。 。在n层MVC应用程序中,“模型”通常是表示层在下面其余层中的外观。
埃里克·金

8

来自模型层。

更准确地说:来自服务,这些服务包含在模型层中,因为它们控制域对象和存储逻辑抽象之间的交互。

控制器应仅负责更改模型层的状态。DAO是持久性机制的一部分。这构成了域业务和应用程序逻辑的一部分。如果开始与Controller中的DAO进行交互,则将泄漏表示层中的域逻辑。


要使用服务层,应该采用DDD模式吗?如果我错了纠正我。我们在MVC中有服务层吗?

你可以有。服务用于将域逻辑与应用程序逻辑分开。这是必要的,然后从纯CRUD域结构(活动记录)移至将存储逻辑与域逻辑分开的结构。在完全实现的模型层中,您具有3个逻辑分离:持久性,域和应用程序。
mefisto

3

我不确定官方的MVC模式需要什么,但是我通常希望在控制器和DAO之间有一个“服务”层。控制器从请求中提取数据,并将其传递给适当的服务类。服务类负责调用传回模型类的一个或多个DAO。然后将那些模型类发送回控制器,以便发送到视图层。由于多个控制器可以使用相同的服务层方法,因此将服务层放入有助于重用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.