Oluşturucu Kalıbı
Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 47 / 57.
Bir oluşturucu, karmaşık bir nesneyi adım adım bir araya getirir ve sonunda build() ile oluşturur. Closure tabanlı bir oluşturucu, parçaları özel değişkenlerde tutar; her adım invisible(self) ile oluşturucunun kendisini döndürür, böylece adımlar zincirlenir ve tek başına çağrılan bir adım hiçbir şey yazdırmaz:
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 "))Çıktı:
large with olives and basilbuild(), nesnenin tamamlanmış olduğunu kontrol edeceğiniz yerdir. Eksik parçalar, yarım oluşturulmuş bir nesne üretmek yerine bir iletiyle işlemi durdurur:
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)))Çıktı:
[1] "To: ada@x.org | Subject: Hi"
[1] "an email needs a recipient"Aynı fikir, düz değerler ve |> pipe operatörüyle de çalışır. Her adım, şu ana kadarki açıklamayı alan ve güncellenmiş bir kopya döndüren bir işlevdir; son adım ise sonucu oluşturur:
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")Çıktı:
POST /users
Accept: jsonBir oluşturucu, bir yapıcıyı çok sayıda isteğe bağlı bağımsız değişkenle değiştirir. Her adım, neyi ayarladığını belirtir ve belirtilmeyen kısımlar varsayılan değerlerini korur:
# okuması zor: TRUE nedir, 3 nedir?
make_report("sales", TRUE, FALSE, 3, "pdf")
# bir builder her değerin ne anlama geldiğini söyler
report_builder("sales")$with_totals()$top(3)$format("pdf")$build()Görev
KolayKapanış tabanlı query_builder(table) işlevini QueryBuilder.R içinde tamamlayın. Adımları, zincirleme kullanılabilmeleri için oluşturucuyu döndürür:
select(cols): gösterilecek sütunlar (varsayılan*);where(cond): bir koşul ekler; birden fazlasıANDile birleştirilir;order_by(col)velimit(n);build():SELECT name, age FROM users WHERE age > 30 AND city = 'Rome' ORDER BY name LIMIT 5gibi sorguyu döndürür ve ayarlanmamış kısımları dışarıda bırakır.
Sağlanan kod tabloyu, ardından select name age, where age > 30, order name veya limit 5 satırlarını okur ve oluşturulan sorguyu yazdırır. Daha sonra tek bir zincir içinde ikinci bir sorgu oluşturur.
Kodunuz QueryBuilder.R içine yazılmalıdır. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
source("QueryBuilder.R")
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
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 = "")
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Tabanlı Programlama bölümündeki tüm dersler
1S3 Temelleri
Dosyalarla ÇalışmaSınıf ile ListelerYapıcı FonksiyonlarPrint ve Format MetotlarıDoğrulayıcılar ve YardımcılarTekrar - Sıcaklıklar4R'da Kapsülleme
Nesne Olarak Closure'larNesne Olarak OrtamlarErişimci FonksiyonlarDurumu KorumaÖzet - Parkmetre2S3 Generic'leri ve Metotları
Generic'ler ve UseMethodVarsayılan MetotlarTemel Generic'ler için MetotlarNextMethod TemelleriTekrar - Şekil Alanları5S4 Sınıfları
S4 Sınıflarını TanımlamaSlotlar ve ErişimGeçerlilik KontrolleriShow MetotlarıÖzet - Ürün Kataloğu8Referans Sınıfları
Referans Sınıflarını TanımlamaMetotlar ve Alan GüncellemeleriKopyalama SemantiğiKalıtım ve callSuperÖzet - Görev Kuyruğu11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Online R derleyicisi