Singleton {R6P} | R Documentation |
Singleton Pattern
Description
Ensure a class only has one instance, and provide a global point of access to it.
Details
<!– One line about what the function does –>
Singleton ensures a class only has one instance, and provide a global point of access to it.
How It Works
Create only one instance of the Singleton class; and
If an instance exists, then serve the same object again.
The main features of Singleton are:
Ensuring that one and only one object of the class gets created;
Providing an access point for an object that is global to the program; and
Controlling concurrent access to resources that are shared.
When to Use It
In situations that require exactly one instance of a class, that must be accessible to clients from a well-known access point. See the
Counter
example.
<div class="alert alert-danger"> **Caution:** Singletons can be a problem in multi-threaded applications, especially when they manipulate mutable data. </div> <div class="alert alert-info"> **Tip:** Singletons work well for immutable data, such as reading from some data source, since anything that can’t change isn’t going to run into thread clash problems. </div>
Methods
Public methods
Method new()
Create or retrieve an object
Usage
Singleton$new()
See Also
Other base design patterns:
NullObject()
,
ValueObject()
Examples
# See more examples at <https://tidylab.github.io/R6P/articles>
address <- function(x) sub('<environment: (.*)>', '\\1', capture.output(x))
# In this example we implement a `Counter` that inherits the qualities of
# Singleton
Counter <- R6::R6Class("Counter", inherit = R6P::Singleton, public = list(
count = 0,
add_1 = function(){self$count = self$count + 1; invisible(self)}
))
# Whenever we call the constructor on `Counter`, we always get the exact same
# instance:
counter_A <- Counter$new()
counter_B <- Counter$new()
identical(counter_A, counter_B, ignore.environment = FALSE)
# The two objects are equal and located at the same address; thus, they are
# the same object.
# When we make a change in any of the class instances, the rest of the
# instances are changed as well.
# How many times has the counter been increased?
counter_A$count
# Increase the counter by 1
counter_A$add_1()
# How many times have the counters been increased?
counter_A$count
counter_B$count