2行追加してSingletonにする方法

オブジェクトをSingletonにしたいケースってたまにあると思いますけど、Javaだとこんな感じ。

public class Singleton {

	private static Singleton instance;

	private Singleton() {
		super();
		System.out.println("Singletonオブジェクト生成");
	}

	public static Singleton getInstance() {
		synchronized (Singleton.class) {
			if (instance == null) {
				instance = new Singleton();
			}
		}
		return instance;
	}
}

当たり前ですけど、いちいち実装しなければなりません。コンストラクタをプライベートにして、staticでインスタンスを持たせて、getInstanceメソッドでは念のためsynchronizedで囲って・・と、結構煩わしいですね。しかもそういう目に遭う度に同じようなコードを書かなくちゃならない。ただ、そう言うもんだと何の疑問も持っていませんでした。

同じような局面にRubyで出会った時、会社のRubistにあっさりと、それrequire 'singleton' で、と言われて目から鱗

require 'singleton'
class Singleton
  include Singleton
  
  def initialize
    puts 'Singletonオブジェクト生成'
  end
  
end

require 'singleton'しておいて、include Singletonすればそのクラスのコンストラクタがprivateになり、クラスメソッドの#instanceが追加されるというもの。*1実質的には2行追加するのみ。

コンストラクタに引数がある場合どうすんだ?という疑問もありますけど、こういうフレキシビリティーは感動的ですらあります(笑)