Java 实体、服务类和命令对象的最佳实践问题

Java 实体、服务类和命令对象的最佳实践问题,java,spring,spring-mvc,Java,Spring,Spring Mvc,实体是直接映射到数据库(我们用于Hibernate)的类 在调用DAO之前,我们的服务类包含这些实体的业务逻辑 我们还有命令对象,它们是与特定视图相关的POJO。我被告知实体本身不应该被用作命令对象,但我得到的关于“为什么”的答案是不够的。我希望这里有人能给我这个答案 我们的一些观点非常简单。它们的属性并不比实体本身多。将一个实体映射到一个基本上是实体镜像的命令对象对我来说似乎毫无意义。我认为在应用程序的所有层(控制器、视图、服务类和DAO层)重用域模型对象(您称之为实体)没有问题。这是您经常看

实体是直接映射到数据库(我们用于Hibernate)的类

在调用DAO之前,我们的服务类包含这些实体的业务逻辑

我们还有命令对象,它们是与特定视图相关的POJO。我被告知实体本身不应该被用作命令对象,但我得到的关于“为什么”的答案是不够的。我希望这里有人能给我这个答案


我们的一些观点非常简单。它们的属性并不比实体本身多。将一个实体映射到一个基本上是实体镜像的命令对象对我来说似乎毫无意义。

我认为在应用程序的所有层(控制器、视图、服务类和DAO层)重用域模型对象(您称之为实体)没有问题。这是您经常看到的常见设计

当且仅当您有一个真正的层分离时,这没有问题——控制器从服务层获取模型对象,服务层从DAO层获取模型对象,等等


如果您的设计是通过从视图层调用
manager.getEmployees()
从数据库加载
Employee
对象,那么这将无法正常工作。

似乎在对象的命名方面存在一些混乱。命令对象通常提供一个execute()方法(带参数),该方法对给定的实体或域对象进行操作,以根据业务逻辑改变其状态。这是一种将业务逻辑封装到简单对象中的非常简洁的方法,这些对象的范围非常有限,无法改变其他对象

这样看来,您正在使用的设计实际上在数据传输对象(DTO或实体)和值对象(系统中的VO或命令对象)之间执行某种桥接。这可能非常浪费,因为您所做的只是将相同的数据复制到不同的对象中

作用于数据传输对象(DTO或实体)模式的数据访问对象(DAO)已建立良好,并促进了层之间的良好分离。通常,Hibernate将实体映射到数据库,并在其中惰性地加载集合。这就是大多数设计失败的地方,因为它们不允许正确初始化集合,因为一旦执行线程离开DAO,会话就结束了。我认为JSP中的“命令对象”实际上是实体的子集,其中的各种集合都是通过Hibernate查询初始化的

我建议您放弃“命令对象”,而选择适当初始化的实体,这将在一个方面简化您的设计,但在另一个方面会导致潜在问题。您需要仔细控制JSP引用和初始化集合的方式。您可能会发现,当JSP对某些尚未初始化的DTO调用getCollection()方法时,您必须查看视图中的OpenSession模式,以确保Hibernate会话对象可用