ソフトウェアエンジニアリングでは、プレーンオールドJavaオブジェクト(POJO )は、特別な制約を受けない通常のJavaオブジェクトです。この用語は、2000年9月にMartin Fowler、Rebecca Parsons、Josh MacKenzieによって造語されました。 [ 1 ]
なぜ人々がシステム内で通常のオブジェクトを使用することにこれほど抵抗を示すのか疑問に思い、単純なオブジェクトには気の利いた名前がないからだと結論付けました。そこで、私たちはそれらに名前を付けたところ、非常に好評を得ました。
「POJO」という用語は、当初は主要なJavaオブジェクトモデル、規約、フレームワークのいずれにも従わないJavaオブジェクトを指していました。しかし、複雑なオブジェクトフレームワークとは対照的な、共通かつ分かりやすい用語が必要とされたことから、その後、言語に依存しない用語として広く採用されるようになりました。
この用語は、斬新な機能を使用しない構成要素に対してレトロニム(後付けの略語)を造語するという、頭字語のパターンを継続している。
理想的には、POJOはJava言語仕様によって課せられる制約以外の制約を受けないJavaオブジェクトです。つまり、POJOは次のような制約を受けるべきではありません。
import javax.servlet.http.HttpServlet ;public class Foo extends HttpServlet { // ... }import javax.ejb.EntityBean ;public class Bar implements EntityBean { // ... }import javax.persistence.Entity ;@Entity public class Baz { // ... }しかし、技術的な問題やその他の理由により、POJO準拠とされている多くのソフトウェア製品やフレームワークでも、永続化などの機能を正しく動作させるには、事前に指定されたアノテーションの使用が依然として必要となります。その考え方は、オブジェクト(実際にはクラス)がアノテーションが追加される前はPOJOであり、アノテーションが削除されるとPOJOの状態に戻るのであれば、それは依然としてPOJOとみなせるというものです。つまり、基本的なオブジェクトは、それを「特殊化されたJavaオブジェクト」(SJOまたはSoJO)にする特別な特性(実装されたインターフェースなど)を持たないため、POJOのままです。
JavaBeanは、シリアライズ可能で、引数なしのコンストラクタを持ち、シンプルな命名規則に従うゲッターおよびセッター メソッドを使用してプロパティにアクセスできるPOJO です。この規則により、任意の JavaBean のプロパティに対して、シンプルな宣言的参照を行うことができます。このような宣言的参照を使用するコードは、Bean の型について何も知る必要がなく、Bean は多くのフレームワークで使用できますが、これらのフレームワークは Bean の正確な型を知る必要はありません。JavaBeans 仕様を完全に実装すると、クラスが真の JavaBean であるためにはSerializableインターフェイスを実装する必要があるため、POJO モデルがわずかに壊れます。JavaBeans と呼ばれる多くの POJO クラスは、この要件を満たしていません。Serializable はマーカー (メソッドなし) インターフェイスであるため、これは大きな負担にはなりません。
以下に、 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ライブラリを使用すると、コードを動的に変更して、これらの規約を記述する手間をかけずに統合できます。次のコードは、空のコンストラクタを追加した同じBeanを生成します。
@NoArgsConstructor public class MyBean { @Getter @Setter private String someProperty ; }他のライブラリやフレームワークは、これらの規約に基づいてコード(またはバイトコード)を直接生成します。これらのツールを追加することで、定型コードの記述が軽減され、結果としてバグの発生頻度とメンテナンスコストが削減されます。
POJO を使用した設計がより一般的に使用されるようになるにつれて、フレームワークで使用されるすべての機能を POJO に提供し、実際に必要な機能領域についてより多くの選択肢を提供するシステムが登場しました。このモデルでは、プログラマは POJO のみを作成します。この POJO は純粋にビジネス ロジックに焦点を当てており、(エンタープライズ)フレームワークに依存していません。アスペクト指向プログラミング(AOP) フレームワークは、永続性、トランザクション、セキュリティなどの横断的な関心事を透過的に追加します。[ 6 ]
Springはこのアイデアをいち早く実現した企業であり、このモデルを普及させる原動力の一つとなった。
EJB BeanがPOJOである例:
以下は、EJB3がPOJOモデルをどのように活用しているかを示す、完全に機能するEJB Beanの例です。
public class HelloWorldService {public String sayHello () { return "Hello, world!" ; } }前述のとおり、BeanはEJBクラスを継承したり、EJBインターフェースを実装したりする必要はなく、EJBアノテーションを含める必要もありません。代わりに、プログラマは外部のXMLファイルで、Beanに追加すべきEJBサービスを宣言します。
<enterprise-beans> <session> <ejb-name> helloWorld </ejb-name> <ejb-class> com.example.HelloWorldService </ejb-class> <session-type> stateless </session-type> </session> </enterprise-beans>実際には、注釈をエレガントだと感じる人もいれば、XMLを冗長で醜く、保守が難しいと考える人もいる。また、注釈がPOJOモデルを汚染すると考える人もいる。[ 7 ]
そのため、XMLの代替手段として、多くのフレームワーク(Spring、EJB、JPAなど)では、XMLの代わりに、またはXMLに加えてアノテーションを使用できます。以下は、上記と同じEJB Beanにアノテーションを追加したものです。この場合、XMLファイルは不要になります。
@Stateless public class HelloWorldService {public String sayHello () { return "Hello, world!" ; } }上記のように注釈を付けると、ビーンはもはや純粋な POJO ではなくなりますが、注釈は単なる受動的なメタデータであるため、クラスを拡張したりインターフェースを実装したりする侵襲性に比べると、有害な欠点ははるかに少なくなります。[ 6 ]したがって、プログラミング モデルは依然として純粋な POJO モデルと非常によく似ています。
プレーンオールドJavaインターフェース(POJI)は、Javaインターフェースの基本的な形式であり、より複雑なJavaインターフェースが許可されていない場面で使用できます。[ 8 ]: 57、572、576、579、1340