Pattern Decorator
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 46 di 57.
Un decoratore avvolge qualcosa e ne aggiunge il comportamento mantenendo la stessa interfaccia. Per una funzione, il decoratore prende una funzione e restituisce una nuova funzione che esegue un lavoro aggiuntivo attorno alla chiamata:
with_logging <- function(f, name) {
function(x) {
cat("calling", name, "with", x, "\n")
f(x)
}
}
double <- function(x) x * 2
logged <- with_logging(double, "double")
print(logged(21))Output:
calling double with 21
[1] 42Un decoratore può ricordare i risultati. with_cache() conserva ogni risposta in un ambiente e chiama la funzione avvolta solo per i nuovi argomenti:
with_cache <- function(f) {
cache <- new.env()
function(x) {
key <- as.character(x)
if (!exists(key, envir = cache, inherits = FALSE)) assign(key, f(x), envir = cache)
get(key, envir = cache)
}
}
work <- 0
slow_square <- function(x) {
work <<- work + 1
x^2
}
fast <- with_cache(slow_square)
for (x in c(3, 4, 3, 3, 4)) fast(x)
cat("results computed:", work)Output:
results computed: 2Anche gli oggetti possono essere decorati. Ogni decoratore è un oggetto che conserva in un campo l'oggetto che avvolge e risponde agli stessi generici, aggiungendo la propria parte e chiedendo il resto all'oggetto interno:
cost <- function(d) UseMethod("cost")
describe <- function(d) UseMethod("describe")
cost.coffee <- function(d) 2
describe.coffee <- function(d) "coffee"
with_milk <- function(inner) structure(list(inner = inner), class = "milk")
cost.milk <- function(d) cost(d$inner) + 0.5
describe.milk <- function(d) paste(describe(d$inner), "+ milk")
cup <- with_milk(with_milk(structure(list(), class = "coffee")))
cat(describe(cup), "=", cost(cup))Output:
coffee + milk + milk = 3I decoratori si concatenano e il loro ordine è importante: quello più esterno viene eseguito per primo all’andata e per ultimo al ritorno:
exclaim <- function(f) function(s) paste0(f(s), "!")
twice <- function(f) function(s) paste(f(s), f(s))
greet <- function(name) paste("hi", name)
a <- twice(exclaim(greet))
b <- exclaim(twice(greet))
cat(a("ada"), "/", b("ada"))Output:
hi ada! hi ada! / hi ada hi ada!Sfida
FacileLe bevande vengono decorate con extra. Drink.R contiene i generici cost() e describe() e la bevanda di base, new_coffee(), che costa 2 e si descrive come coffee. In Extras.R scrivi tre decoratori, ciascuno un oggetto che contiene la bevanda che avvolge nel campo inner:
add_milk(d): classemilk, aggiunge 0.50 e+ milk;add_sugar(d): classesugar, aggiunge 0.20 e+ sugar;add_syrup(d, flavour): classesyrupcon il campoflavour, aggiunge 0.80 e+ vanilla syrup.
Scrivi i loro metodi cost() e describe() chiedendo prima alla bevanda interna. Il codice fornito legge righe come milk,syrup vanilla,sugar (una riga vuota indica un caffè semplice) e stampa coffee + milk + vanilla syrup + sugar: 3.50.
Il tuo codice va in Drink.R e Extras.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Drink.R")
source("Extras.R")
# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
d <- new_coffee()
if (nchar(line) > 0) for (extra in strsplit(line, ",")[[1]]) {
p <- strsplit(extra, " ")[[1]]
d <- switch(p[1], milk = add_milk(d), sugar = add_sugar(d), syrup = add_syrup(d, p[2]))
}
cat(sprintf("%s: %.2f", describe(d), cost(d)), "\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