ということでEffective Java 第2版を読んでいくのです
項目1. コンストラクタの代わりにstaticファクトリメソッドを検討する
オブジェクトの生成:基本的にはnewする(コンストラクタを呼ぶ)のですが別の方法もあります。
…
staticファクトリメソッド
static ファクトリメソッドとは?-クラスのインスタンスを返す、staticなメソッド
*例:Boolean valueOf(boolean b)はnewせずにBoolean.TRUEまたはBoolean.FALSEのクラス変数を返す。
staticファクトリの長所
1. コンストラクタは名前(メソッド名)がもてないけどstaticファクトリメソッドはもてる
コンストラクタのシグネチャ(※1)ではそれがどんなインスタンスを生成するのかわからない (メソッド名がクラス名と同じでなければいけない)
→staticファクトリだと名前をつけられるのでよりわかりやすくなる
コンストラクタがいっぱいあってわかりずらくなる場合はstaticメソッドファクトリに書き換えるチャンス
参考:メソッドのシグネチャとは? = 世界(VM)がメソッドを一意に特定するための情報
メソッドの、「メソッド名」「引数の数」「引数の型」の3つのグループ
シグネチャは英語で署名という意味で、こいつのアイデンティティのことを指す、
つまり世界(VM)がメソッドを一意に特定するための情報 を指すということです。
2. newしなくてもいい(ライフサイクルを制御できる)
オブジェクトの生成を毎回newする(コンストラクタのパターン)以外の選択肢を持てる
例:・インスタンスはあらかじめあるものを使う
・キャッシュみたいになかったらつくる
・毎回newする
既存のインスタンスを使いまわせる =ある時点でどのようなインスタンスが存在するかを制御できる(インスタンス制御)
インスタンス制御されることのメリット
・クラスがシングルトン、インスタンス化不可能であることが保証される
・不変クラスで、インスタンスは世界でただ1つしか存在しかないことも保証できる。
同値性・等価性の比較として、equalsメソッドの代わりに==演算子を使える
メモリ比較だけだから、==演算子の方がequalsより処理が速いため、
パフォーマンスがよくなる。
staticファクトリメソッドはデザインパターンの1つであるFlyweightパターンに似ている
そしてFlyweightパターンは
DIコンテナの設計に似ている。
すなわちstaticファクトリメソッドの考え方はDIの思想に近いところがある
*例:enum
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { ... protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { T result = enumType.enumConstantDirectory().get(name); if (result != null) return result; if (name == null) throw new NullPointerException("Name is null"); throw new IllegalArgumentException( "No enum constant " + enumType.getCanonicalName() + "." + name); } ... }
インスタンス制御するための方法
enumのオブジェクトの生成のように、
・コンストラクタをprivateにする(提供しない)=newさせない
・staticファクトリメソッドだけを提供する
という形でつくることができます。
つづく