【Java】コンストラクタの代わりにStaticFactoryMethodを使う

オブジェクト指向の言語では、コンストラクタという概念がある。
一般的に以下のような形で記述する。

package staticFactoryMethod;

public class Task {
    private int num;
    
    public Task(int num) {
        this.num = num;
    }
}

ただ、コンストラクタは以下の仕様を実現することが出来ない。

  • 生成されるインスタンスの数を1つに制限する
  • 引数の値に応じてサブクラスを戻り値にする

そこで検討すべきであるのが、StaticFactoryMethodである。

インスタンスの生成を制限

package staticFactoryMethod;

public class Singleton {
    private static Singleton singleton = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return singleton;
    }
}

こんな感じに記述すれば、
SingletonクラスのインスタンスはgetInstanceメソッドを通じてしか取得されないし、
返されるインスタンスはいつも同じである。(Singletonパターンに該当)

package staticFactoryMethod;

public class StartUp {

    public static void main(String[] args) {
        // エラーになる
        // Singleton singleton = new Singleton();
        
        // いつでも同じインスタンスを取得可能
        Singleton singleton = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();
        
        // 実行結果: true
        System.out.println(singleton==singleton2);
    }

}

サブクラスを戻り値にして実装を隠す

また、引数の値に応じて異なるクラスを返すことが出来る。
使用者は自分がSmallTaskを手に入れたのかBigTaskを手に入れたのかを
気にせずに使うことが出来る。(実装を隠せる)

package staticFactoryMethod;

public abstract class Task {
    public static Task newInstance(int num) {
        return num>10 ? new BigTask(num) : new SmallTask(num);
    }
}
package staticFactoryMethod;

public class StartUp {

    public static void main(String[] args) {
        Task task = Task.newInstance(64);
        
        // 実行結果: class staticFactoryMethod.BigTask
        System.out.println(task.getClass());
    }

}