普通旧 Java 对象 (POJO) 是啥意思?
Posted
技术标签:
【中文标题】普通旧 Java 对象 (POJO) 是啥意思?【英文标题】:What is meaning of Plain Old Java Object (POJO)?普通旧 Java 对象 (POJO) 是什么意思? 【发布时间】:2011-03-20 13:43:55 【问题描述】:Plain Old Java Object (POJO) 是什么意思?我找不到任何足够解释的东西。
POJO's Wikipedia page 表示 POJO 是一个普通的 Java 对象,而不是一个特殊的对象。现在,在 Java 中什么使或不使和对象特别?
上面的页面还说 POJO 不应该扩展预先指定的类、实现预先指定的接口或包含预先指定的注释。这是否也意味着 POJO 不允许实现 Serializable
、Comparable
之类的接口或 Applets 之类的类或任何其他用户编写的类/接口?
另外,上述政策(不扩展,不实施)是否意味着我们不允许使用任何外部库?
POJO 到底在哪里使用?
编辑:更具体地说,是否允许我扩展/实现属于 Java 或任何外部库的类/接口?
【问题讨论】:
好问题,看起来 POJO 的真正含义有很多变化。我几乎每天都使用这个词,现在我想起来我不确定它到底意味着什么。 +1 只是不要将它与 C++ POD 混淆。 如果有人仍然难以理解含义,这里有一个来自 Spring Framework 团队的很好的解释link 【参考方案1】:Plain Old Java Object 该名称用于强调给定对象是普通 Java 对象,而不是 EJB 2 框架定义的特殊对象。
A级 B 类扩展/实现 C
注意:当 C 是一种分布式框架类或 ifc 时,B 不是 POJO。 例如javax.servlet.http.HttpServlet、javax.ejb.EntityBean 或 J2EE extn 并且不可序列化/可比较。由于可序列化/可比较对 POJO 有效。
这里 A 是一个独立的简单对象。 B 是一个特殊的 obj,因为 B 正在扩展/实现 C。因此 B 对象从 C 中获得了更多含义,并且 B 限制遵循 C 的规则。并且 B 与分布式框架紧密耦合。因此 B 对象从其定义来看不是 POJO。
使用类A对象引用的代码不必知道它的类型,它可以与许多框架一起使用。
所以 POJO 不必 1) 扩展预先指定的类和 2) 实现预先指定的接口。
JavaBean 是可序列化的 POJO 示例,具有无参数构造函数,并允许使用遵循简单命名约定的 getter 和 setter 方法访问属性。
POJO 纯粹专注于业务逻辑,不依赖(企业)框架。 这意味着它具有业务逻辑代码,但是如何创建此实例,该对象属于哪个服务(EJB..)以及它具有哪些特殊特征(有状态/无状态)将由框架通过使用外部 xml 决定文件。
示例 1:JAXB 是将 java 对象表示为 XML 的服务;这些 java 对象很简单,并提供了默认的构造函数 getter 和 setter。
示例 2:Hibernate,其中简单的 java 类将用于表示一个表。列将是它的实例。
示例 3:REST 服务。在 REST 服务中,我们将有 Service Layer 和 Dao Layer 来对 DB 执行一些操作。所以 Dao 会有供应商特定的查询和操作。 Service Layer 将负责调用哪个 DAO 层来执行 DB 操作。 DAO 的创建或更新 API(方法)将以 POJO 作为参数,并更新 POJO 并将其插入/更新到 DB。这些 POJO(Java 类)将只有每列的状态(实例变量)及其 getter 和 setter。
在实践中,有些人认为注解很优雅,而他们认为 XML 冗长、丑陋且难以维护,而另一些人则认为注解污染了 POJO 模型。 因此,作为 XML 的替代方案,许多框架(例如 Spring、EJB 和 JPA)允许使用注解来代替或补充 XML:
优点: 将应用程序代码与基础架构框架解耦是使用 POJO 的众多好处之一。使用 POJO 可以通过将应用程序的业务逻辑与易变的、不断发展的基础架构框架解耦来证明您的应用程序的业务逻辑。升级到新版本或切换到不同的框架变得更容易,风险也更小。 POJO 还使测试更容易,从而简化和加速开发。您的业务逻辑会更清晰、更简单,因为它不会与基础架构代码纠缠在一起
参考:wikisource2
【讨论】:
【参考方案2】:According to Martin Fowler,他和其他一些人想出了一种方式来描述标准类而不是 EJB 等。
【讨论】:
【参考方案3】:该术语的使用意味着它应该告诉您的内容。例如,如果依赖注入框架告诉您可以将 POJO 注入到任何其他 POJO 中,他们想说您不必做任何特别的事情:无需遵守与对象的任何约定,实现任何接口或扩展特殊课程。你可以使用你已经拥有的任何东西。
UPDATE 再举一个例子:虽然 Hibernate 可以将任何 POJO(您创建的任何对象)映射到 SQL 表,但在 Core Data(iPhone 上的目标 C)中,您的对象必须按顺序扩展 NSManagedObject以便系统能够将它们持久化到数据库中。从这个意义上说,Core Data 不能与任何 POJO(或者更确切地说 POOCO=PlainOldObjectiveCObject)一起工作,而 Hibernate 可以。 (因为我刚开始学习核心数据,我可能不会 100% 正确。欢迎提供任何提示/更正 :-))。
【讨论】:
【参考方案4】:普通的旧 Java 对象 :)
好吧,你说得好像这些都是可怕的限制。
在使用 POJO 的通常情况下,它更像是一种好处:
这意味着您使用的任何库/API 都非常愿意使用未经修改或以任何方式粗暴处理的 Java 对象,即您不必做任何特别的事情来让它们工作.
例如,XStream XML 处理器将(我认为)愉快地序列化不实现Serializable
接口的Java 类。这是一个加号!许多使用数据对象的产品曾经强迫您实现SomeProprietaryDataObject
甚至扩展AbstractProprietaryDataObject
类。许多库会期望 bean 行为,即 getter 和 setter。
通常,任何适用于 POJO 的东西也适用于非 POJO。所以 XStream 当然也会序列化 Serializable 类。
【讨论】:
【参考方案5】:POJO 是一个普通的旧 Java 对象 - 与需要企业版 (J2EE) 的东西(bean 等)相比。
POJO 并不是一个真正的硬性定义,而更像是一种描述“普通”非企业 Java 对象的手动方式。使用外部库或框架是否使对象 POJO 是旁观者的看法,很大程度上取决于 WHAT 库/框架,尽管我大胆猜测框架会使 POJO 变得不那么重要
【讨论】:
序列化和可比性也不是 POJO 吗?【参考方案6】:POJO 的全部意义在于简单,您似乎在假设它比看起来更复杂。
如果库支持 POJO,则意味着任何类的对象都是可接受的。这并不意味着 POJO 不能有注释/接口,或者如果它们存在就不会使用它们,但这不是必需的。
恕我直言,维基页面相当清晰。它并不是说 POJO 不能有注释/接口。
【讨论】:
【参考方案7】:Plain Old Java Object (POJO) 一词是什么意思?
POJO 是 Martin Fowler、Rebecca Parsons 和 Josh Mackenzie 在 2000 年 9 月的一次会议上准备演讲时创造的。Patterns of Enterprise Application Architecture 中的 Martin Fowler 解释了如何实现 Java 中的域模型 模式。在列举了使用EJB Entity Beans的一些缺点之后:
人们谈论时总会产生很多热量 在 J2EE 中开发领域模型。许多教材和 介绍 J2EE 的书籍建议您使用实体 bean 来开发一个 域模型,但是这种方法存在一些严重的问题, 至少在当前 (2.0) 规范中。
当您使用容器管理时,实体 bean 最有用 持久性 (CMP)...
实体 bean 不能重入。也就是说,如果你从一个 实体 bean 到另一个对象,那个另一个对象(或它的任何对象 调用)不能回调到第一个实体 bean...
...如果你有带有细粒度接口的远程对象,你会得到 糟糕的表现......
要使用实体 bean 运行,您需要一个容器和一个数据库 连接的。这将增加构建时间并增加时间 进行测试运行,因为测试必须针对数据库执行。 实体 bean 也很难调试。
作为替代方案,他建议使用 Regular Java Objects 来实现域模型:
另一种方法是使用普通的 Java 对象,尽管这通常 引起惊讶的反应——令人惊讶的是有多少人认为 您不能在 EJB 容器中运行常规 Java 对象。 我来了 人们忘记常规 Java 对象的结论是因为 他们没有一个花哨的名字。这就是为什么,在准备演讲时 2000 年,Rebecca Parsons、Josh Mackenzie 和我给了他们一个:POJO (普通的旧 Java 对象)。 POJO 域模型很容易组合在一起, 构建速度快,可以在 EJB 容器外运行和测试,并且是 独立于 EJB(也许这就是 EJB 供应商不鼓励你的原因 使用它们)。
【讨论】:
【参考方案8】:有很多帖子一半正确一半错误。 Rex M in their answer here 给出了正确解释的最佳示例。
[POJO 是类] 不需要任何重要的“胆量”来制作 这行得通。这个想法与非常依赖的对象相反 很难(或不能)在其上实例化和操作 拥有 - 他们需要其他服务、驱动程序、提供程序实例等。 也要在场。
不幸的是,这些完全相同的答案往往伴随着误解,即它们以某种方式简单或通常具有简单结构。这不一定正确,混淆似乎源于这样一个事实,即在 Java (POJO) 和 C# 世界 (POCO) 中,业务逻辑相对容易建模,尤其是在 Web 应用程序世界中。
POJO 可以有多个级别的继承、泛型类型、抽象等。碰巧这在大多数 Web 应用程序中不是必需的,因为业务逻辑不需要它 - 很多工作都投入到数据库中、查询、数据传输对象和存储库。
一旦您不再使用简单的网络应用程序,您的 POJO 就会开始变得更加复杂。例如。制作一个将出租车分配给用户时间表的网络应用程序。为此,您需要一个图形着色算法。要为图形着色,您需要一个图形对象。图中的每个节点都是一个调度对象。现在,如果我们想让它成为通用的,这样不仅可以通过时间表来为图表着色,还可以通过其他方式完成。我们可以使它成为通用的、抽象的并添加继承级别——几乎可以使它成为一个迷你库。
尽管如此,无论其复杂性如何,它仍然是一个 POJO,因为它不依赖于其他框架的内部结构。
【讨论】:
【参考方案9】:一个普通的旧 Java 对象 (POJO),其中包含您的扩展的所有业务逻辑。
经验。包含单个方法的 Pojo
public class Extension
public static void logInfo(String message)
System.out.println(message);
【讨论】:
以上是关于普通旧 Java 对象 (POJO) 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章
POJO(普通旧 Java 对象)和 DTO(数据传输对象)有啥区别?