Spring 在控制器中将模型与视图分开的最佳实践 jsp?
Spring best practice to separate model from view in controller and jsp?
使用 Spring Controller class(with @ModelAttribute) 和jsp 同时准备模型,或者模型只能由 Spring 和来自的视图准备jsp?
这个想法来自这个 topic 。我有一个控制器 class:
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET, params = "mode=create")
public ModelAndView showCreatePage(@ModelAttribute("createForm") ApplicationCreateForm form)
{
return customMethod("some string");
}
在我的 jsp 中我有:
<jsp:useBean id="createForm" scope="request" class="com.example.ApplicationCreateForm"/>
我不需要用要呈现给用户的信息填充表单所有字段都是空的。
据我所知,我已经两次声明 ApplicationCreateForm bean,具有相同的范围 - 请求。
同时使用两者是一种好的设计习惯吗?这是有原因的吗?第二个声明(在 jsp 中)是否给了我更多的权力,例如覆盖模型或者它完全没有必要?当两者都存在时,第二个声明是否会覆盖第一个声明?
我认为您应该在 spring 控制器中充分准备您的模型。然后视图应该尽可能被动,即。仅显示从控制器接收到的模型属性,而没有进一步了解应用程序逻辑。这种方法为您提供了清晰的关注点分离,并且您的视图尽可能独立,并且可以轻松切换为不同的视图技术 - 例如。 thymeleaf 或 freemarker 模板。 MVC 的整个思想是分离表示层并通过泄漏业务逻辑来查看您创建不必要的依赖项。
您的视图应该尽可能简单,因为泄漏到视图的逻辑使得测试和重用变得非常困难。另一方面,如果您的逻辑很好地分离,您可以轻松地测试它并轻松地重用它。理想情况下,业务逻辑应该完全独立于网络环境。
通过定义您正在视图和 class com.example.ApplicationCreateForm 之间创建紧密耦合,使用 spring mvc 您可以在控制器、视图和模型之间实现松散耦合,这可能会发生更改您的模型名称,但您仍然具有相同的属性,这可能足以用于查看,在上述情况下,您将需要更新您的视图,但如果您使用 Spring MVC,则不需要更新。
由于 spring 提出了使事物松散耦合以使您的代码更易于测试的概念,因此您应该始终牢记,关注点分离是您的首要任务。因此,最好的做法是在 Controller 中完全准备模型,而不是在视图中。
保持简单,让您的控制器负责准备您的模型,并让您的视图仅显示模型。
那么,NO
你的问题。第二个声明不会让你变得强大,而是帮助你被束缚。
这个实现有很多问题。
是MVC吗?
如果JSP了解模型,为什么我们需要控制器。让我们去掉路由引擎,直接使用JSP来消费Model。但是这样应用程序将是单一的。我相信你不想要那个。我们有两种主要的 MVC 风格。在两者中,控制器都是面向前方的对象。它接收命令,对其进行解释,与数据层一起工作并获取模型。如果需要,模型将转换为视图模型,然后将此对象传递给视图。
为什么是 viewModel?
假设我们在屏幕上实现分页。我们正在显示人员名单。 Person 是您的模型,但您的视图还需要知道页码、页面大小等。因此您的模型可能不适合这种情况。
假设我们需要多个表中的数据显示在屏幕上。这些数据在某种程度上是相关的。现在您是否将单独的模型对象传递给视图并让它执行所有业务逻辑?最好没有。
设计不应该支持 DTO 或 ViewModel 或命令和查询吗?
我们希望我们的应用程序设计得当。如上所述,我们需要在处理后将数据发送到视图或客户端 (REST)。处理过的数据可能不会映射到您的域,除非我们只是在创建一个 CRUD 东西。如果要实现 CQS 或 CQRS 怎么办?
分离在哪里,SOLID在哪里?
如果我的视图正在执行业务逻辑,那么 'S' 在哪里?如果视图了解模型并且需要对模型进行最细微的更改,那么 'O' 在哪里?如果我想将查询与命令 (CQS) 分开并分别缩放这两个东西怎么办?
总而言之 我会说,是的,你可以这样做,但如果你正在开发一个体面的应用程序或者你认为它最终会是一个,那么这并不好。我见过有人使用模型实体,从 ORM 开始,到控制器再到视图。它会工作,但问题是您是否想要一个整体且紧密耦合的应用程序。根据我的经验,与控制器相比,表示逻辑(视图)具有非常不同的逻辑和数据需求,数据访问层也是如此。
使用 Spring Controller class(with @ModelAttribute) 和jsp 同时准备模型,或者模型只能由 Spring 和来自的视图准备jsp? 这个想法来自这个 topic 。我有一个控制器 class:
@RequestMapping(value = {"", "/"}, method = RequestMethod.GET, params = "mode=create")
public ModelAndView showCreatePage(@ModelAttribute("createForm") ApplicationCreateForm form)
{
return customMethod("some string");
}
在我的 jsp 中我有:
<jsp:useBean id="createForm" scope="request" class="com.example.ApplicationCreateForm"/>
我不需要用要呈现给用户的信息填充表单所有字段都是空的。
据我所知,我已经两次声明 ApplicationCreateForm bean,具有相同的范围 - 请求。
同时使用两者是一种好的设计习惯吗?这是有原因的吗?第二个声明(在 jsp 中)是否给了我更多的权力,例如覆盖模型或者它完全没有必要?当两者都存在时,第二个声明是否会覆盖第一个声明?
我认为您应该在 spring 控制器中充分准备您的模型。然后视图应该尽可能被动,即。仅显示从控制器接收到的模型属性,而没有进一步了解应用程序逻辑。这种方法为您提供了清晰的关注点分离,并且您的视图尽可能独立,并且可以轻松切换为不同的视图技术 - 例如。 thymeleaf 或 freemarker 模板。 MVC 的整个思想是分离表示层并通过泄漏业务逻辑来查看您创建不必要的依赖项。
您的视图应该尽可能简单,因为泄漏到视图的逻辑使得测试和重用变得非常困难。另一方面,如果您的逻辑很好地分离,您可以轻松地测试它并轻松地重用它。理想情况下,业务逻辑应该完全独立于网络环境。
通过定义您正在视图和 class com.example.ApplicationCreateForm 之间创建紧密耦合,使用 spring mvc 您可以在控制器、视图和模型之间实现松散耦合,这可能会发生更改您的模型名称,但您仍然具有相同的属性,这可能足以用于查看,在上述情况下,您将需要更新您的视图,但如果您使用 Spring MVC,则不需要更新。
由于 spring 提出了使事物松散耦合以使您的代码更易于测试的概念,因此您应该始终牢记,关注点分离是您的首要任务。因此,最好的做法是在 Controller 中完全准备模型,而不是在视图中。
保持简单,让您的控制器负责准备您的模型,并让您的视图仅显示模型。
那么,NO
你的问题。第二个声明不会让你变得强大,而是帮助你被束缚。
这个实现有很多问题。
是MVC吗?
如果JSP了解模型,为什么我们需要控制器。让我们去掉路由引擎,直接使用JSP来消费Model。但是这样应用程序将是单一的。我相信你不想要那个。我们有两种主要的 MVC 风格。在两者中,控制器都是面向前方的对象。它接收命令,对其进行解释,与数据层一起工作并获取模型。如果需要,模型将转换为视图模型,然后将此对象传递给视图。
为什么是 viewModel?
假设我们在屏幕上实现分页。我们正在显示人员名单。 Person 是您的模型,但您的视图还需要知道页码、页面大小等。因此您的模型可能不适合这种情况。
假设我们需要多个表中的数据显示在屏幕上。这些数据在某种程度上是相关的。现在您是否将单独的模型对象传递给视图并让它执行所有业务逻辑?最好没有。
设计不应该支持 DTO 或 ViewModel 或命令和查询吗?
我们希望我们的应用程序设计得当。如上所述,我们需要在处理后将数据发送到视图或客户端 (REST)。处理过的数据可能不会映射到您的域,除非我们只是在创建一个 CRUD 东西。如果要实现 CQS 或 CQRS 怎么办?
分离在哪里,SOLID在哪里?
如果我的视图正在执行业务逻辑,那么 'S' 在哪里?如果视图了解模型并且需要对模型进行最细微的更改,那么 'O' 在哪里?如果我想将查询与命令 (CQS) 分开并分别缩放这两个东西怎么办?
总而言之 我会说,是的,你可以这样做,但如果你正在开发一个体面的应用程序或者你认为它最终会是一个,那么这并不好。我见过有人使用模型实体,从 ORM 开始,到控制器再到视图。它会工作,但问题是您是否想要一个整体且紧密耦合的应用程序。根据我的经验,与控制器相比,表示逻辑(视图)具有非常不同的逻辑和数据需求,数据访问层也是如此。