Pattern Singleton
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 42 di 57.
Un pattern di progettazione è una soluzione collaudata a un problema di progettazione che si ripresenta più e più volte. Il pattern singleton garantisce che esista esattamente un’istanza di qualcosa, accessibile da qualsiasi punto. In R, una funzione di accesso crea l’istanza alla prima chiamata, la conserva in una variabile creata con local() e restituisce la stessa ogni volta:
get_config <- local({
instance <- NULL
function() {
if (is.null(instance)) {
instance <<- new.env()
instance$theme <- "light"
}
instance
}
})
a <- get_config()
a$theme <- "dark"
b <- get_config()
cat(b$theme, identical(a, b))Output:
dark TRUEL'istanza è un ambiente, quindi una modifica effettuata tramite una chiamata viene vista da ogni altra parte del programma. Due funzioni in punti diversi scrivono nello stesso log:
get_log <- local({
instance <- NULL
function() {
if (is.null(instance)) {
instance <<- new.env()
instance$lines <- character(0)
}
instance
}
})
page_a <- function() {
log <- get_log()
log$lines <- c(log$lines, "a visited")
}
page_b <- function() {
log <- get_log()
log$lines <- c(log$lines, "b visited")
}
page_a()
page_b()
page_a()
print(get_log()$lines)Output:
[1] "a visited" "b visited" "a visited"L'istanza viene creata solo quando serve per la prima volta. Contando le creazioni, si vede che avviene una sola volta, indipendentemente da quante volte viene chiamato l'accessore:
created <- 0
get_db <- local({
instance <- NULL
function() {
if (is.null(instance)) {
created <<- created + 1
instance <<- new.env()
}
instance
}
})
for (i in 1:5) db <- get_db()
cat("created", created, "time(s)")Output:
created 1 time(s)Usa i singleton con moderazione. Un singleton è uno stato globale: qualsiasi codice può modificarlo e un test non può partire da una copia pulita senza ripristinarlo. È adatto a ciò che è davvero unico per programma, come un logger o le impostazioni; passare un oggetto come argomento è spesso più chiaro:
# Più facile da testare: il log viene passato come argomento
process <- function(order, log) {
log$lines <- c(log$lines, paste("processing", order$id))
}Sfida
FacileCompleta il logger singleton in Logger.R. get_logger() restituisce un ambiente, creato alla prima chiamata, con il campo entries (carattere, inizialmente vuoto). Poi scrivi:
log_info(msg)elog_error(msg), che aggiungono[INFO] msgo[ERROR] msgalle voci del logger condiviso;error_count(), che conta le voci che iniziano con[ERROR].
Il codice fornito legge righe info,started o error,disk full, registra ciascuna, poi stampa ogni voce, il numero di errori e indica se due chiamate a get_logger() restituiscono lo stesso oggetto.
Il tuo codice va in Logger.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Logger.R")
# Código de entrada/salida proporcionado: mantenlo tal como está
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, ",")[[1]]
if (p[1] == "error") log_error(p[2]) else log_info(p[2])
}
for (e in get_logger()$entries) cat(e, "\n", sep = "")
cat("errors: ", error_count(), "\n", sep = "")
cat("one logger: ", identical(get_logger(), get_logger()), "\n", sep = "")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Nozioni di base su S3
Lavorare con i fileListe con una classeFunzioni costruttriciMetodi di stampa e formattazioneValidatori e funzioni di supportoRipasso - Temperature4Incapsulamento in R
Chiusure come oggettiAmbienti come oggettiFunzioni di accessoProteggere lo statoRiepilogo - Parcometro2Generics e metodi S3
Generics e UseMethodMetodi predefinitiMetodi per i generics di baseNozioni di base su NextMethodRiepilogo - Aree delle forme5Classi S4
Definire le classi S4Slot e accessoControlli di validitàMetodi showRiepilogo - Catalogo prodotti8Classi di riferimento
Definizione delle classi di riferimentoMetodi e aggiornamenti dei campiSemantica della copiaEreditarietà e callSuperRiepilogo - coda di attività11Progetto: Gestione della biblioteca
Libri e iscrittiPrestito dei libriEsercitati da solo: Compilatore R online