Enterprise Java 实体应该是愚蠢的吗?

2024-03-11

在我们遗留的 Java EE 应用程序中,有大量值对象 (VO) 类,它们通常只包含 getter 和 setter,也许equals() and hashCode()。这些(通常)是要保存在持久性存储中的实体。 (根据记录,我们的应用程序没有 EJB - 尽管might将来会发生变化 - 并且我们使用 Hibernate 来持久化我们的实体。)操作 VO 中数据的所有业务逻辑都位于单独的类中(不是 EJB,只是 POJO)。我的面向对象心态讨厌这一点,因为我确实相信给定类上的操作应该驻留在同一个类中。所以我有一种重构的冲动,将逻辑转移到相关的 VO 中。

我刚刚与一位在 Java EE 方面比我更有经验的同事进行了讨论,他确认哑实体至少曾经是推荐的方法。然而,他最近也看到了质疑这一立场有效性的观点。

我知道存在一些问题至少限制了实体类中可以放入的内容:

  • 它不应该直接依赖于数据层(例如查询代码应该进入单独的 DAO)
  • 如果它直接暴露给更高层或客户端(例如通过 SOAP),则可能需要限制其接口

还有更正当的理由吗not将逻辑转移到我的实体中?或者还有其他需要考虑的问题吗?


The DTO and VO应该用于传输数据并且不嵌入逻辑。这业务对象另一方面应该嵌入一些逻辑。我说some,因为在协调涉及多个业务对象的逻辑的服务中放置的内容与在业务对象本身中放置的内容之间始终需要找到平衡。业务对象中的典型逻辑可以是验证、字段计算或其他一次仅影响一个业务对象的操作。

请注意,我没有提到这个词entity迄今为止。持久性实体随着 ORM 的普及而流行,现在我们尝试使用持久性实体作为 DTOand同时业务对象。也就是说,实体本身在层与层之间流动,并包含一些逻辑。

还有什么更正当的理由不 将逻辑转移到我的实体中?或任何 其他需要考虑的问题?

正如您所指出的,这完全取决于依赖关系和您公开的内容。只要实体是哑的(接近 DTO),它们就可以轻松地隔离在一个专用的 jar 中,用作层的API。您在实体中放入的逻辑越多,做到这一点就越困难。注意你公开的内容和依赖的内容(加载类时,客户端也需要有依赖的类)。这适用于异常、继承层次结构等。

举个例子,我有一个项目,其中实体有一个方法toXml(...)在业务层使用。因此,实体的客户端依赖于 XML。

但是,如果您不太关心层以及 API 和实现之间的严格分离,我认为在实体中移动一些逻辑是很好的。

EDIT

这个问题已经讨论过很多次了,并且可能会继续讨论,因为没有明确的答案。一些有趣的链接:

  • 消气剂消除器 http://martinfowler.com/bliki/GetterEradicator.html
  • 贫血域模型 http://en.wikipedia.org/wiki/Anemic_Domain_Model
  • 封闭的重要性 http://codecourse.sourceforge.net/materials/The-Importance-of-Being-Closed.pdf
  • 领域建模 http://www.aptprocess.com/whitepapers/DomainModelling.pdf
  • 我的业务逻辑去哪里了? http://blog.unhandled-exceptions.com/index.php/2008/12/26/services-anemic-domain-models-and-where-does-my-business-logic-go/
  • 传输对象与业务对象 https://dzone.com/articles/transfer-obejcts-vs-business
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Enterprise Java 实体应该是愚蠢的吗? 的相关文章

  • 使用比较器对对象进行排序给出空指针

    我正在尝试对包含 3 张卡的 ArrayList 进行排序 我正在用比较器来做这件事 这是否太过分了 Card getRank 返回 2 到 14 之间的整数 我完全不知道哪里出了问题 我之前已经成功完成了这个 并与我的其他代码进行了比较
  • java.lang.NoClassDefFoundError:HttpSessionListener

    我正在尝试部署一场我没有编写的战争 但我在日志中收到此错误 java lang NoClassDefFoundError HttpSessionListener 我知道 HttpSessionListener 位于servlet api j
  • 如何在流中收集到TreeMap中?

    我有两个Collectors groupingBy在流中 我需要收集所有信息TreeMap 我的代码 Map
  • java.sql.SQLException: ORA-01005: 给定的密码为空;登录被拒绝

    我在尝试连接到数据库时遇到以下异常 java sql SQLException ORA 01005 null password given logon denied at oracle jdbc driver T4CTTIoer proce
  • 使用 Gson 序列化时如何公开类名

    我的场景非常复杂 但总结如下 我试图了解编译器的源代码 并了解每个 AST 节点代表什么 我正在生成不同程序的 AST 的 JSON 序列化 然后检查可视化的 JSON 输出 它工作得很好 除了一个问题是在 Gson 中生成的 JSON 数
  • Jackson Json 将对象反序列化为列表

    我正在使用 Spring 的 Web 服务RestTemplate并反序列化Jackson 在来自服务器的 JSON 响应中 其中一个字段可以是对象或列表 这意味着它可以是 result or result 有没有办法通过对我要反序列化的类
  • 黄瓜与 Micronaut

    我正在尝试将 Cucumber 与 Micronaut 一起使用 但当我尝试将其与 Cucumber 一起使用时 MicronautTest 注释根本不起作用 未注入 theApple 请参阅下面的代码 如果我在没有黄瓜的情况下运行它就可以
  • @NotNull.List 的目的

    当我查看标准时限制条件 http docs oracle com javaee 6 api javax validation constraints package summary html在 Bean Validation API JSR
  • 从继承的受保护 Java 字段创建公共访问器

    我怎样才能完成以下工作 class Foo extends javax swing undo UndoManager increase visibility works for method override def editToBeUnd
  • Java 中的本机方法

    我花了一些时间学习什么是 Java Native 方法以及它们是在平台相关代码 主要是 C 中实现的 但是我在哪里可以找到这些 Java 的本机实现呢 例如 Thread 类的 sleep long millis 方法是本机的 但它的实现代
  • 如何将 wsdl 内部架构设置为 Jaxb2Marshaller 以验证我所做的每篇文章?

    我正在使用 SOAP Web 服务 在调用它之前我必须验证每个 xml 帖子 所以我正在使用 The CXF codegen 插件生成POJO树结构 第三部分 wsdl xxxx soap service wsdl 一个类实现Web服务网关
  • 在 Java 5 及更高版本中迭代 java.util.Map 的所有键/值对的最简单方法是什么?

    在 Java 5 及更高版本中迭代 java util Map 的所有键 值对的最简单方法是什么 假设K是您的密钥类型 并且V是你的值类型 for Map Entry
  • 在 JSON 对象中强制执行非空字段

    我们的 REST API 接收一些 JSON 对象输入 其中某些字段要求不为空 这些可以是字符串 整数 甚至可以是其他一些类实例作为参考 我们正在尝试找到一种方法来强制这些字段不为空 而不是在 API 中进行空检查的正确方法 当前的 if
  • 如何使用 UUID 生成唯一的正 Long

    我需要为我的数据库主键列生成唯一的长 ID 我以为我可以用UUID randomUUID getMostSignificantBits 但有时它也会产生一些负多头 这对我来说是个问题 是否可以从 UUID 中仅生成正长 将会有数十亿个条目
  • kafka Avro 多个主题的消息反序列化器

    我正在尝试以 avro 格式反序列化 kafka 消息 我使用以下代码 https github com ivangfr springboot kafka debezium ksql blob master kafka research c
  • 如何减少 JSF 中的 javax.faces.ViewState

    减少 JSF 中视图状态隐藏字段大小的最佳方法是什么 我注意到我的视图状态约为 40k 这会在每次请求和响应时下降到客户端并返回到服务器 特别是到达服务器时 这对用户来说会显着减慢 我的环境 JSF 1 2 MyFaces Tomcat T
  • 在 Java 中打开现有文件并关闭它。

    是否可以在java中打开一个文件附加数据并关闭多次 例如 psuedocode class variable declaration FileWriter writer1 new FileWriter filename fn1 writer
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • 根据 Java 环境变量中的值创建使用 @JsonIgnore 的自定义注释

    我需要创建一个新的注释 用于在环境变量设置时忽略输出 JSON 文件中的字段var false 我尝试使用JsonAnnotationIntrospector 但无法获得预期的输出 public class Vehicle String v
  • 在Java的System.out中以表格格式输出

    我正在从数据库获取结果 并希望将数据作为 Java 标准输出中的表输出 我尝试过使用 t 但我想要的第一列的长度变化很大 有没有办法将其显示在类似输出的漂亮表格中 Use System out format http java sun co

随机推荐

  • Ruby 中的 class << self 习惯用法

    什么是class lt lt self do in Ruby 首先 class lt lt foo语法打开foo的单例类 eigenclass 这允许您专门化在该特定对象上调用的方法的行为 a foo class lt lt a def i
  • Python Gtk.Entry 占位符文本

    我有一个登录窗口 有两个 gtk Entry 对象 一个用于用户名 一个用于密码 我如何向条目添加一些幽灵文本 因此条目中写有 用户名 但如果您单击内部 文本就会消失 从 Gtk 3 2 开始 可以设置占位符文本 http develope
  • IPython shell 的换行问题

    如果我在 IPython 中运行了很长的一行 并尝试调用它 使用向上箭头 或在当前行的开头处退格 则它显示不正确 全部挤成一行 例如 在下面的会话中我写了很长的一行 1 输入了一个有点空白的行 2 然后向上箭头两次以获得print网上声明
  • 如何隐藏system()输出

    我正在 Windows XP 上工作 我可以通过调用自动执行 ssh 会话的 TCL 脚本 通过浏览器成功运行 system 命令 我还从脚本返回一个值 但是我的问题是脚本将整个 ssh 会话转储到浏览器中 我的 php 脚本如下所示 la
  • 下拉列表问题

    我遇到一个问题 IE 6 7 中的下拉列表的行为如下 可以看到下拉的width宽度不够 无法在不扩展整个下拉列表的情况下显示整个文本 但是在 Firefox 中 没有问题 因为它expands the width因此 这是我们在 IE 6
  • 使用 NetworkStream.BeginRead 和 NetworkStream.EndRead 实现超时

    我编写了以下函数来实现超时功能NetworkStream的异步读取函数 BeginRead and EndRead 在我注释掉该行之前它工作正常Trace WriteLine bytesRead bytesRead Why private
  • Chartjs:如何删除特定标签

    我有一个包含这些数据和选项的条形图 var data labels periodnames datasets yAxisID bar stacked data rcash backgroundColor FFCE56 label yAxis
  • 如何将 JTextPane 中的文本和 JComponent 垂直居中?

    目前看起来是这样 该怎么做才能看起来如此 下面是我的代码 JFrame f new JFrame JTextPane textPane new JTextPane JTextField component new JTextField co
  • 将会话 ID 作为 url 参数传递的危害

    所以我刚刚注意到互联网银行网站之一正在将会话 ID 作为 url 参数传递 见下图 我以前没有在任何地方看到 在 url 中 在本例中它位于 private 之后 1 这个 有什么用 2 为什么互联网银行 需要成为互联网上最安全的地方 将会
  • 如何使用 Watir-WebDriver 将文本发送到 CKEditor WYSIWYG 编辑器框

    我有一个 watir webdriver 脚本 它使用下面的代码设置 CKEditor 框 但这仅适用于 Mac OSX 上的 Firefox 当我专注于屏幕时 例如 如果我集中注意力并让此脚本在后台运行 则不会输入文本 但不会引发异常或错
  • onAnimationEnd() 被调用两次

    从 23 更新构建 sdk 27 后 在调用下面的代码时遇到了 onAnimationEnd 触发两次的问题 onAnimationStart 仅调用一次 并且 onAnimationRepeat 未按预期调用 现在 在应用程序中 当用户按
  • 使用beautifulsoup和python提取标签信息

    假设我有一些像
  • Jenkins Pipelines:加载外部 Jenkins 管道脚本时重用工作区

    我有以下用例 使用编写的管道脚本签出 拉取某个 Git 修订版 我需要这个 因为我动态检索修订版 从该修订版本中 加载位于之前签出的文件中的 Jenkins pipeline file 该文件将依赖于同一签出版本的文件 因此 从same工作
  • 向流量数据添加自定义属性

    问题 当我将数据传递到 flot 时 如果我可以传递一些我想要访问的补充数据 那将非常方便plotclick事件被触发 My Data 这是一些标准数据 label first data 5 color 123 label first da
  • Windows 批处理脚本:将所有文件的名称、路径、大小和所有者列出到 csv 文件中

    我有一个脚本 可以列出文件夹及其子文件夹下的所有文件 以及一些属性 例如路径 文件名 修改日期和大小 但是 我无法添加一项额外的属性 文件所有者 ECHO off SET v1 dpF SET v2 nxF SET v3 zF for r
  • 在 firestore get 查询中使用通配符

    我想在 firebase 中创建一个云函数 每当用户第一次登录时就会触发该函数 该函数需要将特定用户身份验证中的 UID 添加到 firestore 中特定的现有文档中 问题是需要将 UID 添加到我不知道位置的文档中 我现在的代码并不能完
  • 在 Python 3.6 中使用 pandas.to_sql 将外来(非 ASCII)字符写入 Oracle DB

    我很难从 a 中写入值pandas DataFrame其中包含 Oracle 数据库的非 ASCII 字符 这是一个可重现的示例 给定真实的连接字符串 import pandas as pd from sqlalchemy import c
  • 将自定义视图添加到警报视图

    我有这样的问题 我想在警报视图中显示自定义视图 所以我创建了一个单独的 xib 文件并设计了我的界面 并为其实现了该类 但是当我应用下面的代码时 它给了我一个错误 这是代码 UIAlertView alert UIAlertView all
  • 如何在编辑模式下重新格式化自定义 UITableViewCell 以适应删除控件?

    我有一个自定义 UITableViewCell 其中包含一个 UILabel 其中显示可变数量的文本 单元格的高度是动态计算的 以适应文本量 问题是 UILabel 文本在编辑模式 删除 期间没有重新格式化 如以下屏幕截图所示 我需要使用自
  • Enterprise Java 实体应该是愚蠢的吗?

    在我们遗留的 Java EE 应用程序中 有大量值对象 VO 类 它们通常只包含 getter 和 setter 也许equals and hashCode 这些 通常 是要保存在持久性存储中的实体 根据记录 我们的应用程序没有 EJB 尽