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