【问题标题】:Architectural layers in Java web application [duplicate]Java Web应用程序中的架构层[重复]
【发布时间】:2016-03-26 19:46:24
【问题描述】:

我正在开发一个 java web 应用程序并尝试遵循一些模式,如 dao/dto。目前我正在考虑这样的基础架构层:

我遇到了一些关于图层的问题。该方案将这样进行:DAO 接受 DTO 并从数据库返回对象(实体),服务层也接受 DTO,使用 DAO 并使用返回的对象执行所有必需的逻辑。 UI Bean、Service、DAO 和 DTO 类是特定于实体的 - 每个实体都有自己的层。

  1. 现在我是否需要 UI bean 在视图中使用,或者这会是一种矫枉过正,而 UI 视图可以直接将服务类用作 ui bean?如果没有,我为什么需要 UI bean?

  2. 另一个问题是关于 DTO。我已经创建了具有所有必需属性的实体,据我所知,DTO 类就像实体类的反射。那么为什么我需要这些 DTO 类,如果我使用它们,我会侦察它需要从实体到 dto 的一些转换,反之亦然。我是否在服务层进行转换?视图(例如 html 页面)是否还会显示 DTO 对象属性而不是实际实体(如调用 #{UIBean.entityProperty})?

【问题讨论】:

  • 谢谢,但这并不能回答我的问题。我在询问是否需要额外的(UI bean)层作为服务和 DAO 层的补充。此外,如果需要 DTO 或者我可以使用实体类,因为 DTO 类反映了实体类,并且需要在 DTO 和实体对象之间进行转换。我正在考虑使用 DTO,因为我听说有人说将实体暴露给 UI 和服务是不好的做法,你必须有某种 DTO。
  • 我想都在里面,还请阅读相关帖子……

标签: java spring hibernate jsf jpa


【解决方案1】:

既然你有 Spring 标签,

我将用 Spring Data Repository 替换您的 [DAO]。所以大多数时候,你写接口方法/@query注解,Spring Data写实现。

将 DTO 替换为 JPA 实体。所以我可以使用一些逆向工程。

[UI Bean] 将大部分是 JPA 实体的组合。经过一些验证

【讨论】:

    【解决方案2】:

    根据经验,请尝试根据您的上下文划分逻辑层。启发你的理论,但要小心使用它。我用几个例子给你我对 layer 的兴趣的谦卑理解。这个愿景当然不完整,但我希望它能帮助您回答您的问题。

    1. 那么使用 UIBean 而不是 Service DTO 是不是有点矫枉过正?我会说这取决于你的上下文。

    也许您的 UI bean 中有用户输入数据?例如,您必须使用 JSR 303 注释来验证它们。如果这些注释在该层中有意义,则它们对于下面的层毫无用处。这就是为什么您将拥有一个带有 JSR 303 注释的 UIBean 和一个不带 JSR 303 注释的 DTOBean。

    但如果它们完全相同,为什么要重复?也许在 UIBean 层,日期可以表示为 String 类型,并且您希望在 DTO 层操作 Date 类型而不是 String。 这就是为什么您需要调整图层之间的数据以处理对特定图层有意义的对象。例如,您可以添加一个 BOAdapter(在 UIView 和 Service 之间)和 DTOAdapter(在 Service 和 DAO 之间)。这些适配器对于在每个 POJO 格式中转换数据很有用。例如,您可以在您的 BO(=UIBean) 中有一个用三个字符串表示的日期,并且您想要一个用于 DTO 的 Date 对象,因此您可以在 BOAdapter 中对其进行转换:

    public class BOAdapter(){
       private BOAdapter(){}
       public static DTO toDTO(BO objectBO){
          DTO objectDTO = new DTO();
          SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-aa");
          objectDTO.setDate(df.parse(objectBO.getYear()+"-"+objectBO.getMonth()+"-"+objectBO.getDay());
          [...]
    }
    }
    
    1. 为什么我需要 DTOAdapter ?也许您有一个数据库,其中至少包含两个表 Customers 和 Adresses,它们之间存在完整性约束。 JPA 将自动生成正确的代码。但是你真的需要 UIView 之前的所有这些代码吗?我的意思是,如果您正在编码的功能只需要客户的姓名、姓氏和出生日期,那么他们的地址就没有用了。 这就是为什么您需要在层之间调整数据以使用对特定层有意义的对象。在这种情况下,您可以创建一个仅包含姓名、姓氏和出生日期信息的 DTO 对象,并在您的 DTOadapter 中创建一个方法,将您的自定义 DTO 转换为一个重型 JPA 对象,以便与数据库正常工作。

    但是我需要整个实体来编码我的功能?除了 JSR 303 之外,您可能还需要在该层内添加验证约束。因此,出于与 BO 对象相同的原因,在您的实体之外拥有 DTO 类可能会很有趣。

    但是我的实体很大怎么容易复制呢?尝试使用工具自动映射数据(如推土机)。如果不是太大,请手动操作。

    【讨论】:

      【解决方案3】:

      首先,我将只在前端部分使用 DTO bean,但由于你已经提到 UI-bean,我想这些可以解决问题,外观使用这些将它们传递给控制器用于显示您的网络组件。 在服务和外观之间,您将后端的实体映射到 dto-beans。 这样,您的前端将完全松散地耦合到您的后端。

      关于您的第二个问题,我想指出您的 UI 应始终使用 dto 或查看 bean 的确切原因。 您可以将多个后端实体 bean 组合成一个 dto bean,以便在前端进行处理。

      一般来说,我始终牢记 DTO 用于公共访问、公开它的 Web 服务、Web 前端或 Swing 应用程序,或者... 仅在 dao 和服务层中使用的实体类永远不会进一步向上。

      【讨论】:

        猜你喜欢
        • 2018-08-27
        • 1970-01-01
        • 2014-05-28
        • 1970-01-01
        • 2011-05-05
        • 2015-01-27
        • 2014-06-20
        • 2014-07-05
        • 2012-12-30
        相关资源
        最近更新 更多