Pola Factory
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 43 dari 57.
Factory adalah fungsi yang membuat object sehingga pemanggil tidak perlu mengetahui class atau konstruktornya. Fungsi ini menerima deskripsi, seperti nama tipe, lalu mengembalikan object yang tepat:
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")Output:
circle 12.57
square 4 Untuk tipe yang tidak dikenalnya, switch() mengembalikan NULL. Sebaiknya factory berhenti dan menampilkan pesan yang menyebutkan tipe tersebut, agar kesalahan terlihat di tempat kesalahan itu dibuat:
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)Output:
unknown shape: hexagonRegistry menyimpan constructor dalam daftar bernama, sehingga factory itu sendiri tidak pernah berubah. Di sini registry berupa environment, dan register_shape() menambahkan jenis baru saat program berjalan:
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)))Output:
[1] "rect"
[1] "circle" "rect" Kode yang menggunakan object hanya bergantung pada generik, seperti area(). class baru yang didaftarkan dan memiliki method area() akan berfungsi dengan kode tersebut tanpa perubahan:
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))))Output:
[1] 10Tantangan
MudahSebuah record dapat diekspor dalam beberapa format. Exporters.R berisi export(exporter, record) generik dan method untuk csv_exporter, yang mengembalikan nilai-nilai yang digabungkan dengan koma. Lengkapi dua method lainnya di sana:
json_exporter:{"name": "Ada", "age": "36"};text_exporter:name=Ada; age=36.
Lalu tulis factory make_exporter(format) di Factory.R: csv, json, atau text menghasilkan list kosong dengan class csv_exporter, json_exporter, atau text_exporter, sedangkan format lain akan berhenti dengan unknown format: xml (gunakan call. = FALSE). Kode yang disediakan membaca nama field dan nilainya, lalu nama format, kemudian mencetak setiap hasil ekspor atau error: beserta pesannya.
Tulis kodemu di Exporters.R dan Factory.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
source("Exporters.R")
source("Factory.R")
# Kode input/output yang disediakan: biarkan tetap seperti semula
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 = "")
}
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