Delegasyon Kalıbı
Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 46 / 57.
Delegasyon, bir nesnenin bazı kararları bir protokol aracılığıyla başka bir nesneye, yani delegesine, devretmesini sağlar. Nesne kendi işini yapar ve değişkenlik gösteren noktalarda delegesine danışır. Apple'ın framework'leri bu kalıbı her yerde kullanır:
protocol DownloadDelegate: AnyObject {
func progress(_ percent: Int)
func finished(_ file: String)
}
final class Downloader {
weak var delegate: DownloadDelegate?
func download(_ file: String) {
for p in [50, 100] { delegate?.progress(p) }
delegate?.finished(file)
}
}
final class Screen: DownloadDelegate {
func progress(_ percent: Int) { print("\(percent)%") }
func finished(_ file: String) { print("done: \(file)") }
}
let screen = Screen()
let d = Downloader()
d.delegate = screen
d.download("photo.png")Çıktı:
50%
100%
done: photo.pngDelege özelliği isteğe bağlıdır ve çağrılarda delegate?. kullanılır; bu nedenle kimse dinlemiyor olsa bile nesne çalışır. weak olarak tanımlandığından nesne, delege nesnesini kendi başına canlı tutmaz; bu da birbirlerine işaret eden nesneler arasındaki güçlü referans döngülerini önler:
weak var delegate: DownloadDelegate? // protokolün yalnızca sınıf olması gerekir: AnyObject
delegate?.finished(file) // delegate yokken hiçbir şey yapmazBir delegate ayrıca soruları yanıtlayabilir; bu da alt sınıflandırma yapmadan nesnenin davranışını özelleştirmesine olanak tanır:
protocol ListDelegate: AnyObject {
func shouldShow(_ item: String) -> Bool
}
final class ListView {
weak var delegate: ListDelegate?
func render(_ items: [String]) -> [String] {
items.filter { delegate?.shouldShow($0) ?? true }
}
}
final class HideDrafts: ListDelegate {
func shouldShow(_ item: String) -> Bool { !item.hasPrefix("draft") }
}
let view = ListView()
let rules = HideDrafts()
print(view.render(["a", "draft b"]))
view.delegate = rules
print(view.render(["a", "draft b"]))Çıktı:
["a", "draft b"]
["a"]Delegasyon, gözlemci deseninden farklıdır: Bir nesnenin kendisine sorular sorduğu ve bilgi verdiği bir delegesi vardır; buna karşın bir konu, yalnızca bilgilendirdiği birçok gözlemciye sahip olabilir.
// delegation: bir partner, soruları yanıtlayabilir
weak var delegate: TableDelegate?
// observer: herhangi sayıda dinleyici, yalnızca bilgilendirilir
private var observers: [(Event) -> Void] = []Görev
KolayBir Checkout, kararlar için temsilcisinden bilgi ister. Yalnızca sınıflar için olan CheckoutDelegate protokolünde discount(for total: Int) -> Int ve didComplete(total: Int) bulunur. Checkout içinde bir weak var delegate bulunur ve pay(_ prices: [Int]) -> Int fiyatları toplar, temsilcinin indirimini çıkarır (temsilci yoksa 0), temsilciye nihai toplamı bildirir ve bu toplamı döndürür. Toplamı 100 veya daha fazla olan işlemlerde %10 indirim yapan ve tamamlanan her toplamı receipts içinde kaydeden bir temsilci olan LoyaltyShop'u uygulayın.
Sağlanan kod, virgülle ayrılmış fiyat satırlarını okur. İlk satır için temsilci olmadan, diğer satırlar için ise bir LoyaltyShop ile ödeme yapar; her toplamı yazdırır ve son olarak receipts: 120 90 çıktısını verir.
Kodunuz CheckoutDelegate.swift, Checkout.swift ve LoyaltyShop.swift dosyalarına yazılmalıdır. main.swift, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
// Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
var input: [String] = []
while let line = readLine() { input.append(line) }
let checkout = Checkout()
let shop = LoyaltyShop()
for (i, line) in input.enumerated() {
if i == 1 { checkout.delegate = shop }
print(checkout.pay(line.split(separator: ",").map { Int($0)! }))
}
print("receipts: " + shop.receipts.map { String($0) }.joined(separator: " "))
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıfları TanımlamaMetotlar ve selfBaşlatıcılarSınıflar ReferanstırTekrar - Kütüphane Kartı4Kapsülleme
Erişim DenetimiDışarıdan Salt OkunurDurumu KorumaBaşarısız Olabilen BaşlatıcılarTekrar - Banka Hesabı7Polimorfizm ve Generic'ler
PolimorfizmTür DönüşümüGeneric FonksiyonlarGeneric TürlerTekrar - Şekil Hesaplayıcı2Struct Yapıları ve Değer Türleri
Struct YapılarıDeğer SemantiğiDeğiştirici MetotlarStruct mı Class mıTekrar - Envanter Öğesi5Kalıtım
Alt sınıflarMetotları Geçersiz KılmaBaşlatıcılar ve superfinal ve HiyerarşilerTekrar - Çalışan Hiyerarşisi11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç AlmaKendi başına pratik yap: Swift playground