【Effective Java】第2章 項目1 : コンストラクタよりstatic factory methodを検討せよ
Javaクラスにコンストラクタを書いてインスタンスを生成するのは一般的な方法だが、それとは異なるstatic factory methodも検討するべき。以下はBooleanからの例。
public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
利点
1. 名前があることでコードが読みやすくなる。
・"恐らく素数"である値を返す BigInteger(int, int, Random) よりは、BigInteger.probablePrimeの方が分かりやすく、使いやすい。
・また、名前があるので一つのクラスに複数持つことが可能。コンストラクタの場合、複数持たせるために引数の順番を変えるなどをすることはできるが、可読性は大きく下がる。
2. コンストラクタとは違い、呼び出される度に新オブジェクトを生成する必要が無い。
・キャッシュしたり既に生成されているインスタンスを利用することが可能なため、パフォーマンスの向上に寄与する。
・GoFのFlyweightパターンに似た概念。
3. 戻り値のサブタイプを返すことができる。
・例えばjavaのcollectionフレームワークは45の実装クラスがあるが、そのほとんどが一つのnoninstantiableクラス(java.util.collections)で制御されている。利用者がこのAPIを使うためにいくつものクラスを読み込む必要がなくなる。
4. サブタイプで返すため、返すオブジェクトを引数によって変更できる。
・例えばEnumSetクラスはEnumが64個以下の値しかない場合はReguarEnumSetインスタンスを、65個以上の場合はJumboEnumSetインスタンスを返す。利用者からは見えないので、今後自由に増やしていくことも可能。
欠点
1. static factory methodのみを用意してpublicコンストラクタが無い場合、サブクラスを作ることができない。
2. どのようにインスタンスを生成するかわかりづらい。
コンストラクタのようにAPIドキュメントで目立たないので、命名規則でこの欠点をカバーする必要がある。
よく利用されるメソッド
・from
・of
・valueOf
・instance or getInstance
・create or newInstance
・getType
・newType
・type
※このstatic factory methodはGoFのFactory Methodパターンとは異なり、単にクラスのインスタンスを生成するためのもの。