Fabrika Kalıbı
Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 43 / 57.
Bir factory, çağıranın sınıfı veya onun oluşturucusunu bilmesine gerek kalmaması için nesneler oluşturan bir işlevdir. Tür adı gibi bir açıklama alır ve doğru nesneyi döndürür:
area <- function(s) UseMethod("area")
area.circle <- function(s) pi * s$r^2
area.square <- function(s) s$side^2
make_shape <- function(type, size) {
switch(type,
circle = structure(list(r = size), class = "circle"),
square = structure(list(side = size), class = "square"))
}
for (t in c("circle", "square")) cat(t, round(area(make_shape(t, 2)), 2), "\n")Çıktı:
circle 12.57
square 4 Bilmediği bir tür için switch(), NULL döndürür. Bir fabrika bunun yerine türü adlandıran bir mesajla durmalıdır; böylece hata, yapıldığı yerde görünür:
make_shape <- function(type, size) {
switch(type,
circle = structure(list(r = size), class = "circle"),
square = structure(list(side = size), class = "square"),
stop("unknown shape: ", type, call. = FALSE))
}
msg <- tryCatch(make_shape("hexagon", 1), error = function(e) conditionMessage(e))
cat(msg)Çıktı:
unknown shape: hexagonKayıt defteri, oluşturucuları adlandırılmış bir listede tutar; böylece fabrikanın kendisi hiçbir zaman değişmez. Burada kayıt defteri bir ortamdır ve register_shape(), program çalışırken yeni bir tür ekler:
registry <- new.env()
register_shape <- function(name, maker) assign(name, maker, envir = registry)
make_shape <- function(name, ...) {
if (!exists(name, envir = registry, inherits = FALSE)) stop("unknown shape: ", name, call. = FALSE)
get(name, envir = registry)(...)
}
register_shape("circle", function(r) structure(list(r = r), class = "circle"))
register_shape("rect", function(w, h) structure(list(w = w, h = h), class = "rect"))
print(class(make_shape("rect", 2, 3)))
print(sort(ls(registry)))Çıktı:
[1] "rect"
[1] "circle" "rect" Nesneleri kullanan kod yalnızca area() gibi jeneriklere bağlıdır. Kaydedilen ve bir area() yöntemine sahip yeni bir sınıf, bu kodla hiçbir değişiklik yapılmadan çalışır:
registry <- new.env()
register_shape <- function(name, maker) assign(name, maker, envir = registry)
make_shape <- function(name, ...) get(name, envir = registry)(...)
area <- function(s) UseMethod("area")
total_area <- function(shapes) sum(vapply(shapes, area, numeric(1)))
register_shape("square", function(a) structure(list(a = a), class = "square"))
area.square <- function(s) s$a^2
register_shape("tri", function(b, h) structure(list(b = b, h = h), class = "tri"))
area.tri <- function(s) s$b * s$h / 2
print(total_area(list(make_shape("square", 2), make_shape("tri", 4, 3))))Çıktı:
[1] 10Görev
KolayBir kayıt çeşitli biçimlerde dışa aktarılabilir. Exporters.R, genel export(exporter, record) işlevini ve değerleri virgüllerle birleştirerek döndüren csv_exporter yöntemini içerir. Buradaki diğer iki yöntemi tamamlayın:
json_exporter:{"name": "Ada", "age": "36"};text_exporter:name=Ada; age=36.
Ardından Factory.R içinde make_exporter(format) fabrikasını yazın: csv, json veya text, sınıfı sırasıyla csv_exporter, json_exporter veya text_exporter olan boş bir liste döndürür; diğer tüm biçimler unknown format: xml ile durur (call. = FALSE kullanın). Sağlanan kod alan adlarını ve değerleri, ardından biçim adlarını okur ve her dışa aktarımı ya da error: ile mesajı yazdırır.
Kodunuz Exporters.R ve Factory.R dosyalarına yazılmalıdır. main.R sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
source("Exporters.R")
source("Factory.R")
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
fields <- strsplit(input[1], ",")[[1]]
values <- strsplit(input[2], ",")[[1]]
record <- setNames(values, fields)
for (fmt in input[-(1:2)]) {
out <- tryCatch(export(make_exporter(fmt), record), error = function(e) paste("error:", conditionMessage(e)))
cat(out, "\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