Tagbangers Blog

Effective Java読み直し1-staticファクトリメソッド(1)

ということで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ファクトリメソッドだけを提供する
という形でつくることができます。

つづく