Pola Delegasi
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Swift di Coddy. Pelajaran 46 dari 57.
Delegasi memungkinkan sebuah object menyerahkan beberapa keputusan kepada object lain, yaitu delegate-nya, melalui sebuah protokol. Object tersebut menjalankan tugasnya dan bertanya kepada delegate pada bagian-bagian yang bervariasi. Framework Apple menggunakan pola ini di mana-mana:
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")Output:
50%
100%
done: photo.pngproperty delegate bersifat opsional dan pemanggilannya menggunakan delegate?., jadi object tetap berfungsi meskipun tidak ada yang mendengarkan. Deklarasinya menggunakan weak agar object tidak membuat delegate tetap hidup dengan sendirinya, sehingga siklus retain antara object yang saling menunjuk dapat dihindari:
weak var delegate: DownloadDelegate? // mengharuskan protokol hanya untuk class: AnyObject
delegate?.finished(file) // tidak melakukan apa pun jika tidak ada delegateSebuah delegate juga dapat menjawab pertanyaan, sehingga delegate dapat menyesuaikan perilaku object tanpa membuat subclass:
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"]))Output:
["a", "draft b"]
["a"]Delegasi berbeda dari pola observer: sebuah object memiliki satu delegate yang ditanyai dan diberi tahu, sedangkan sebuah subject dapat memiliki banyak observer yang hanya diberi tahu.
// delegasi: satu mitra, dapat menjawab pertanyaan
weak var delegate: TableDelegate?
// pengamat: pendengar dalam jumlah berapa pun, hanya menerima pemberitahuan
private var observers: [(Event) -> Void] = []Tantangan
MudahCheckout meminta keputusan dari delegatenya. Protokol CheckoutDelegate (khusus class) memiliki discount(for total: Int) -> Int dan didComplete(total: Int). Checkout memiliki weak var delegate, dan pay(_ prices: [Int]) -> Int menjumlahkan harga, mengurangi diskon delegate (0 jika tidak ada delegate), memberi tahu delegate total akhir, lalu mengembalikannya. Implementasikan LoyaltyShop, sebuah delegate yang memberikan diskon 10% untuk total 100 atau lebih dan mencatat setiap total yang selesai di receipts.
Kode yang disediakan membaca baris berisi harga yang dipisahkan koma. Kode ini memproses pembayaran pada baris pertama tanpa delegate dan baris lainnya dengan LoyaltyShop, mencetak setiap total, lalu mencetak receipts: 120 90.
Letakkan kodemu di CheckoutDelegate.swift, Checkout.swift, dan LoyaltyShop.swift. main.swift berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
// Kode input/output yang disediakan: biarkan tetap seperti ini
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: " "))
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Class dan Object
Bekerja dengan FileMendefinisikan ClassMethod dan selfInitializerClass adalah ReferensiUlasan: Kartu Perpustakaan4Enkapsulasi
Kontrol AksesHanya Bisa Dibaca dari LuarMelindungi StateInitializer yang Bisa GagalRangkuman: Rekening Bank7Polimorfisme dan Generik
PolimorfismeKonversi TipeFungsi GenerikTipe GenerikRangkuman: Kalkulator Bentuk2Struct dan Tipe Nilai
StructSemantik NilaiMethod yang Mengubah NilaiStruct atau classRangkuman, Item Inventaris11Proyek: Manajemen Perpustakaan
Buku dan AnggotaPeminjaman BukuLatihan sendiri: Playground Swift