はじめに
Effective Java 第2版 P6に出てくる下記の内容について深堀する。
static ファクトリーメソッドが、何度呼び出されても同じオブジェクトを返すことができることは、ある時点でどのようなインスタンスが存在するかを厳密に制御するのにも使用できます。この制御をおこなうクラスは インスタンス制御されている (instance-controlled)と言われます。
目次
結局どんな状態?
- 実行環境が、あるクラスのインスタンス数を制限している状態
- 1個の場合もあるし、複数個の場合もあるが、**「このクラスのインスタンスはn個以上存在することはありません!!」**というのを保証している状態
- 同じインスタンスが1つだけしか存在しない
- インスタンスが同じ(
a == b
)であれば、インスタンスの内容も同一(a.equal(b)
)ということ - 上記の性質により、値比較の際
equal(Object)
の代わりに==
演算子による比較が可能
具体例は?
シングルトン
インスタンスが1個であることが保証されているクラス。
下記はJavaでの記述例
// Enumで実装したパターン
// sealedで継承不可クラスになる
public class SingletonClass
{
// 外部から変更できないようにする
private static final SingletonClass INSTANCE = new SingletonClass();
// 外部から生成できないようにする
private SingletonClass() { //初期化処理 };
// インスタンス取得
public static SingletonClass GetInstance() {return INSTANCE;}
}
下記はC#での記述例
// Singletonパターン
public class SingletonClass
{
// 外部から変更できないようにする
private static SingletonClass _singleInstance = new SingletonClass();
// インスタンス取得
public static SingletonClass GetInstance(){ return _singleInstance; }
// 外部から生成できないようにする
private SingletonClass(){
//初期化処理
}
}
Enum
インスタンスがn個であることが保証されているクラス。 ※追記:Javaのみ
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
追記:ただし、C#のEnumはインスタンスがn個であることが保証されて いない。
クラスとして実装されているJavaと違って、C#のEnumはCの列挙型のように、名前付きの整数に過ぎないので、Javaと同様の保証はされない。
詳細はコメント欄を参照。
C#ではEnumでシングルトン作れないの?
蛇足だが気になったので調査する。
Javaでは下記のようにしてEnumを使用してシングルトンを実装することができる。
public enum Singleton {
INSTANCE;
public void execute (String arg) {
// インスタンス取得など、お目当ての処理を実装
}
}
同様にしてC#でもEnumでシングルトンを実装できないのか?というのが疑問である。
調査の結果、 C#はEnumそのものにフィールドやメソッドを定義することができないため、Javaと同様にSingletonを作るのは難しいということが判明した。
仮にEnumを使って実装するとしたら、下記のように 拡張メソッド を使用する必要がある
追記:コメントで指摘があったが、そもそもC#のEnumは名前付き整数に過ぎないため、インスタンス数の制限を保証できない。
そのため、C#でEnumを利用したシングルトンの実装はできない