Pola Builder
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 47 dari 57.
builder merakit object yang rumit langkah demi langkah dan membuatnya di akhir dengan build(). Builder berbasis closure menyimpan bagian-bagiannya dalam variabel privat; setiap langkah mengembalikan builder itu sendiri dengan invisible(self), sehingga langkah-langkahnya dapat dirangkai dan langkah yang dipanggil sendiri tidak mencetak apa pun:
pizza_builder <- function() {
size <- "medium"
toppings <- character(0)
self <- list(
size = function(s) { size <<- s; invisible(self) },
add = function(t) { toppings <<- c(toppings, t); invisible(self) },
build = function() structure(list(size = size, toppings = toppings), class = "pizza")
)
self
}
p <- pizza_builder()$size("large")$add("olives")$add("basil")$build()
cat(p$size, "with", paste(p$toppings, collapse = " and "))Output:
large with olives and basilbuild() adalah tempat untuk memeriksa apakah object sudah lengkap. Bagian yang hilang akan memicu pesan, bukan menghasilkan object setengah jadi:
email_builder <- function() {
to <- NULL
subject <- ""
self <- list(
to = function(x) { to <<- x; invisible(self) },
subject = function(x) { subject <<- x; invisible(self) },
build = function() {
if (is.null(to)) stop("an email needs a recipient", call. = FALSE)
paste0("To: ", to, " | Subject: ", subject)
}
)
self
}
print(email_builder()$to("ada@x.org")$subject("Hi")$build())
print(tryCatch(email_builder()$subject("Hi")$build(), error = function(e) conditionMessage(e)))Output:
[1] "To: ada@x.org | Subject: Hi"
[1] "an email needs a recipient"Gagasan yang sama berlaku untuk nilai biasa dan pipe |>. Setiap langkah adalah fungsi yang mengambil deskripsi sejauh ini dan mengembalikan salinan yang diperbarui, lalu langkah terakhir menyusun hasilnya:
request <- function(url) list(url = url, method = "GET", headers = character(0))
with_method <- function(req, m) { req$method <- m; req }
with_header <- function(req, name, value) { req$headers[name] <- value; req }
build_request <- function(req) {
c(paste(req$method, req$url), paste0(names(req$headers), ": ", req$headers))
}
r <- request("/users") |> with_method("POST") |> with_header("Accept", "json") |> build_request()
cat(r, sep = "\n")Output:
POST /users
Accept: application/jsonBuilder menggantikan constructor dengan banyak argumen opsional. Setiap langkah menyebutkan apa yang diaturnya, dan bagian yang tidak disebutkan tetap menggunakan nilai default:
# Sulit dibaca: apa arti TRUE dan 3?
make_report("sales", TRUE, FALSE, 3, "pdf")
# builder menjelaskan arti setiap nilai
report_builder("sales")$with_totals()$top(3)$format("pdf")$build()Tantangan
MudahLengkapi query_builder(table) berbasis closure di QueryBuilder.R. Setiap langkah mengembalikan builder agar langkah-langkah tersebut dapat dirangkai:
select(cols): kolom yang akan ditampilkan (default*);where(cond): menambahkan kondisi; beberapa kondisi digabungkan denganAND;order_by(col)danlimit(n);build(): mengembalikan query, sepertiSELECT name, age FROM users WHERE age > 30 AND city = 'Rome' ORDER BY name LIMIT 5, tanpa menyertakan bagian yang belum ditetapkan.
Kode yang disediakan membaca tabel, lalu baris select name age, where age > 30, order name atau limit 5, kemudian mencetak query yang dibuat. Setelah itu, kode tersebut membuat query kedua dalam satu rangkaian.
Tulis kodemu di QueryBuilder.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
source("QueryBuilder.R")
# Kode input/output yang disediakan: biarkan tetap seperti semula
input <- suppressWarnings(readLines(file("stdin")))
q <- query_builder(input[1])
for (line in input[-1]) {
p <- strsplit(line, " ")[[1]]
rest <- paste(p[-1], collapse = " ")
if (p[1] == "select") q <- q$select(p[-1])
if (p[1] == "where") q <- q$where(rest)
if (p[1] == "order") q <- q$order_by(p[2])
if (p[1] == "limit") q <- q$limit(as.numeric(p[2]))
}
cat(q$build(), "\n", sep = "")
cat(query_builder("logs")$select("msg")$limit(1)$build(), "\n", sep = "")
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar S3
Bekerja dengan fileList dengan classFungsi KonstruktorMethod print dan formatValidator dan helperUlasan: Suhu4Enkapsulasi di R
Closure sebagai objectEnvironment sebagai objectFungsi accessorMelindungi stateRangkuman: Meter Parkir2S3 Generics dan Method
Generics dan UseMethodMethod DefaultMethod untuk Base GenericsDasar-Dasar NextMethodRekap: Luas Bangun5S4 class
Mendefinisikan class S4Slots dan AksesPemeriksaan ValiditasMethod showRingkasan: Katalog Produk8Kelas Referensi
Mendefinisikan Kelas ReferensiPembaruan method dan fieldSemantik PenyalinanPewarisan dan callSuperRangkuman: Antrean Tugas11Proyek: Manajemen Perpustakaan
Buku dan AnggotaMeminjam BukuLatihan sendiri: Compiler R online