Pola Strategy
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Swift di Coddy. Pelajaran 45 dari 57.
Pola strategy menempatkan setiap variasi algoritma dalam tipenya sendiri di balik protokol bersama. Kode yang menggunakannya menyimpan sebuah strategy dan dapat menggantinya saat program berjalan:
protocol ShippingStrategy {
func cost(weight: Int) -> Int
}
struct Standard: ShippingStrategy { func cost(weight: Int) -> Int { 5 + weight } }
struct Express: ShippingStrategy { func cost(weight: Int) -> Int { 15 + weight * 2 } }
struct Checkout {
var shipping: any ShippingStrategy
func total(price: Int, weight: Int) -> Int { price + shipping.cost(weight: weight) }
}
var c = Checkout(shipping: Standard())
print(c.total(price: 100, weight: 3))
c.shipping = Express()
print(c.total(price: 100, weight: 3))Output:
108
121Di Swift, closure sering kali cukup untuk strategi dengan satu method. Tipe ini menyimpan fungsi dan memanggilnya:
struct Sorter {
var rule: (String, String) -> Bool
func sort(_ words: [String]) -> [String] { words.sorted(by: rule) }
}
let words = ["banana", "kiwi", "apple"]
var s = Sorter(rule: <)
print(s.sort(words))
s.rule = { $0.count < $1.count }
print(s.sort(words))Output:
["apple", "banana", "kiwi"]
["kiwi", "apple", "banana"]Strategi ini menggantikan switch di dalam algoritma. Varian baru menjadi tipe baru (atau closure), dan kode yang menggunakannya tetap tidak berubah:
// tanpa strategi: setiap opsi baru mengubah fungsi ini
func cost(kind: String, weight: Int) -> Int {
switch kind { case "standard": return 5 + weight; default: return 15 + weight * 2 }
}
// dengan strategi: Checkout tidak pernah berubah
struct Overnight: ShippingStrategy { func cost(weight: Int) -> Int { 40 } }Strategi dapat dipilih dari data, misalnya dari pengaturan pengguna, dengan factory kecil:
protocol Discount { func apply(_ price: Int) -> Int }
struct NoDiscount: Discount { func apply(_ p: Int) -> Int { p } }
struct Percent: Discount { let rate: Int; func apply(_ p: Int) -> Int { p - p * rate / 100 } }
func discount(for member: String) -> any Discount {
member == "gold" ? Percent(rate: 20) : NoDiscount()
}
print(discount(for: "gold").apply(200))
print(discount(for: "basic").apply(200))Output:
160
200Tantangan
MudahSerangan karakter game adalah sebuah strategi. Protocol Attack memiliki name dan damage(strength:) -> Int. Implementasikan Sword (strength * 2), Bow (strength + 5), dan Magic (menyimpan mana; damage menghasilkan strength * 3 saat mana minimal 10 dan 1 jika tidak; damage sendiri tidak mengubah mana). Hero menyimpan strength dan attack-nya, dan strike() mengembalikan Ada hits with sword for 20.
Kode yang disediakan membaca nama dan strength hero, lalu perintah equip sword, equip bow, equip magic 15, atau strike. Kode tersebut mencetak hasil setiap serangan.
Tulis kodemu di Attack.swift, Sword.swift, Bow.swift, Magic.swift, dan Hero.swift. main.swift berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
// Kode input/output yang disediakan: biarkan apa adanya
var input: [String] = []
while let line = readLine() { input.append(line) }
let head = input[0].split(separator: ",").map(String.init)
var hero = Hero(name: head[0], strength: Int(head[1])!, attack: Sword())
for cmd in input.dropFirst() {
let p = cmd.split(separator: " ").map(String.init)
if p[0] == "strike" { print(hero.strike()); continue }
switch p[1] {
case "bow": hero.attack = Bow()
case "magic": hero.attack = Magic(mana: Int(p[2])!)
default: hero.attack = Sword()
}
}
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