Mẫu State
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 48 trên 57.
Đối tượng trong mẫu trạng thái hoạt động khác nhau tùy theo trạng thái hiện tại. Mỗi trạng thái là một danh sách các hàm xử lý, và đối tượng chuyển từng yêu cầu đến các hàm xử lý của trạng thái mà nó đang ở:
states <- list(
green = list(label = "go", next_state = "yellow"),
yellow = list(label = "slow down", next_state = "red"),
red = list(label = "stop", next_state = "green")
)
current <- "green"
for (i in 1:4) {
cat(current, ":", states[[current]]$label, "\n")
current <- states[[current]]$next_state
}Đầu ra:
green : go
yellow : slow down
red : stop
green : go Trình xử lý nhận một sự kiện và trả về trạng thái tiếp theo cùng một phản hồi, vì vậy các chuyển đổi là dữ liệu chứ không phải một chuỗi if. Cửa xoay mở khóa khi có người bỏ xu vào và khóa lại sau khi có người đi qua:
states <- list(
locked = list(
coin = function() list(to = "unlocked", say = "unlocked"),
push = function() list(to = "locked", say = "blocked")
),
unlocked = list(
coin = function() list(to = "unlocked", say = "already open"),
push = function() list(to = "locked", say = "welcome")
)
)
current <- "locked"
for (event in c("push", "coin", "coin", "push")) {
r <- states[[current]][[event]]()
current <- r$to
cat(event, "->", r$say, "\n")
}Đầu ra:
push -> blocked
coin -> unlocked
coin -> already open
push -> welcome Bản thân máy là một closure nhỏ: nó giữ trạng thái hiện tại, tra cứu trình xử lý và trả lời ignored cho sự kiện mà trạng thái đó không biết:
make_machine <- function(states, start) {
current <- start
list(
handle = function(event) {
h <- states[[current]][[event]]
if (is.null(h)) return("ignored")
r <- h()
current <<- r$to
r$say
},
state = function() current
)
}
states <- list(off = list(press = function() list(to = "on", say = "light on")),
on = list(press = function() list(to = "off", say = "light off")))
m <- make_machine(states, "off")
for (e in c("press", "kick", "press")) cat(e, ":", m$handle(e), "|", m$state(), "\n")Đầu ra:
press : light on | on
kick : ignored | on
press : light off | off Một trạng thái mới là một mục mới trong danh sách. Máy không thay đổi, và chỉ những trạng thái dẫn đến trạng thái mới mới cần một hàm xử lý mới:
states <- list(
off = list(press = function() list(to = "on", say = "on")),
on = list(press = function() list(to = "off", say = "off"),
overheat = function() list(to = "broken", say = "fuse blown")),
broken = list(repair = function() list(to = "off", say = "repaired"))
)
current <- "off"
for (e in c("press", "overheat", "press", "repair")) {
h <- states[[current]][[e]]
if (is.null(h)) { cat(e, ": ignored\n"); next }
r <- h()
current <- r$to
cat(e, ":", r$say, "\n")
}Đầu ra:
press : on
overheat : fuse blown
press : ignored
repair : repaired Thử thách
DễHoàn thành cửa quay trong Turnstile.R. Danh sách states có các trạng thái locked và unlocked, mỗi hàm xử lý trả về list(to = ..., say = ...):
- locked:
coinmở khóa và chuyển sangunlocked;pushvẫn giữ trạng thái khóa vớiblocked; - unlocked:
coinvẫn giữ trạng thái mở khóa vớithanks, already open;pushkhóa cửa, trả vềwelcomevà tính thêm một lượt qua.
Sau đó hoàn thành make_turnstile(), hàm này bắt đầu ở trạng thái khóa và trả về handle(event) (phản hồi, hoặc ignored nếu gặp sự kiện không xác định), state() và passes(). Tính thêm một lượt qua mỗi khi xử lý push trong trạng thái mở khóa. Code được cung cấp đọc các sự kiện và in từng phản hồi cùng trạng thái mới, sau đó in số lượt qua.
Code của bạn nằm trong Turnstile.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("Turnstile.R")
# Đoạn code đầu vào/đầu ra đã được cung cấp: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
t <- make_turnstile()
for (event in input) cat(event, ": ", t$handle(event), " [", t$state(), "]\n", sep = "")
cat("passes: ", t$passes(), "\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