Gözlemci Kalıbı
Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 44 / 57.
observer deseni, subject olarak adlandırılan bir nesnenin, ne zaman bir şey olduğunu kimin dinlediğini bilmeden diğer kodlara bildirmesini sağlar. Subject, callback işlevlerinin (observer'ların) bir listesini tutar ve her olayda bunların her birini çağırır:
make_subject <- function() {
observers <- list()
list(
subscribe = function(f) observers[[length(observers) + 1]] <<- f,
notify = function(event) for (f in observers) f(event)
)
}
button <- make_subject()
button$subscribe(function(e) cat("logger saw", e, "\n"))
button$subscribe(function(e) cat("counter saw", e, "\n"))
button$notify("click")Çıktı:
logger saw click
counter saw click Bir gözlemci, kendi durumuna sahip bir kapanış olabilir. Bu kapanış gördüğü olayları sayarken, konu sayma hakkında hiçbir şey bilmez:
make_subject <- function() {
observers <- list()
list(subscribe = function(f) observers[[length(observers) + 1]] <<- f,
notify = function(event) for (f in observers) f(event))
}
make_counter <- function() {
n <- 0
list(observe = function(event) n <<- n + 1, count = function() n)
}
door <- make_subject()
c1 <- make_counter()
door$subscribe(c1$observe)
for (e in c("open", "close", "open")) door$notify(e)
print(c1$count())Çıktı:
[1] 3Gözlemcileri adlar altında saklamak, abonelikten çıkmalarına olanak tanır. observers[[name]] <<- NULL birini kaldırır ve diğerleri olayları almaya devam eder:
make_subject <- function() {
observers <- list()
list(
subscribe = function(name, f) observers[[name]] <<- f,
unsubscribe = function(name) observers[[name]] <<- NULL,
notify = function(event) for (f in observers) f(event)
)
}
s <- make_subject()
s$subscribe("ada", function(e) cat("ada:", e, "\n"))
s$subscribe("bo", function(e) cat("bo:", e, "\n"))
s$notify("first")
s$unsubscribe("ada")
s$notify("second")Çıktı:
ada: first
bo: first
bo: second Özne, bir olayın hangi verileri taşıyacağını belirler. Bir fiyat göstergesi eski ve yeni fiyatı iletir ve yalnızca fiyat gerçekten değiştiğinde bildirimde bulunur:
make_ticker <- function(price) {
observers <- list()
list(
subscribe = function(f) observers[[length(observers) + 1]] <<- f,
set_price = function(new) {
if (new == price) return(invisible(NULL))
old <- price
price <<- new
for (f in observers) f(old, new)
}
)
}
t <- make_ticker(10)
t$subscribe(function(old, new) cat("price", old, "->", new, "\n"))
for (p in c(12, 12, 9)) t$set_price(p)Çıktı:
price 10 -> 12
price 12 -> 9 Görev
Kolaymake_newsletter() fabrikasını Newsletter.R içinde tamamla. Okuyucularının geri çağırmalarını özel bir adlandırılmış listede tutar ve üç işlev döndürür:
subscribe(name, f)geri çağırmayı adın altında saklar (yeniden abone olmak mevcut kaydın yerini alır);unsubscribe(name)kaydı kaldırır;publish(title)her geri çağırmayı başlıkla, abonelik sırasına göre çağırır ve bildirim gönderilenlerin sayısını döndürür.
Sağlanan kod sub ada, unsub ada ve post Big news komutlarını okur ve her okuyucuya ada got: Big news yazdıran bir geri çağırma verir. Her gönderi için başlığı, geri çağırmaların satırlarını ve bildirim gönderilenlerin sayısını yazdırır.
Kodun Newsletter.R içine yazılmalıdır. main.R sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
source("Newsletter.R")
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
news <- make_newsletter()
reader <- function(name) {
force(name)
function(title) cat(" ", name, " got: ", title, "\n", sep = "")
}
for (line in input) {
p <- strsplit(line, " ")[[1]]
if (p[1] == "sub") news$subscribe(p[2], reader(p[2]))
if (p[1] == "unsub") news$unsubscribe(p[2])
if (p[1] == "post") {
title <- paste(p[-1], collapse = " ")
cat("post: ", title, "\n", sep = "")
n <- news$publish(title)
cat(" notified ", n, "\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