Rubyによるデザインパターンまとめ : singleton

Rubyによるデザインパターン

Rubyによるデザインパターン

利用する場面

オブジェクトが複数のインスタンスを生成する必要がなく、そのオブジェクトを唯一存在させたい場合。

サンプル

まずはクラス変数に唯一のインスタンスをもたせて、2つめ以降のインスタンスをつくれなくする方法。

class Fuji
  attr_reader :height
  def initialize
    @height = 3776
  end  

  @@instance = self.new

  def self.instance
    return @@instance
  end

  def erupt
    p "DOOOOOOOOOOOONNNNN!!!!!!!"
  end

  private_class_method :new
end

p Fuji.instance.height # => 3776
Fuji.instance.erupt # => "DOOOOOOOOOOOONNNNN!!!!!!!"

続いて、Rubyの組み込みモジュールを利用する方法。(構造は上と同じ。)

require 'singleton'

class Fuji
  include Singleton
  attr_reader :height

  def initialize
    @height = 3776
  end  

  def erupt
    p "DOOOOOOOOOOOONNNNN!!!!!!!"
  end
end

p Fuji.instance.height # => 3776
Fuji.instance.erupt # => "DOOOOOOOOOOOONNNNN!!!!!!!"

インスタンス自体をつくらず、クラス自体を唯一のオブジェクトとして扱うパターン。

class Fuji
  @@height = 3776
  def self.height
    @@height
  end

  def self.erupt
    p "DOOOOOOOOOOOONNNNN!!!!!!!"
  end
end

p Fuji.height # => 3776
Fuji.erupt # => "DOOOOOOOOOOOONNNNN!!!!!!!"

最後に、moduleを唯一のオブジェクトとして扱うパターン。(moduleだとそもそもインスタンスをつくれないので複数のインスタンスができることを心配しなくてよい。)

module Fuji
  @@height = 3776
  def self.height
    @@height
  end

  def self.erupt
    p "DOOOOOOOOOOOONNNNN!!!!!!!"
  end
end

p Fuji.height # => 3776
Fuji.erupt # => "DOOOOOOOOOOOONNNNN!!!!!!!"

その他

クラス変数にgetterとsetterを持たせたい場合、自前で定義する必要がある。 ただしRailsではclass_attributeなどの組み込みメソッドが用意されている。

参考:Rails: クラスレベルの3つのアクセサを比較する(翻訳)