はじめに
Java Enterprise Edition(Java EE)は長年にわたり、さまざまな業界(銀行業、保険業、小売業、接客業、旅行業、電気通信業など多数)においてエンタープライズビジネスアプリケーションを開発し配備するための最上のプラットフォームであり続けてきました。それはとりもなおさず、銀行基幹業務オペレーションから航空座席予約エンジンに至るまであらゆるものをサポートする堅牢でスケーラビリティの高い分散アプリケーションを構築できる標準ベースのプラットフォームをJava EEが提供していることによります。とはいえ、出来のよいJava EEアプリケーションを開発するのは必ずしも容易ではありません。まず、Java EEプラットフォームには数多くの選択肢があるためどれを使うかで迷ってしまいます。実にさまざまなフレームワーク、ユーティリティライブラリ、統合開発環境(IDE)、ツールオプションがあるため、選択はより難しくなっています。そのため、Java EEベースのソフトウェアを開発する際には、適切なテクノロジを選ぶことが非常に大事です。確固としたアーキテクチャとデザインの原則に基づいてテクノロジを選択すれば、保守や再利用や拡張が容易なアプリケーションを構築するのに大いに役立つでしょう。
この記事では、Java EEアプリケーションのアーキテクチャとデザインの基本事項を説明します。これらはアプリケーション全体を開発するための土台となります。
まずは、分散コンピューティングとn層アプリケーションアーキテクチャの発展過程を簡単に紹介します。次に、分散アプリケーションの開発においてJava EEプラットフォームアーキテクチャがどのように役立つのかを示します。またMVC(Model-View-Controller)アーキテクチャ原則にも触れます。その後、MVC原則とJava EEを組み合わせて多層Java EEアプリケーションアーキテクチャを構築します。
アプリケーションアーキテクチャが整ったら、オブジェクト指向原則に基づいたJava EEアプリケーションデザインに取り組みます。デザインパターンを使ってアプリケーションデザインならびにベストプラクティスの選定を単純化する方法についても説明します。さらにJava EEデザインパターンカタログにも言及します(これはSunのJava BluePrintsでドキュメント化されたもので、その後『Core J2EE Design Pattern』(Deepak Alur他著、Prentice Hall刊、2003年)で詳細に論じられています)。そして最後にUML(Unified Modeling Language)ならびにJava EEのデザインとアーキテクチャを視覚的に記述するUMLの役割について概説します。
この記事は『Pro Java. EE Spring Patterns: Best Practices and Design Strategies Implementing Java EE Patterns with the Spring Framework』(Dhrubojyoti Kayal著)のある章を基にしており、Apressから転載の許可を得ています。
分散コンピューティングの発展
分散コンピューティングでは、アプリケーションをいくつかの部分に分割し、それぞれを別々のコンピュータ上で同時に実行します。これは「ネットワークコンピューティング」とも呼ばれます。分割された各部分がネットワークを通じて(一般にTCP/IPまたはUDPの上に築かれたプロトコルを使って)相互に通信するからです。この各部分のことを「層(tier)」と呼びます。それぞれの層は、接続層またはクライアント層によって利用される独立したサービス群を提供します。これらの層はさらに「レイヤ(layer)」に分割することができ、各レイヤはさらに細分化された機能を提供します。大抵のアプリケーションは次のような3つのレイヤを持っています。
- 「プレゼンテーションレイヤ」―ユーザーインターフェースを担当します。
- 「ビジネスレイヤ」―ビジネスルールを実行します。その過程でデータアクセスレイヤとの対話も行います。
- 「データアクセスレイヤ」―エンタープライズ情報システム(EIS)に格納されたデータの取得と操作を担当します。
分散アプリケーションアーキテクチャの漸進的な変遷を分析すれば、ネットワークコンピューティングの現状に対する理解が深まるでしょう。以下の数セクションでは、分散アーキテクチャの変遷について例を挙げながら説明します。
単層アーキテクチャ
単層アーキテクチャの起源は、ダム端末で接続されたモノリシックなメインフレームの時代までさかのぼることになります。当時は、ユーザーインターフェース、ビジネスルール、データといったレイヤから成るアプリケーション全体が同じ物理ホスト上に配置されていました。ユーザーは端末またはコンソールを使ってこれらのシステムと対話していましたが、そうした端末はテキストベースの非常に限られた処理機能しか持っていませんでした(図1を参照)。
2層アーキテクチャ
1980年代の初期には、パーソナルコンピュータ(PC)の人気が高まりました。PCはダム端末に比べて廉価で処理能力も高かったからです。これによって真の分散(「クライアント/サーバ」)コンピューティングへの道が開かれたのです。こうしてクライアントまたはPCがユーザーインターフェースプログラムを実行するようになりました。これらはグラフィカルユーザーインターフェース(GUI)もサポートしていたので、ユーザーはGUIを使ってデータの入力やメインフレームサーバとの対話ができました。メインフレームサーバはビジネスルールとデータだけをホストするようになりました。データ入力が完了したら、GUIアプリケーションは必要に応じて妥当性検証を行ってから、ビジネスロジックの実行のためにデータをサーバに送ることができました。Oracle Formsベースのアプリケーションは2層アーキテクチャの好例です。GUIを提供するフォームはPC上にロードされており、ビジネスロジック(ストアドプロシージャとしてコーディングされたもの)とデータはOracleデータベースサーバ上にあります。
その後、また違った形の2層アーキテクチャが出現しました。UIだけでなくビジネスロジックもクライアント層に配置するというものです。この種のアプリケーションは一般にデータベースサーバに接続して種々のクエリを実行しました。こうしたクライアントは実行可能コードのかなりの部分がクライアント層にあるため、「シック(thick)」クライアントまたは「ファット(fat)」クライアントと呼ばれました(図2を参照)。
3層アーキテクチャ
2層のシッククライアントアプリケーションは開発こそ容易ですが、ユーザーインターフェースやビジネスロジックに変更があると、すべてのクライアントについてソフトウェアアップグレードを実施する必要があります。幸いなことに、90年代の中期にハードウェアの価格が下がり、CPUの処理能力が大きく向上しました。このことに加えて、インターネットとWebベースのアプリケーション開発が拡大したことで、3層アーキテクチャが出現しました。
3層アーキテクチャモデルでは、クライアントPCに必要なのは、サーバから送られてくるプレゼンテーション内容を表示するためのブラウザなど、あまり多くの機能を持たないクライアントソフトウェアだけです。サーバはプレゼンテーション、ビジネスロジック、およびデータアクセスロジックをホストします。アプリケーションデータはリレーショナルデータベースなどのエンタープライズ情報システムから取得されます。このようなシステムでは、ビジネスロジックにリモートアクセスできるので、Javaコンソールアプリケーションでスタンドアロンのクライアントをサポートできます。ビジネスレイヤは一般にデータアクセスレイヤを通じて情報システムと対話します。アプリケーション全体がサーバに置かれているところから、このサーバは「アプリケーションサーバ」とか「ミドルウェア」とも呼ばれます(図3を参照)。
n層アーキテクチャ
インターネットの帯域幅が拡大すると、世界中の企業が自分たちのサービスをWeb対応にしました。その結果、アプリケーションサーバはプレゼンテーションレイヤのタスクという重荷を負わずに済むようになりました。このタスクはプレゼンテーション内容を生成する特殊化されたWebサーバが肩代わりするようになったのです。このプレゼンテーション内容はクライアント層のブラウザに転送され、クライアント層はユーザーインターフェースのレンダリングを行います。n層アーキテクチャにおけるアプリケーションサーバはリモートアクセスが可能なビジネスコンポーネントをホストします。これらにはプレゼンテーションレイヤのWebサーバがネットワークを通じてネイティブなプロトコルを使ってアクセスします。図3はn層アプリケーションを図解したものです。
Java EEアーキテクチャ
n層分散アプリケーションの開発は複雑で挑戦しがいのある仕事です。処理を別々の層に振り分けると、リソースをうまく利用できるようになります。また層ごとに最も適した人材を割り当てることも可能になります。例えば、WebページのデザイナはWebサーバのプレゼンテーションレイヤに集中的に力を注ぐことができますし、データベース開発者はストアドプロシージャや関数の開発に専念できます。ただし、これらの層を孤立したサイロとして放置しておいたのでは何の役にも立ちません。エンタープライズとしての大きな目標を達成するためには、それらを統合する必要があります。これを行うために最も効率的なプロトコルを活用することが非常に重要になります。そうしないと、パフォーマンスの大幅な低下を招きます。
分散アプリケーションでは、統合だけでなく、さまざまなサービスが必要になります。異種の情報システムと対話すると共に、トランザクションの作成、参加、および管理ができなければなりません。エンタープライズデータの同時処理を保証するためには、このことが絶対に必要です。n層アプリケーションはインターネットを通じてアクセスされるので、不正なアクセスを防ぐために強力なセキュリティサービスが不可欠です。
今日、CPUやメモリといったハードウェアの価格は劇的に下がっています。それでも、プロセッサがサポートするメモリ量など、一定の制限が存在します。従って、システムリソースの使い方を最適化する必要があります。現代的な分散アプリケーションは一般にオブジェクト指向テクノロジを利用して作られています。そのため、オブジェクトキャッシュやオブジェクトプールといったサービスが非常に使いやすくなっています。これらのアプリケーションはリレーショナルデータベースやその他の情報システム(メッセージ指向のミドルウェアなど)とよく対話します。けれども、これらのシステムとの接続を開くのはコストのかさむ処理です。なぜなら、多くのプロセスリソースを消費し、パフォーマンスを大幅に低下させる可能性があるからです。このようなシナリオでは、パフォーマンスを高めると共にリソースの使用を最適化するために接続プールが大きな効果を発揮します。
一般に分散アプリケーションでは、トランザクション、セキュリティ、プーリングといったシステムサービスを活用するためにミドルウェアサーバを使用しています。これらのサービスへのアクセスには、ミドルウェアサーバAPIを使用しなければなりませんでした。そのため、アプリケーションコードがベンダに固有のAPIで汚されることになりました。このようにベンダAPIに縛られると、多くの開発時間が浪費され、保守が非常に難しくなり、移植性も低下します。
1999年、Sun Microsystemsは分散多層エンタープライズアプリケーションの開発の困難さに対処するため、Java EE 2プラットフォームをリリースしました。このプラットフォームはJava Platform、Standard Edition 2に基づいていたので、「一度書けばどこにでも配備し実行できる」という利点がありました。このプラットフォームは仕様に基づいていたため、オープンソースコミュニティと、IBM、Oracle、BEAなどの有力ベンダから強力な支持を得ることができました。仕様で定められた契約に従ってさえいれば誰でもサービスを開発できたのです。仕様とプラットフォームは進化し続けています。プラットフォームは現在Java Platform、Standard Edition 5に基づいており、これはJava Platform、Enterprise Edition 5と呼ばれています。この記事では、この最新バージョン(公式にJava EE 5と呼ばれている)を扱うことにします。