Patron Stratégie
Fait partie de la section Programmation orientée objet du Journey R de Coddy. Leçon 45 sur 57.
Le modèle strategy rend un algorithme remplaçable : le code qui en a besoin le reçoit comme argument. En R, une fonction est une valeur, donc la stratégie est une fonction transmise, et l’appelant choisit laquelle :
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))Sortie :
[1] "pay 80"
[1] "pay 40"Une liste nommée de stratégies permet au programme d’en choisir une par son nom lors de l’exécution, par exemple à partir d’une saisie utilisateur :
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")Sortie :
regular 50
member 45
staff 35 Les stratégies avec des paramètres sont créées par des fabriques. percent_off(10) renvoie une nouvelle fonction de stratégie qui mémorise son pourcentage :
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)))Sortie :
[1] 90 75 70Un objet peut contenir sa stratégie dans un champ et la remplacer ultérieurement. Le reste de l’objet reste identique :
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))Sortie :
[1] "fig" "pear" "banana"
[1] "banana" "fig" "pear" Défi
FacileLes frais de livraison sont choisis par une stratégie : une fonction du poids total du panier et de son sous-total qui renvoie le coût de livraison. Dans Strategies.R, écrivez :
standard(kg, subtotal): 4.99 plus 1 par kg ;express(kg, subtotal): deux fois le coût standard ;free_over(limit): renvoie une stratégie qui coûte 0 lorsque le sous-total est supérieur ou égal àlimit, et le coût standard dans le cas contraire.
Dans Cart.R, new_cart(strategy) et add_item() sont fournis ; complétez subtotal(cart) et shipping_cost(cart), qui appelle la stratégie du panier. Le code fourni lit la stratégie (standard, express ou free_over 50), puis les articles book 12 0.5 (nom, prix, kg), et affiche les totaux.
Votre code doit se trouver dans Strategies.R et Cart.R. main.R contient le code fourni pour les entrées et sorties et ne peut pas être modifié.
Essayez vous-même
source("Strategies.R")
source("Cart.R")
# Code d'entrée/sortie fourni : le garder tel quel
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 = "")
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation orientée objet
1Bases de S3
Travailler avec les fichiersListes avec une classeFonctions constructricesMéthodes print et formatValidateurs et fonctions utilitairesRécapitulatif - Températures4Encapsulation dans R
Les fermetures comme objetsLes environnements comme objetsFonctions d’accèsProtéger l’étatRécapitulatif - Parcmètre2S3 : génériques et méthodes
Génériques et UseMethodMéthodes par défautMéthodes pour les génériques de baseNotions de base sur NextMethodRécapitulatif - Aires des formes5Classes S4
Définir des classes S4Slots et accèsVérifications de validitéMéthodes showRécapitulatif - Catalogue de produits8Classes de référence
Définition des classes de référenceMéthodes et mises à jour des champsSémantique de copieHéritage et callSuperRécapitulatif - File d’attente des tâches11Projet : gestion de bibliothèque
Livres et membresEmprunter des livres3Héritage S3
Vecteurs de classesOrdre de recherche des méthodesÉtendre avec NextMethodVérifier avec inherits()Récapitulatif - Paie du personnelEntraînez-vous par vous-même : Compilateur R en ligne