ruby設計デフォルト-単例モード(一)


要点
明らかに単例モードの要点は3つある.1つは、クラスに1つのインスタンスしかありません.2つ目は、このインスタンスを自分で作成する必要があります.3つ目は、システム全体にこのインスタンスを独自に提供する必要があります.
具体的な実装の観点から言えば、以下の3つの点である.1つは、単一のモードのクラスがプライベートな構造関数のみを提供することであり、2つは、クラス定義にクラスを含む静的プライベートオブジェクトであり、3つは、クラスが提供することである.
概要
単例モードは設計モードの中で最も簡単な形式の一つである.このモードの目的は、クラスのオブジェクトをシステム内の唯一のインスタンスにすることです.これを実現するには、クライアントがインスタンス化することから始めます.したがって、オブジェクトクラスを生成する一意のインスタンスのみを許可するメカニズムを使用して、オブジェクトを生成するすべてのアクセスを「ブロック」する必要があります.ファクトリメソッドを使用してインスタンス化プロセスを制限します.この方法は、クラスのインスタンスに別の一意のインスタンスを生成させることは意味がないため、静的メソッド(クラスメソッド)であるべきである.
class ClassVariableTester
  @@class_count = 0

  def initialize
    @instance_count = 0
  end

  def increment
    @@class_count = @@class_count + 1
    @instance_count = @instance_count + 1
  end

  def to_s
    "class count :#{@@class_count} -- instance count :#{@instance_count}"
  end
  
end

cv1 = ClassVariableTester.new
cv1.increment
cv1.increment
puts("cv1:#{cv1}")
cv2 = ClassVariableTester.new
puts("cv2:#{cv2}")

#cv1:class count :2 -- instance count :2
#cv2:class count :2 -- instance count :0

#          ,@@class_count  2, @instance_count 0
#             , cv1.increment       @@class_count 2
#     ClassVariableTester  cv2   ,   @@class_count,     @@class_count  2
#              ,      cv2 @@instance_count 0
#               

 
class SimpleLogger

  @@instance = SimpleLogger.new
  
  def self.get_instance
    @@instance
  end

  private_class_method :new
end

sl1 = SimpleLogger.get_instance
sl2 = SimpleLogger.get_instance
puts sl1 == sl2

#   :true
#                   ,                 

#    SimpleLogger.new             ,       new       
sl3 = SimpleLogger.new
# private method `new' called for SimpleLogger:Class (NoMethodError)

 
require 'singleton'
class SimpleLogger
  include Singleton

end

#puts SimpleLogger.new
sl1 = SimpleLogger.instance
sl2 = SimpleLogger.instance
puts sl1 == sl2

#   :true

#ruby      singleton,         
#  Singleton,         ,       ,      instance  ,   new    
#  SimpleLogger.instance         

#            
#        “    (eager instantiation)”
#               
#        “    (lazy instantiation)”
#   instance      

#    Singleton           ,    public_class_method  new       
#   ,  new   public  ,    SimpleLogger.new      
class SimpleLogger
  public_class_method :new
end

puts SimpleLogger.new

 
#       

#( )      ,          ,                 
#                  ,
$logger = SimpleLogger.new
#( )       
class SimpleLogger
  
  WARNING = 1
  INFO = 2

  def initialize(file)
    @@log = File.open(file, "w")
    @@level = WARNING
  end
  

  def self.warning(msg)
    puts @@level > WARNING
    @@log.puts(msg) if @@level > WARNING
    @@log.flush
  end

  def self.level
    @@level
  end

  def self.level=(new_level)
    @@level = new_level
  end
  
end
SimpleLogger.new("test.txt")
puts SimpleLogger.level
SimpleLogger.level = SimpleLogger::INFO
puts SimpleLogger.level
SimpleLogger.warning("warning")