Wzorzec strategii
Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 45 z 57.
Wzorzec strategii sprawia, że algorytm można wymieniać: kod, który go potrzebuje, otrzymuje go jako argument. W R funkcja jest wartością, więc strategia jest przekazywaną funkcją, a wywołujący wybiera, której użyć:
no_discount <- function(total) total
half_price <- function(total) total / 2
checkout <- function(total, discount = no_discount) {
paste("pay", discount(total))
}
print(checkout(80))
print(checkout(80, half_price))Wynik:
[1] "pay 80"
[1] "pay 40"Lista strategii z nazwami pozwala programowi wybrać jedną z nich na podstawie nazwy w czasie działania, na przykład na podstawie danych wejściowych użytkownika:
pricing <- list(
regular = function(p) p,
member = function(p) p * 0.9,
staff = function(p) p * 0.7
)
for (who in c("regular", "member", "staff")) cat(who, pricing[[who]](50), "\n")Wynik:
regular 50
member 45
staff 35 Strategie z ustawieniami są tworzone przez fabryki. percent_off(10) zwraca nową funkcję strategii, która zapamiętuje swój procent:
percent_off <- function(pct) function(total) total * (1 - pct / 100)
fixed_off <- function(amount) function(total) max(0, total - amount)
rules <- list(percent_off(10), percent_off(25), fixed_off(30))
print(vapply(rules, function(r) r(100), numeric(1)))Wynik:
[1] 90 75 70Obiekt może przechowywać swoją strategię w polu i później ją zmieniać. Reszta obiektu pozostaje taka sama:
new_sorter <- function(key) structure(list(key = key), class = "sorter")
sort_with <- function(s, words) words[order(s$key(words))]
by_length <- function(w) nchar(w)
by_last_letter <- function(w) substring(w, nchar(w))
s <- new_sorter(by_length)
words <- c("pear", "fig", "banana")
print(sort_with(s, words))
s$key <- by_last_letter
print(sort_with(s, words))Wynik:
[1] "fig" "pear" "banana"
[1] "banana" "fig" "pear" Wyzwanie
ŁatwyWysyłka jest wybierana przez strategię: funkcję, która przyjmuje całkowitą wagę koszyka i jego sumę częściową, a zwraca koszt wysyłki. W pliku Strategies.R napisz:
standard(kg, subtotal): 4.99 plus 1 za każdy kg;express(kg, subtotal): dwukrotność standardowego kosztu;free_over(limit): zwraca strategię, która nalicza koszt 0, gdy suma częściowa jest co najmniej równalimit, a w przeciwnym razie nalicza standardowy koszt.
W pliku Cart.R funkcje new_cart(strategy) i add_item() są już dostępne; uzupełnij subtotal(cart) i shipping_cost(cart), która wywołuje strategię koszyka. Dostarczony kod odczytuje strategię (standard, express lub free_over 50), a następnie produkty book 12 0.5 (nazwa, cena, kg) i wypisuje sumy.
Twój kod umieść w plikach Strategies.R i Cart.R. Plik main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
source("Strategies.R")
source("Cart.R")
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], " ")[[1]]
rule <- if (p[1] == "free_over") free_over(as.numeric(p[2])) else get(p[1])
cart <- new_cart(rule)
for (line in input[-1]) {
q <- strsplit(line, " ")[[1]]
cart <- add_item(cart, q[1], as.numeric(q[2]), as.numeric(q[3]))
}
cat(sprintf("items: %.2f, shipping: %.2f, total: %.2f", subtotal(cart), shipping_cost(cart), subtotal(cart) + shipping_cost(cart)), "\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