Menu
Coddy logo textTech

전략 패턴

Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 45번째.

전략 패턴은 알고리즘을 교체 가능하게 만듭니다. 알고리즘이 필요한 코드는 이를 인수로 받습니다. R에서는 함수가 값이므로 전략은 전달되는 함수이며, 호출자가 사용할 함수를 선택합니다:

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))

출력:

[1] "pay 80"
[1] "pay 40"

이름이 지정된 전략 목록을 사용하면 프로그램이 실행 시간에 이름으로 하나를 선택할 수 있습니다. 예를 들어 사용자 입력을 통해 선택할 수 있습니다.

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")

출력:

regular 50 
member 45 
staff 35 

설정이 있는 전략은 팩토리로 생성됩니다. percent_off(10)은 할인율을 기억하는 새로운 전략 함수를 반환합니다:

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)))

출력:

[1] 90 75 70

객체는 필드에 전략을 저장하고 나중에 교체할 수 있습니다. 객체의 나머지 부분은 그대로 유지됩니다:

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))

출력:

[1] "fig"    "pear"   "banana"
[1] "banana" "fig"    "pear"  
challenge icon

챌린지

쉬움

배송은 전략에 의해 선택됩니다. 전략은 장바구니의 총 무게와 소계에 대한 함수이며 배송비를 반환합니다. Strategies.R에 다음을 작성하세요:

  • standard(kg, subtotal): 4.99에 kg당 1을 더합니다;
  • express(kg, subtotal): 표준 비용의 2배입니다;
  • free_over(limit): 소계가 limit 이상이면 비용이 0이고, 그렇지 않으면 표준 비용이 되는 전략을 반환합니다.

Cart.R에는 new_cart(strategy)와 add_item()이 제공되어 있습니다. 장바구니의 전략을 호출하는 subtotal(cart)과 shipping_cost(cart)를 완성하세요. 제공된 코드는 전략(standard, express 또는 free_over 50)을 읽은 다음, 항목 book 12 0.5(이름, 가격, kg)을 읽고 합계를 출력합니다.

코드는 Strategies.R과 Cart.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.

직접 해보기

source("Strategies.R")
source("Cart.R")

# 제공된 입력/출력 코드: 그대로 유지하세요
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 icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 R 컴파일러