PR

 通常,Javaでクラスのインスタンスを生成するには,図1のように実装する。ここで,「Supplier」は共通機能を提供する公開インタフェース,「SupplierA」はその実装クラス,「User」は共通機能を利用するクラスである。Userクラスは,Supplierインタフェースが提供する共通機能を利用するために,その実装クラスであるSupplierAに対し,new演算子を用いてインスタンスを生成している(図1(1))。その後で,インタフェース「Supplier」の実装クラスのインスタンスにより提供される機能の「doSomethingメソッド」を利用している(図1(2))。

[Supplier.java]
public interface Supplier {
    void doSomething();
}
[SupplierA.java]
pulibc class SupplierA implements Supplier {
    public void doSomething(){
    ・・・・
    }
}
[User.java]
public class User {
    private Supplier    supplier;
    public void process(){
        // (1) SupplierAのインスタンスを生成
        Supplier  supplier = new SupplierA();
        // (2) SupplierのdoSomething機能を利用する
        supplier.doSomething();
・・・・
    }
}
図1●インスタンスを生成するJavaのコード例

 一見,この実装には何も問題がないように思うだろう。しかし,新たな実装クラス「SupplierB」が追加され,インスタンスの生成対象クラスがSupplierAからSupplierBに無条件に(あるいは特定条件下で)変わったとしたらどうなるか。その場合は,(1)部を次のように修正することになる。

        // (1) SupplierBのインスタンスを生成
        Supplier  supplier = new SupplierB();

 通常,公開された共通機能はさまざまなクラスから利用される。もし,Supplierの共通機能を利用するクラスがUser以外にもあったとすると,それらについても同様の修正が必要になる。

 図1に示したコードで問題なのは,共通機能を利用するUserクラスが直接,実装クラスのインスタンスを生成している点だ。Userクラスは,インタフェース「Supplier」が提供する共通機能を利用したいだけであって,インタフェース「Supplier」の実装クラスであるSupplierAやSupplierBには依存したくない。共通機能の提供側が,その実装クラスに依存せずに,共通機能を利用できるよう配慮する必要がある。

Factory Methodで間接化する

 この課題に対応するには,「Factory Method」と呼ばれるデザイン・パターンを用いればよい。Factory Methodとは,オブジェクトの生成を受け持つメソッド(factory method)を介して,間接的にオブジェクトを生成する方法のこと。インスタンス生成を個別に行わせないよう,実装クラスのインスタンスを生成するメソッドを用意するのである。

 その実装例を図2に示す。SupplierFactoryクラスを設け,そこにSupplierインタフェースの実装クラスのインスタンスを生成するクラス・メソッド「createSupplier」を用意した。Userクラスは,Supplierインタフェースの実装クラスのインスタンスを直接生成するのではなく,createSupplierを利用してインスタンス生成をSupplierFactoryクラスに委ねればよい。

[SupplierFactory.java]
public class SupplierFactory {
    public static Supplier  createSupplier(){
        // Supplierの実装クラスのインスタンスを生成して返す
    }
}
[User.java]
public class User {
    public void process(){
        Supplier  supplier = SupplierFactory.createSupplier();
        supplier.doSomething();
    }
}
図2●Factory Methodの実装例
原田 一樹(はらだ かずき)
NTTデータ 法人システム事業本部 モバイルビジネス事業部
(シニアITスペシャリスト ソフトウェアアーキテクチャ)
入社して以来,法人分野の業務システム開発に従事している。メインフレームのシステム開発が業務経験の半分以上を占めることから,「メインフレーム的な作法」を好む傾向がある。ソフトウエア開発に興味があり,日々精進している。