Menu
Coddy logo textTech

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 70

Un 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"  
challenge icon

Défi

Facile

Les 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 = "")
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur R en ligne