Ensure a class only has one instance, and provide a global point of access to it.
Singleton ensures a class only has one instance, and provide a global point of access to it.
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.
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.
Caution: Singletons can be a problem in multi-threaded applications, especially when they manipulate mutable data.
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.
Other base design patterns:
NullObject()
,
ValueObject()
new()
Create or retrieve an object
Singleton$new()
# 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)#> [1] TRUE# 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#> [1] 0# Increase the counter by 1 counter_A$add_1() # How many times have the counters been increased? counter_A$count#> [1] 1counter_B$count#> [1] 1