Wzorzec Singleton
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 42 z 57.
Wzorzec projektowy to sprawdzone rozwiązanie problemu projektowego, który pojawia się wielokrotnie. Wzorzec singleton gwarantuje, że istnieje dokładnie jedna instancja danego obiektu, dostępna z dowolnego miejsca. W R funkcja dostępowa tworzy instancję przy pierwszym wywołaniu, przechowuje ją w zmiennej utworzonej za pomocą local() i za każdym razem zwraca tę samą instancję:
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))Wynik:
dark TRUEInstancja jest środowiskiem, więc zmiana wprowadzona za pomocą jednego wywołania jest widoczna dla każdej innej części programu. Dwie funkcje w różnych miejscach zapisują do tego samego dziennika:
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)Wynik:
[1] "a visited" "b visited" "a visited"Instancja jest tworzona dopiero wtedy, gdy jest po raz pierwszy potrzebna. Liczenie utworzeń pokazuje, że dzieje się to raz, niezależnie od tego, jak często wywoływany jest akcesor:
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)")Wynik:
created 1 time(s)Używaj singletonów oszczędnie. Singleton to stan globalny: dowolny kod może go zmienić, a test nie może rozpocząć działania na czystej kopii bez jego zresetowania. Sprawdza się w przypadku rzeczy, które rzeczywiście występują w programie tylko raz, takich jak rejestrator lub ustawienia; często jaśniej jest przekazać obiekt jako argument:
# łatwiejsze do testowania: log jest przekazywany jako argument
process <- function(order, log) {
log$lines <- c(log$lines, paste("processing", order$id))
}Wyzwanie
ŁatwyUzupełnij logger singleton w Logger.R. get_logger() zwraca jedno środowisko, tworzone przy pierwszym wywołaniu, z polem entries (znakowym, początkowo pustym). Następnie napisz:
log_info(msg)ilog_error(msg), które dodają[INFO] msglub[ERROR] msgdo wpisów współdzielonego loggera;error_count(), które zlicza wpisy zaczynające się od[ERROR].
Dostarczony kod odczytuje wiersze info,started lub error,disk full, zapisuje każdy z nich w logu, a następnie wyświetla wszystkie wpisy, liczbę błędów oraz informację, czy dwa wywołania get_logger() zwracają ten sam obiekt.
Umieść swój kod w Logger.R. main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
source("Logger.R")
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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 = "")
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy S3
Praca z plikamiListy z klasąFunkcje konstruktoraMetody print i formatWalidatory i funkcje pomocniczePowtórzenie — temperatury4Enkapsulacja w R
Domknięcia jako obiektyŚrodowiska jako obiektyFunkcje dostępoweOchrona stanuPodsumowanie – parkometr2Generics i metody S3
Generics i UseMethodMetody domyślneMetody dla podstawowych genericsPodstawy NextMethodPowtórzenie — pola figur5Klasy S4
Definiowanie klas S4Sloty i dostępSprawdzanie poprawnościMetody wyświetlaniaPodsumowanie – katalog produktów8Klasy referencyjne
Definiowanie klas referencyjnychMetody i aktualizacja pólSemantyka kopiowaniaDziedziczenie i callSuperPodsumowanie – kolejka zadań11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książek3Dziedziczenie S3
Wektory klasKolejność wyszukiwania metodRozszerzanie za pomocą NextMethodSprawdzanie za pomocą inherits()Powtórzenie — lista płac pracownikówPoćwicz samodzielnie: Kompilator R online