Javaプログラミングの古典のひとつ『Effective Java』ではSingleton実現にあたってenum
を利用することが推奨されています(「項目4: privateのコンストラクタかenum型でシングルトン特性を強制する」)。先日業務においてenum
を利用したSingletonの実装を行う機会があったので、そのサンプルコードを残しておきたいと思います。
Singleton.java
public enum Singleton {
/** クラス外部から呼び出してはならない. */
INSTANCE;
private String field;
/**
* 事実上のコンストラクタ。
* インスタンスの取得にはこのメソッド以外を利用してはならない。
* @return インスタンス
*/
public static Singleton getInstance() {
if (INSTANCE.field == null) {
INSTANCE.field = "field";
}
return INSTANCE;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
System.out.println(instance1.getField()); //=> field
instance1.setField("changed field");
// 別のインスタンスを生成しているように見えるが、
// 実は同じインスタンスを使いまわしている。
Singleton instance2 = Singleton.getInstance();
System.out.println(instance2.getField()); //=> changed field
}
}
class
を用いた方法だと、とりわけ並列プログラミングにおいて考慮すべき点が増え、それに比例して実装も複雑化するのですが、enum
を使うと、ごくごくシンプルにSingletonを実現することができます。とはいえこの利用方法はenum
本来の使い方からは逸脱している――ありていにいえば「裏技」のようにも思えるので、「実装するだけでシングルトンになるinterface」が標準ライブラリにあればいいのになあと節に思う次第です(´・ω・`)