ソフトウェア工学において、プレーンオールドJavaオブジェクト(POJO)とは、特別な制約を受けない通常のJavaオブジェクトを指します。この用語は、2000年9月にマーティン・ファウラー、レベッカ・パーソンズ、ジョシュ・マッケンジーによって造語されました。[ 1 ]
なぜ人々がシステムで通常のオブジェクトを使うことにそれほど抵抗を感じるのか疑問に思い、単純なオブジェクトには派手な名前がないからではないかと結論づけました。そこで、オブジェクトに名前を与えてみたところ、とても好評でした。
「POJO」という用語は当初、主要なJavaオブジェクトモデル、規約、フレームワークのいずれにも従わないJavaオブジェクトを指していました。その後、複雑なオブジェクトフレームワークとは対照的に、共通かつ分かりやすい用語の必要性から、言語に依存しない用語として採用されるようになりました。
この用語は、新しい派手な機能を使用しない構成を 表すレトロニムを作り出すための頭字語パターンを継続しています。
理想的には、POJO は Java 言語仕様によって強制されるもの以外のいかなる制約にも縛られない Java オブジェクトです。つまり、POJO には以下の制約は必要ありません。
javax.servlet.http.HttpServletをインポートします。パブリッククラスFooはHttpServletを拡張します{ // ... }javax.ejb.EntityBeanをインポートします。パブリッククラスBar はEntityBeanを実装します{ // ... }javax.persistence.Entityをインポートします。@EntityパブリッククラスBaz { // ... }しかし、技術的な困難やその他の理由により、POJO準拠とされている多くのソフトウェア製品やフレームワークは、実際には永続化などの機能を正しく動作させるために、事前に指定されたアノテーションの使用を必要とします。これは、オブジェクト(実際にはクラス)がアノテーションが追加される前はPOJOであり、アノテーションを削除するとPOJOの状態に戻る場合、依然としてPOJOと見なせるという考え方です。その場合、基本オブジェクトは、実装されたインターフェースなどの特別な特性を持たないため、「Specialized Java Object」(SJO、または(sic)SoJO)であるため、POJOのままです。
JavaBeanは、直列化可能で、引数なしのコンストラクタを持ち、単純な命名規則に従うgetter メソッドと setter メソッドを使用してプロパティにアクセスできるPOJO です。この規則により、任意の JavaBeans のプロパティに対して単純な宣言的参照を行うことができます。このような宣言的参照を使用するコードは、Bean のタイプについて何も認識する必要がなく、多くのフレームワークで、これらのフレームワークが Bean の正確なタイプを認識する必要なく、Bean を使用できます。JavaBeans 仕様は、完全に実装された場合、クラスが真の JavaBean であるためにはSerializableインターフェースを実装する必要があるため、POJO モデルをわずかに破ります。いまだに JavaBeans と呼ばれている多くの POJO クラスはこの要件を満たしていません。Serializableはマーカー (メソッドのない) インターフェースであるため、これは大きな負担にはなりません。
以下は、POJO のプロパティへの 双方向バインディングを持つJavaServer Faces (JSF) コンポーネントの例を示しています。
<h:inputText値 = "#{MyBean.someProperty}" />POJO の定義は次のようになります。
パブリッククラスMyBean {プライベートString someProperty ;パブリック文字列getSomeProperty () { somePropertyを返します; }public void setSomeProperty ( String someProperty ) { this . someProperty = someProperty ; } }JavaBean 命名規則により、単一の " " 参照は、値を取得するための" " (プロパティがブール型somePropertyの場合は " " ) メソッドと、値を設定するための " " メソッドに自動的に変換されます。 getSomeProperty()isSomeProperty()setSomeProperty(String)
Project Lombokライブラリを使えば、面倒なコード記述をすることなく、これらの規約を動的に統合できます。以下のコードは、空のコンストラクタを追加した同じBeanを生成します。
@NoArgsConstructorパブリッククラスMyBean { @Getter @SetterプライベートString someProperty ; }他のライブラリやフレームワークは、これらの規約に従って直接コード(またはバイトコード)を生成します。これらのツールを追加することで、ボイラープレートを軽減し、バグの発生頻度とメンテナンスコストを削減できます。
POJOを用いた設計が一般的になるにつれ、フレームワークで使用されているすべての機能をPOJOに提供し、実際に必要な機能領域についてより幅広い選択肢を提供するシステムが登場しました。このモデルでは、プログラマーはPOJOを作成するだけで済みます。このPOJOは純粋にビジネスロジックに焦点を当てており、(エンタープライズ)フレームワークに依存しません。アスペクト指向プログラミング(AOP)フレームワークは、永続性、トランザクション、セキュリティといった横断的な懸念事項を透過的に追加します。[ 6 ]
Spring はこのアイデアを早期に実装したものであり、このモデルを普及させる原動力の 1 つでした。
EJB Bean が POJO である例:
以下は、EJB3 が POJO モデルをどのように活用するかを示す、完全に機能する EJB Bean を示しています。
パブリッククラスHelloWorldService {パブリック文字列sayHello () { "Hello, world!"を返します。} }既に述べたように、このBeanはEJBクラスを拡張したり、EJBインターフェースを実装したり、EJBアノテーションを記述したりする必要はありません。代わりに、プログラマーは外部XMLファイルで、どのEJBサービスをBeanに追加すべきかを宣言します。
<enterprise-beans> <session> <ejb-name> helloWorld </ejb-name> <ejb-class> com.example.HelloWorldService </ejb-class> <session-type>ステートレス</session-type> </session> </enterprise-beans>実際には、アノテーションはエレガントであると考える人もいれば、XMLは冗長で見苦しく、メンテナンスが難しいと考える人もいます。また、アノテーションはPOJOモデルを汚染すると考える人もいます。[ 7 ]
そのため、多くのフレームワーク(Spring、EJB、JPAなど)では、XMLの代わりに、あるいはXMLに加えてアノテーションを使用できます。以下は、上記と同じEJB Beanにアノテーションを追加した例です。この場合、XMLファイルは不要になります。
@StatelessパブリッククラスHelloWorldService {パブリック文字列sayHello () { "Hello, world!"を返します。} }上記のアノテーションを付けると、Beanはもはや真の純粋なPOJOではなくなりますが、アノテーションは単なる受動的なメタデータであるため、クラスを拡張したりインターフェースを実装したりする必要がある場合の侵入性に比べて、有害な欠点ははるかに少なくなります。[ 6 ]したがって、プログラミングモデルは依然として純粋なPOJOモデルに非常に似ています。
POJI(Plain Old Java Interface)はJavaインターフェイスの基本形式であり、より複雑なJavaインターフェイスが許可されていない箇所でも使用できます。[ 8 ]:57、572、576、579、1340