POJO

软件工程裡的POJO（plain old Java object)，也稱為普通老式Java物件、純Java物件、一般Java物件，是沒有受特殊限制的一般Java物件，這是马丁·福勒（Martin Fowler）、Rebecca Parsons和Josh MacKenzie在2000年9月時所提出。

「POJO」一詞一開始是指不依循任何主流Java物件模型、約定或框架的Java物件，和複雜的物件模型相對。

此一詞語開啟了一連串首字母縮略字，針對不使用先進技術的構造建立返璞词。

 JavaScript裡的「普通老式JavaScript物件」（Plain old JavaScript object）
 Ruby裡的「普通老式Ruby物件」（Plain old Ruby object，簡稱PORO）  
 Perl裡的「普通老式文件」（Plain old Documentation，簡稱pod）
 .NET框架裡的「一般CLR物件」（Plain old CLR object，簡稱POCO）。
 PHP裡的「普通老式PHP物件」（Plain old PHP object，簡稱POPO。
 电话学裡的「普通老式电话服务」（Plain old telephone service，簡稱POTS）
定義
理想上，POJO是一種只受Java語言規範所限制，此外不受其他限制的Java物件，因此，POJO不應：
 繼承預定義的類型，像是
import javax.servlet.http.HttpServlet;

public class Foo extends HttpServlet { 
    // ...
}
 實現預定義的介面，像是
import javax.ejb.EntityBean;

public class Bar implements EntityBean {
    // ...
}
 包括預定義的Java注解（annotations），像是
import javax.persistence.Entity;

@Entity
public class Baz {
    // ...
}
不過，因為技術問題（例如要讓持久化正常運作）和其他原因，許多宣稱是POJO相容的軟體產品或是框架仍需要用到一些預定義的註解。

POJO的概念是若物件（其實是類別）在加入註解之前是POJO，在移除註解後仍可以視為是POJO。POJO的基本概念是：沒有特殊的特徵（例如實現特定介面），因此不是「特殊Java物件」（Specialized Java Object）。
不同環境下的定義
JavaBeans

JavaBeans是支援序列化，具有，提供getter方法和setter方法存取物件的POJO。因為此命名規則，可以對任意JavaBeans的屬性進行簡單的宣告式參考。使用這類宣告式參考的程式碼不需知道有關JavaBean類型的任何資訊，JavaBean可以用在許多的框架中，框架不需知道JavaBeans的實際型態。
若要完全實現JavaBeans規範，必須實現序列化介面，因此會稍微打破POJO的規定。因為序列化是標記介面，不需實現任何方法，在程式碼上的負擔很小。

以下是JavaServer Faces（JSF）元件和POJO屬性雙方綁定的例子：

<h:inputText value="#{MyBean.someProperty}"/>

POJO的定義如下：

public class MyBean {
    private String someProperty;

    public String getSomeProperty() {
         return someProperty;
    }

    public void setSomeProperty(String someProperty) {
        this.someProperty = someProperty;
    }
}

因為JavaBean的命名原則，單一的someProperty參考可以自動翻譯成取值的getSomeProperty()方法（或性質是布林，則是isSomeProperty()方法），以及設定值的setSomeProperty(String)方法。

Project Lombok函式庫可以動態改變程式碼，在不用寫這些程式碼的情形下進行整合。以下的程式碼會創建相同的JavaBean，再加上空的創建子：
@NoArgsConstructor
public class MyBean {
    @Getter 
    @Setter
    private String someProperty;
}
其他這類命名約定的函式庫或是框架會直接產生程式，可減少（Boilerplate code），也減少了錯誤的出現率以及維護成本。

透明地增加服務
隨著使用POJO的設計越來越普遍，已出現了為POJO提供所有功能，並且可以選擇實際需要哪些功能領域的框架。在此模型下，程式設計者創建的就只有POJO。此POJO只專注在业务逻辑，不依賴（企業級）框架。面向切面的程序设计（AOP）框架透明地加入横切关注点，像是持久性（Persistence）、事务处理、安全性等Martin, Robert C; (2008); Clean Code, Chapter 11, Pure Java AOP Frameworks。

Spring Framework是很早期實現此概念的框架，也是推廣此模型的推進者之一。

以下是一些這類的例子：
 Enterprise JavaBeans（EJB） 
 Java持久化API（JPA，包括Hibernate）
 CDI（Java EE平台的上下文和依賴入）

以下的例子是一個全功能的EJB bean，說明EJB3如何善用POJO模型的特點：

public class HelloWorldService {

    public String sayHello() {
        return "Hello, world!";
    }
}

在以上的範例中，程式碼沒有延伸任何EJB的類別，或是實現任何EJB的介面，也不需要包括EJB的註解。程式開發者會宣告外部的XML檔，說明哪些EJB服務需加在其中：

<enterprise-beans>
    <session>
        <ejb-name>helloWorld</ejb-name>
        <ejb-class>com.example.HelloWorldService</ejb-class>
        <session-type>stateless</session-type>
    </session>
</enterprise-beans>

在實務上，有些人會覺得Java註解比較優雅輕巧，認為XML冗長、醜陋，不容易維護，不過也有人比較在意Java註 解對POJO模型的污染Panda, Debu; Rahman, Reza; Lane, Derek; (2007). EJB 3 in action, Manning Publications Co., Shelter Island (NY),  (www.manning.com/books/ejb-3-in-action). Chapter 11, Deployment descriptors vs. annotations。

因此，許多框架（像Spring、EJB和JPA）提供可以不用XML的替代作法，可以不加入XML，改用註解代替。以下程式也是同一個EJB bean，但加入了註解，此例中就不需要XML檔了：

@Stateless
public class HelloWorldService {

    public String sayHello() {
        return "Hello, world!";
    }
}

因為有加入註解，此程式已不是真正的純POJO，不過註解只是被動性的元資料，和侵入式的延伸類別和實現介面來說，註解的缺點要少很多。此程式開發模型仍很像純POJO模型。

相關首字母縮略字
POJI
POJI（A Plain old Java Interface）是一種基本的Java介面，適用在不允許更複雜Java介面的應用。

相關條目
 数据传输对象（DTO）
 貧血領域模型
 KISS原则
參考資料

Category:Java
Category:计算机行话