DEV Community

rubyhub.io
rubyhub.io

Posted on • Originally published at Medium

Ruby Design Patterns | SINGLETON 👴🏼

Overview

Singleton is a creational design pattern responsible for the fact that a class can only have one instance.

Real World Example

As an example of today’s pattern, I chose the head of the Catholic Church, the Pope. However, I do not mean the Pope as a person, but as an institution. As we know from history the first Pope was St. Peter, and from that time to the present day, this office is held by various persons. However, it is impossible for more than one Pope to exist at the same time. This institution imposes in advance that this position may only be occupied by one person at a time.

Image description

Code Example

Let’s move the above example to the programming world and create a Pope class that can pray through the pray! method.

class Pope
  def pray!
    puts 'In nomine Patris, et Filii, et Spiritus Sancti...'
  end
end

pope = Pope.new
pope.pray! # => 'In nomine Patris, et Filii, et Spiritus Sancti...'

new_pope = Pope.new
new_pope.pray! # => 'In nomine Patris, et Filii, et Spiritus Sancti...'

pope == new_pope # => false
Enter fullscreen mode Exit fullscreen mode

As we can see with the standard approach, we are able to create more than one instance of the Pope class. This is why we need to use the Singleton pattern to prevent creating more than one instance of a given class.

class Pope
  @@instance = new

  def self.instance
    @@instance
  end

  def pray!
    puts 'In nomine Patris, et Filii, et Spiritus Sancti...'
  end

  private_class_method :new
end

pope = Pope.new # => NoMethodError: private method 'new' called for Pope:Class
Pope.instance.pray! # => "In nomine Patris..."
Enter fullscreen mode Exit fullscreen mode

As you can see in the example above, we can’t directly create a class with the new method, which is now private, and we need to use the instance method instead. By comparing two instances to each other, we can make sure that they are the same instance.

pope = Pope.instance
new_pope = Pope.instance
pope == new_pope # => true
Enter fullscreen mode Exit fullscreen mode

Singleton pattern is so popular that there is a Singleton module in the standard Ruby library, thanks to which we will not have to focus on pattern configuration.

class Pope
  include Singleton

  def pray!
    puts 'In nomine Patris, et Filii, et Spiritus Sancti...'
  end
end
Enter fullscreen mode Exit fullscreen mode

This code works in exactly the same way as the code presented at the beginning of this article.

Top comments (0)