Singleton Kalıbı
Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 42 / 57.
Tasarım kalıbı, yaygın bir tasarım problemine yönelik kanıtlanmış bir çözümdür. Singleton kalıbı, bir sınıfın tam olarak bir örneğe sahip olmasını ve bu örneğe her yerden erişilebilmesini sağlar. Swift'te bu, örneği tutan bir static let ile birlikte, hiç kimsenin başka bir örnek oluşturamaması için bir private init kullanılarak gerçekleştirilir:
final class Settings {
static let shared = Settings()
var theme = "light"
private init() {}
}
Settings.shared.theme = "dark"
print(Settings.shared.theme)Çıktı:
darkSettings.shared öğesinin her kullanımı aynı nesneye başvurur; bu nedenle programın bir bölümünde yapılan değişiklik her yerde görünür. static let ilk kullanımda tembel olarak oluşturulur ve birkaç iş parçacığı aynı anda başlasa bile güvenlidir:
final class Counter {
static let shared = Counter()
private(set) var hits = 0
private init() {}
func hit() { hits += 1 }
}
func pageA() { Counter.shared.hit() }
func pageB() { Counter.shared.hit(); Counter.shared.hit() }
pageA()
pageB()
print(Counter.shared.hits)
print(Counter.shared === Counter.shared)Çıktı:
3
trueBaşlatıcı private olduğu için Settings() sınıfın dışında derlenmez; bu da “yalnızca bir tane” sözünü yerine getirir:
// let other = Settings() // hata: 'Settings' başlatıcısı 'private' koruma seviyesi nedeniyle erişilemezSingleton’ları ölçülü kullanın. Singleton, global durumdur: herhangi bir kod onu değiştirebilir ve testler temiz bir kopyayla başlatılamaz. Logger veya uygulamanın yapılandırması gibi program başına gerçekten tek olan şeyler için uygundurlar; bir nesneyi parametre olarak geçirmek genellikle daha açıktır.
// test için daha net: logger içeriye geçirilir
func process(order: Order, log: Logger) { log.write("processing \(order.id)") }Görev
KolayLogger singleton'ını tamamla. Bir static let shared örneği, private bir başlatıcı, entries değerlerinden oluşan bir private(set) dizisi ve log(_:level:) işlevi vardır; bu işlev [INFO] message veya [ERROR] message değerlerini depolar (level, info ya da error olur). errorCount hesaplanan bir özelliktir. Sağlanan kod, iki farklı işlevden Logger.shared'ı çağırır; bu nedenle her ikisi de aynı örneğe ulaşmalıdır.
Sağlanan kod, info,message veya error,message biçimindeki satırları okur, info satırlarını handleInfo üzerinden ve error satırlarını handleError üzerinden gönderir, ardından her girdiyi ve errors: 1 değerini yazdırır.
Kodun Logger.swift ve Functions.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) }
for line in input {
let p = line.split(separator: ",", maxSplits: 1).map(String.init)
if p[0] == "error" { handleError(p[1]) } else { handleInfo(p[1]) }
}
for e in Logger.shared.entries { print(e) }
print("errors: \(Logger.shared.errorCount)")
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