static ファクトリメソッドについて

はじめに

今日Effective Javaの本を読み始めました。
最初の章にstatic ファクトリメソッドについて書かれていたのですが、
字が多くてなかなかイメージしずらかったので、いつものように簡単な例を出しながら
自分なりにまとめてみました。

コンストラクタの代わりにstatic ファクトリメソッドを使う

クライアントがインスタンスを得る方法は2通りあります。
1つはクラスが提供するコンストラクタを利用する方法です。
もう1つは、クラスのインスタンスを返すstatic ファクトリメソッドを利用する方法です。
コンストラクタは毎回インスタンスを生成しますが、static ファクトリメソッドを使うと、 既存のインスタンスを使いまわすように制御することも可能になります。

実際にstatic ファクトリメソッドを利用してみます。

public class FactoryMethod {

    private static List<FactoryMethod> pool = new ArrayList<FactoryMethod>();   

    private FactoryMethod() {
    }

    public static FactoryMethod valueOf() {
        if(pool.size() == 0) {
            pool.add(new FactoryMethod());     // インスタンスを生成してプールに追加する
        }

        return pool.get(0);
    }

}

valueOf()メソッドで、既存のインスタンスが存在していないかを確認して、 ない時だけ、インスタンスを作成しています。

public class Main {
    public static void main(String[] args) {
        FactoryMethod obj1 = FactoryMethod.valueOf();
        FactoryMethod obj2 = FactoryMethod.valueOf();

        if(obj1 == obj2) {
            System.out.println("obj1とobj2は同じインスタンスです。");
        }
    }
}

f:id:xxyoko10:20200429201841p:plain

同じインスタンスを取得できました。
これで重複したオブジェクトの生成を避けることができます。

また、コンストラクタとは違って、メソッドに適切な名前を付けることができるので
コードを読みやすくなります。

デメリットもあるみたい

extendsして、サブクラスを作成することができません。
public またはprotectedのコンストラクタを持っていないからです。
f:id:xxyoko10:20200429205009p:plain

継承ができないので、コンポジションを代わりに使うことになるでしょう。

参考文献