第2回 鍵はPOJOベースのアプリケーション・デザイン


西ヶ谷岳(サン・マイクロシステムズ)
2005/7/23

  Page.1 Page.2

 第1回「JSF・Spring・Hibernateで次世代Javaに備える」では、Java EE 5.0に関連するJSRのドラフトドキュメントをレビューし、Java EEがPOJOベースのアプリケーション・デザインを推し進めるプラットフォームに変化することを理解していただいたと思います。

 第2回は、まだJava EE 5.0が利用できない現状に目を向け、JSF、Spring、Hibernateを利用した、POJOベースのアプリケーション・アーキテクチャについて解説します。なぜ、この組み合わせが最適なのか、POJOベースのデザインのメリットは何かについて、Java EE 5.0との関係と併せて解説します。

 古典的なWebアプリケーション・アーキテクチャ

 エンタープライズ・アプリケーションを設計するほとんどの場合、アプリケーションの大規模化に耐え得るメンテナンス性を確保するため、階層化アーキテクチャを採用します。J2EE 1.4の標準仕様に従った、古典的なWebアプリケーションの構成は図1で表されます。

図1 古典的なWebアプリケーション・アーキテクチャ

 すなわち、J2EEパターンに従った以下の方針でデザインを行います。

  • モジュールをプレゼンテーション層、ビジネス層、インテグレーション層に分離する
  • プレゼンテーション層には、Strutsに代表されるMVCモデルに従ったフレームワークを使用
  • ビジネス層におけるビジネス・ロジックはセッション・ビーンで実装。トランザクションおよびセキュリティ管理はEJBコンテナの機能を利用する
  • インテグレーション層におけるビジネス・オブジェクトの実装にはCMPのエンティティ・ビーンで実装。JDBCアクセスのコードを不要にする
  • 3つの層で共通に利用するビジネス・オブジェクトは、バリュー・オブジェクト(あるいはトランスファー・オブジェクト)パターンに従って、POJOとしてデザイン

 システムの要件によって、使用する技術のバリエーションは異なるかもしれませんが、デザインのベースラインとしては、これらがベストプラクティスであるといえます。

 このアーキテクチャはいったん出来上がってしまえば、非常に強固で信頼性の高い優れたアーキテクチャですが、ビジネス層とインテグレーション層でのEJBの採用は開発フェーズに苦痛を伴うものであることが問題とされてきました。その苦痛の1つは、EJBの複雑さに伴う生産性の問題であり、もう1つは、EJB単体テストの難しさです。前者の問題は、メタデータを用いたコード生成ツールであるXDocletの登場によって大幅に改善されたものの、後者の問題が残ります。EJBコンポーネントはEJBコンテナにデプロイしなければ正しくテストすることができません。EJBデプロイ時のオーバヘッドはシステムの規模に比例して、どんどん大きくなるため、テストドリブンな開発を難しくします。

 POJOベースのWebアプリケーション・アーキテクチャ

 ビジネス・ロジックをPOJOとして実装できれば、単体テストはJUnitを使って簡単に実施することができます。インテグレーション層の実装には、スタンドアロンでも実行可能なDAO(データ・アクセス・オブジェクト)として実現し、POJOとしてデザインしたビジネス・オブジェクトを直接データベースの入出力として扱うことができれば、単体テストが容易になり、アプリケーションサーバへのデプロイメントのオーバヘッドの問題も解消することができます。POJOをベースにした、よりモダンなアプリケーションのデザインは、図2で表されます。

図2 POJOベースのWebアプリケーション・アーキテクチャ

 アプリケーションを構成するコンポーネントをPOJOとして実現するためには、POJOをサポートするプラットフォーム技術が必要になります。ビジネス・ロジックをPOJOに保つためには、ビジネス・ロジックに手を加えず、トランザクション、セキュリティ、トレース出力などの前処理や後処理を織り込めるAOP(Aspect Oriented Programming)技術が必要になります。DAOの実装を容易にするためには、POJOを対象としたO/Rマッピング技術が必要になります。そして、互いの独立性が高まったコンポーネントを、アプリケーションとして結合するための技術がDI(Dependency Injection)です。JSF、Spring、Hibernateの組み合わせは、現状のJ2EE 1.4環境であっても、POJOベースのアーキテクチャに必要なAOP、DI、O/Rマッピングを提供します。そして、POJOベースで実現されたアプリケーションのコンポーネントは、Java EE 5.0環境にほとんどそのまま移行することができることに注意してください。

 それでは、なぜJSF、Spring、Hibernateが最適な組み合わせなのかをもう少し具体的に見てみましょう。

 なぜ、プレゼンテーション層はStrutsではなく、JSFなのか?

 Strutsは、Webアプリケーションのプレゼンテーション層に必要なMVCモデル、ページ遷移、入力データのJavaタイプマッピング、バリデーションを機能として持つ優れたフレームワークです。JSFは、表面上はStrutsと全く異なる仕様となっていますが、概念的にはStrutsと同等の機能を持ち、それらを再編成してより洗練された優れたアーキテクチャになっているといえます。JSFのスペックリードがStrutsの開発者であるCraig McClanahanであることからもそれは明らかですね。

 JSFはこれまでGUIビルダとの親和性ばかりがその特徴として紹介されてきました。もちろん、この機能は重要で、アプリケーション開発の初期の段階でプロトタイプが容易にでき、顧客に対してアプリケーション完成時のイメージを直感的に与えるのに役立ちます。また、プロトタイプのJSPやバッキング・ビーンのソースコードは、開発のベースとしてそのまま利用して、効率的に開発作業を進められるメリットもあります。

 しかし、JSFがStrutsより優れているより重要な点は、POJOベースの実行環境であることです。Strutsでは、HTMLフォームに入力されたHTTPパラメータは、StrutsのActionFormサブクラスのプロパティに格納されます。ビジネス・ロジックに入力データを渡すときに、このActionFormサブクラスをそのままビジネス・メソッドの引数に渡すように設計する人は恐らくいないでしょう。プレゼンテーション層とビジネス層を疎結合にするため、ActionFormのプロパティをPOJOなバリュー・オブジェクトに移し替えてから、ビジネス・メソッドの引数とするのが一般的でしょう。一方、JSFは、HTMLフォームを構成するJSP上の入力コンポーネントから、JSF-EL(#{foo.bar}の形式のJavaオブジェクトへのバインディング表現)を使って、直接POJOなオブジェクトのプロパティに入力値を設定することができます。

 もし、入力フォームのページに入力パラメータが数十個あったとすると、StrutsのActionFormでは入力パラメータを一次元的にしか扱うことができないため、ActionFormは数十個のsetter/getterがずらりと並ぶ数百行のソースコードになります。通常この数十個のパラメータは構造的な関係を持っているはずですので、ActionFormのパラメータをきれいなビジネス・オブジェクトのツリー構造に変換するためのフレームワーク開発が別途必要になります。JSFのページの場合はこのようなオブジェクトマッピングのための追加開発は必要なく、JSF-ELのバインディングを定義するだけで、複雑なオブジェクト・ツリーへの変換が可能です。

 また、JSF実行環境は、セッター・インジェクションに限定されますが、DIコンテナとしての機能を持っています。ビジネス層の入出力となるオブジェクト・ツリーとアクション・メソッドを含むバッキング・ビーンとの依存関係は、JSF設定ファイルのタグで依存性の注入を行うことができます。さらに、SpringのJSFサポート機能を組み合わせれば、バッキング・ビーンとそれが必要とする Springコンテナ管理下にあるサービス・オブジェクトとワイヤリングすることもできるようになります。JSFのDIコンテナとしての詳細については、次回により詳細に解説します。

  1/2

 INDEX

第2回 JSF、Spring、Hibernateが最適な組み合わせ
Page1
古典的なWebアプリケーション・アーキテクチャ
POJOベースのWebアプリケーション・アーキテクチャ
なぜ、プレゼンテーション層はStrutsではなく、JSFなのか?
  Page2
POJOなサービス・オブジェクトをEJBでラッピングする
ビジネス・オブジェクトはCMPではなく、HibernateでO/Rマッピングする
まとめ


Java Solution全記事一覧



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間