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 70Mộ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" 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ằnglimit, 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 = "")
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
1Kiến thức cơ bản về S3
Làm việc với tệpDanh sách với một lớpHàm khởi tạoPhương thức in ra và định dạngTrình xác thực và hàm hỗ trợÔn tập: nhiệt độ4Tính đóng gói trong R
Closure dưới dạng đối tượngMôi trường dưới dạng đối tượngHàm truy cậpBảo vệ trạng tháiÔn tập: đồng hồ tính phí đỗ xe2S3, hàm generic và phương thức
Hàm generic và UseMethodPhương thức mặc địnhPhương thức cho hàm generic cơ sởCơ bản về NextMethodÔn tập: diện tích hình5Các lớp S4
Định nghĩa lớp S4Slot và quyền truy cậpKiểm tra tính hợp lệPhương thức showÔn tập: Danh mục sản phẩmTự luyện tập: Trình biên dịch R online