We need to have a single instance of a certain class across the whole application.
In the Singleton pattern, the access to the constructor is restricted so that it cannot be instantiated. So, the creation of the single instance is done inside the class and is held as a class variable. It can be accessed through a getter across the application.
Let's consider the implementation of a logger class:
class SimpleLogger
attr_accessor :level
ERROR = 1
WARNING = 2
INFO = 3
def initialize
@log = File.open("log.txt", "w")
@level = WARNING
end
def error(msg)
@log.puts(msg)
@log.flush
end
def warning(msg)
@log.puts(msg) if @level >= WARNING
@log.flush
end
def info(msg)
@log.puts(msg) if @level >= INFO
@log.flush
end
end
Logging is a feature used across the whole application, so it makes sense that there should only be a single instance of the logger. We can make sure that nobody instantiates the SimpleLogger
class twice by making its constructor private:
class SimpleLogger
# Lots of code deleted...
@@instance = SimpleLogger.new
def self.instance
return @@instance
end
private_class_method :new
end
SimpleLogger.instance.info('Computer wins chess game.')
We can get the same behavior by including the Singleton
module, so that we can avoid duplicating code if we create several singletons:
require 'singleton'
class SimpleLogger
include Singleton
# Lots of code deleted...
end