企業向けアプリケーションのさまざまな“常識”をJavaのオープンソース・フレームワーク群である「JBoss」から学んでいきましょう。企業システムを構築するうえでの基礎となる知識をリファレンス感覚で説明していきます。初心者から中堅、ベテランまで大歓迎!
前回の「“全部入り”のEclipseで学ぶ統合開発環境の常識」では、企業向けアプリケーションを構築する際に必要な要素として「統合開発環境」について説明し、実際にサンプルアプリケーションを作成し、企業向けアプリケーションの構築における、統合開発環境の機能やその重要性を学びました。
今回は、DIやAOPを通して、それらに関連するフレームワークやJBossのソフトウェアについて説明していきたいと思います。
企業向けアプリケーションの開発では、DIやAOPという言葉は、すでに常識的な技術として認識されています。これらの技術は、多くの企業向けアプリケーションを構築する際に扱われています。ここまで常識的な技術になったことは、これらの技術が開発者にとって有益であることがいえます。
まだ、DIやAOPを聞いたことがない方や実際に触ったことがない方は、ぜひその仕組みを理解していただけたらと思います。きっと、今後の企業向けアプリケーション開発に役立つことになります。それでは、DIから説明していきます。
DIとは、Dependency Injectionの略称で、「依存性(Dependency)の注入(Injection)」という意味です。Dependency Injectionという言葉を初めて聞いた方が、「依存性の注入」といわれてもあまりイメージが湧かないと思います。この「依存性の注入」とは、一体どういうことなのでしょうか?
この「依存性の注入」を説明するに当たって、最初に「依存性」の部分に焦点を当ててみたいと思います。「依存性」を表す例として、簡単なJavaのプログラムを作成してみます。以下は、会社クラス(Company)と営業部クラス(SalesDepartment)を表すプログラムです。
public class Company { /** 営業部 */ private SalesDepartment salesDepartment; /** * コンストラクタ * * @param salesDepartment */ public Company(SalesDepartment salesDepartment) { this.salesDepartment = salesDepartment; } /** * 営業部名を表示 */ public void viewDepartment() { salesDepartment.viewDepartment(); } }
/** * 営業部クラス */ public class SalesDepartment { public void viewDepartment() { System.out.println("営業部です。"); } }
/** * 実行クラス */ public class Main { public static void main(String[] args) { // 営業部を生成 SalesDepartment salesDepartment = new SalesDepartment(); // 会社を生成 Company company = new Company(salesDepartment); // 会社の部署名を表示 company.viewDepartment(); } }
このサンプルは、「会社クラスが営業部クラスを保持して、その名称を表示する」というものです。この場合、会社クラスに営業部クラスというオブジェクトを直接記述しているため、もし営業部クラスを削除した場合、参照元の会社クラスや実行クラスではコンパイルエラーが起こってしまいます。
これは、「会社が営業部を生成するには、営業部のオブジェクトを知っている必要がある」ということになります。このようにクラス間でのオブジェクトの関係している状態を「依存性」と呼びます。
「依存性」のイメージが湧いたところで、本題の「依存性の注入」について説明します。「依存性の注入」をひと言で表すと、「依存しているオブジェクトをプログラムの実行時に外部から注入すること」です。これは、どのようなことなのでしょうか? 具体的にイメージしやすいように、上記のサンプルを改良して説明していきたいと思います。
まず、「依存性の注入」を分かりやすくするために、クラス間の依存性を改善します。サンプルには営業部しかありませんが、実際の会社にはいろいろな部署が存在します。例えば、総務部、人事部、経理部、企画、広報などです。これらの抽象的な表現として、部署インターフェイスを作成し、名称を表示するメソッドを記述してみます。
/** * 部署インターフェイス */ public interface Department { void viewDepartment(); }
部署インターフェイスを作成したところで、上記のサンプルプログラムを改良してみます。まず、会社クラスのコンストラクタとフィールドを、営業部クラスから部署インターフェイスへと修正します。
public class Company { /** 部署 */ private Department department; /** * コンストラクタ * * @param department */ public Company(Department department) { this.department = department; } /** * 部署名を表示 */ public void viewDepartment() { department.viewDepartment(); } }
次に、営業部クラスに部署インターフェイスを実装させます。
public class SalesDepartment implements Department { @Override public void viewDepartment() { System.out.println("営業部です。"); } }
さらにここで、新たに部署インターフェイスを実装した人事部クラスを作成します。
/** * 人事クラス */ public class PersonnelDepartment implements Department { @Override public void viewDepartment() { System.out.println("人事部です。"); } }
では、プログラムの呼び出し元を見てみましょう。
public class Main { public static void main(String[] args) { // 部署を生成 Department department = new SalesDepartment(); // 会社を生成 Company company = new Company(department); // 会社の部署名を表示 company.viewDepartment(); } }
改良前の実行クラスでは、営業部クラスを受け皿にして、営業部のインスタンスを生成していましたが、部署インターフェイスに変更したことにより拡張性が高くなりました。例えば、新規に作成した人事部クラスを表現したい場合、実行クラスを以下のように修正するだけで済みます。
// 部署を生成 Department department = new PersonnelDepartment();
また、改良を加えたことにより、営業部クラスや人事部クラスがなくても会社クラスではコンパイルエラーが起こることはありません。クラス間の依存性は、インターフェイスを用いて、改善できました。
次ページでは、引き続きにDI(依存性の注入)について説明し、AOP(「アスペクト指向プログラミング」)も解説します。
Copyright © ITmedia, Inc. All Rights Reserved.