Creational Design Patterns: Singleton Method
Purpose
The Singleton pattern ensures that a class has only one instance and provides global access to it. This is especially useful when only one object is required to coordinate actions throughout a system.
Explanation
- Singleton restricts the instantiation of a class to a single object.
- It provides a way to access its sole instance through a static method.
- The instance is typically stored as a class variable, and the constructor is made private to prevent external instantiation.
Implementing Singleton Pattern in Ruby
In Ruby, the Singleton pattern can be implemented using the Singleton
module provided by the Ruby standard library, or by manually controlling the instantiation process.
Let’s implement a Vehicle
class as an example.
Using the Singleton Module
Ruby provides a Singleton
module, which is the simplest way to create a singleton class.
Here’s how you can use it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
require 'singleton'
class Vehicle
include Singleton
attr_accessor :type, :model
def initialize
@type = "Car"
@model = "Sedan"
end
def details
"Vehicle Type: #{@type}, Model: #{@model}"
end
end
vehicle1 = Vehicle.instance
vehicle2 = Vehicle.instance
puts vehicle1.details
# Outputs: Vehicle Type: Car, Model: Sedan
puts vehicle2.details
# Outputs: Vehicle Type: Car, Model: Sedan
puts vehicle1.object_id == vehicle2.object_id
# Outputs: true, proving both are the same instance
Explanation:
The Singleton
module takes care of everything: It ensures that the new
method is private, provides an instance
method, and controls the instantiation process.
Manually Implementing Singleton Pattern
You can also manually implement the Singleton pattern by controlling the instantiation process:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Vehicle
@instance = nil
private_class_method :new
def self.instance
@instance ||= new
end
attr_accessor :type, :model
def initialize
@type = "Car"
@model = "Sedan"
end
def details
"Vehicle Type: #{@type}, Model: #{@model}"
end
end
vehicle1 = Vehicle.instance
vehicle2 = Vehicle.instance
puts vehicle1.details
# Outputs: Vehicle Type: Car, Model: Sedan
puts vehicle2.details
# Outputs: Vehicle Type: Car, Model: Sedan
puts vehicle1.object_id == vehicle2.object_id
# Outputs: true, proving both are the same instance
Explanation:
- The
new
method is made private to prevent direct instantiation. - The class has a class-level instance variable
@instance
that stores the single instance of the class. - The
instance
method checks if an instance already exists; if not, it creates one.
Key Points:
- Global Access Point: The Singleton pattern allows controlled access to a single instance of a class.
- Shared Resource: It is particularly useful when a single object needs to manage shared resources, such as a configuration manager or a logging system.
- Thread Safety: In multi-threaded applications, ensure that the Singleton implementation is thread-safe, as two threads might simultaneously access the
instance
method and create two instances.
We just saw how Singleton Pattern can be implemented in Ruby using both built-in Singleton
module and manual.
Happy Coding :)
Comments powered by Disqus.