Menu
CoddyTech

Mẫu Strategy

Thuộc phần Lập trình hướng đối tượng trong hành trình R của Coddy. Bài học 45 trên 57.

Mẫu strategy cho phép thay thế một thuật toán: code cần thuật toán đó sẽ nhận nó làm đối số. Trong R, hàm là một giá trị, vì vậy strategy là một hàm được truyền vào, còn hàm gọi sẽ chọn hàm nào:

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

Đầu ra:

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

Một danh sách chiến lược có tên cho phép chương trình chọn chiến lược theo tên khi chạy, chẳng hạn như từ đầu vào của người dùng:

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

Đầu ra:

regular 50 
member 45 
staff 35 

Các chiến lược có thiết lập được tạo bởi các hàm factory. percent_off(10) trả về một hàm chiến lược mới ghi nhớ tỷ lệ phần trăm:

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

Đầu ra:

[1] 90 75 70

Một đối tượng có thể lưu chiến lược của mình trong một trường rồi thay đổi chiến lược đó sau. Phần còn lại của đối tượng vẫn giữ nguyên:

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

Đầu ra:

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

Thử thách

Dễ

Phí vận chuyển được chọn theo một chiến lược: một hàm dựa trên tổng khối lượng của giỏ hàng và tổng tiền hàng, rồi trả về phí vận chuyển. Trong Strategies.R, hãy viết:

  • standard(kg, subtotal): 4.99 cộng thêm 1 cho mỗi kg;
  • express(kg, subtotal): gấp đôi phí tiêu chuẩn;
  • free_over(limit): trả về một chiến lược có phí bằng 0 khi tổng tiền hàng lớn hơn hoặc bằng limit, nếu không thì tính phí tiêu chuẩn.

Trong Cart.R, new_cart(strategy) và add_item() đã có sẵn; hãy hoàn thành subtotal(cart) và shipping_cost(cart), hàm này gọi chiến lược của giỏ hàng. Code được cung cấp sẽ đọc chiến lược (standard, express hoặc free_over 50), sau đó đọc các mặt hàng book 12 0.5 (tên, giá, kg) và in ra các tổng.

Code của bạn nằm trong Strategies.R và Cart.R. main.R chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

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

# Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch R online