Java 在三层体系结构的服务中需要域模型吗?

Java 在三层体系结构的服务中需要域模型吗?,java,spring-boot,model,entity,three-tier,Java,Spring Boot,Model,Entity,Three Tier,我正在用SpringBoot构建一个API Rest,我想澄清一下关于我的架构的概念,看看社区是否可以帮助我 假设在我的数据库中有一个名为Person的表。我正在安装一个基于三层架构的架构。一般计划如下: 一方面,我有PersonDao.java,它将负责访问数据库,从Person表中检索元组。为此,它使用一个名为PersonEntity.java的类,该类包含表中的所有列(作为属性)PersonDao.java将从PersonModel.java类返回一个对象PersonModel.java

我正在用SpringBoot构建一个API Rest,我想澄清一下关于我的架构的概念,看看社区是否可以帮助我

假设在我的数据库中有一个名为
Person
的表。我正在安装一个基于三层架构的架构。一般计划如下:

  • 一方面,我有
    PersonDao.java
    ,它将负责访问数据库,从
    Person
    表中检索元组。为此,它使用一个名为
    PersonEntity.java
    的类,该类包含表中的所有列(作为属性)
    PersonDao.java
    将从
    PersonModel.java
    类返回一个对象
    PersonModel.java
    是表示
    Person
    业务模型的类

  • 另一方面,我有
    PersonService.java
    ,它负责执行我的应用程序的业务逻辑。此服务调用
    PersonaDao.java
    来访问存储在数据库中的信息
    PersonService.java
    使用
    PersonModel.java
    类的对象,因为该类表示我的应用程序的业务对象
    PersonService.java
    将始终返回
    PersonDto,java

  • 最后,
    PersonController.java
    。此控制器将公开RESTAPI的连接接口。他总是与DTO合作,并通过DTO与PersonService.java进行通信

PersonController(PersonDto)PersonService(PersonModel)PersonDao(PersonEntity)DB

问题是:是否有必要使用
PersonModel.java
类,以便
PersonService.java
只处理此类的对象?还是让
PersonService.java
直接处理类
PersonEntity.java
中的对象更好?如果我这样做是为了维护单一责任的原则,这样每个层只处理其范围内的对象

如果答案是,
PersonModel.java
对于维护每一层的单一责任原则是必要的。如果使用了JpaRepository,会有什么变化吗?如果我问这个问题,是因为在许多教程和示例中,我看到当使用
JpaRepository
时,服务直接与实体协同工作。在这种情况下,我们不应该创建一个表示服务的业务对象的类吗

编辑:在对这个问题的回答()中,我脑海中有意义的架构会被反映出来,但它肯定不是最正确的东西。我得出的结论是,每一层都会使用自己的对象。复制/粘贴答案:

通常,您有不同的层:

  • 存储数据的持久层
  • 业务层对数据进行操作
  • 用于公开数据的表示层
通常,每个层将使用其自己的对象类型:

  • 持久层:存储库、实体
  • 业务层:服务、域对象
  • 表示层:控制器、DTO
这意味着 图层只能处理它自己的对象,并且永远不会将它们传递给用户 另一层


提前感谢。

据我所知,您的问题特别是关于层及其在
逻辑层中的使用。(因此,
表示
数据
层不属于问题的一部分)

关于
PersonModel
我不确定您对
PersonModel
的意思以及它的实际功能,但乍一看,我可以说您通常不需要这样的东西,这只会增加额外的代码复制和维护开销

关于
PersonDto
顾名思义,
DTO
s实际上是用于在客户机(
表示层
层)和API(
逻辑层
内的
控制器/边界层
层)之间传输数据,后者用于公开客户机的“客户友好”表示,以某种方式管理过度和不足的抓取(多亏了这一点,现在几乎不再是一个问题)。因此,您的业务服务类根本不需要了解或处理DTO

另外,正如您已经提到的,为了业务或dao,类不应该以任何方式处理额外的数据映射(例如Dto模型、模型实体)。它们已经完成了逻辑层(参见边界层、服务层)中的特定任务

关于
人格
这通常表示您和
数据层的真实实体(例如RDBMS中的数据库表或NoSQL中的文档)。所以这很普遍

  • 实体类的命名不带后缀,例如
    entity
    。只需使用简单的名称,例如
    Person

  • 实体类包含附加注释(例如JPA),以使它们对
    ORM层可见(例如Hibernate)

  • 实体类不应该是必需的并且实际上包含一些附加行为(可能是您想要对
    PersonModel
    类执行的操作),例如

班级人员{
生日;
int getAge(){/*根据生日计算年龄*/}
布尔isAdult(){/*getAge()>=18*/}
}
收尾 用例:创建
实体

兴隆(出境航班)

[Client]-->(数据:JSON-->-->-->[PersonController]-->用于在后台自动化此过程。好东西
[Client] --> (data: JSON) --> <Deserialization as `PersonDTO`> --> <DTO Validation> --> [PersonController] --> <AutoMapping to `Person` entity> --> [PersonService] --> [PersonDao] --> <ORM and JDBC> --> <Entity Validation> --> DB
DB --> <ORM and JDBC> --> [PersonDao] --> [PersonService] --> <AutoMapping to `Person` entity> --> [PersonController] --> <AutoMapping `Person` entity to `PersonDTO`>  --> <Serialization of `PersonDTO`> --> (data: JSON) -> [Client]