Wzorzec Singleton
Część sekcji Programowanie obiektowe ścieżki Swift w Coddy. Lekcja 42 z 57.
Wzorzec projektowy to sprawdzone rozwiązanie typowego problemu projektowego. Wzorzec singleton gwarantuje, że klasa ma dokładnie jedną instancję, dostępną z dowolnego miejsca. W Swift jest to static let przechowujące instancję oraz private init, dzięki któremu nikt nie może utworzyć kolejnej:
final class Settings {
static let shared = Settings()
var theme = "light"
private init() {}
}
Settings.shared.theme = "dark"
print(Settings.shared.theme)Wynik:
darkKażde użycie Settings.shared odnosi się do tego samego obiektu, więc zmiana wprowadzona w jednej części programu jest widoczna wszędzie. static let jest tworzone leniwie przy pierwszym użyciu i bezpiecznie, nawet gdy kilka wątków uruchomi się jednocześnie:
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)Wynik:
3
truePonieważ inicjalizator jest prywatny, Settings() nie kompiluje się poza klasą, co pozwala dotrzymać obietnicy „tylko jednej instancji”:
// let other = Settings() // błąd: inicjalizator 'Settings' jest niedostępny ze względu na poziom dostępu 'private'Używaj singletonów oszczędnie. Singleton to stan globalny: dowolny kod może go zmienić, a testy nie mogą łatwo rozpocząć działania od czystej kopii. Nadają się do rzeczy, które naprawdę występują tylko raz w programie, takich jak rejestrator lub konfiguracja aplikacji; często czytelniej jest przekazać obiekt jako parametr.
// Łatwiejsze do testowania: logger jest przekazywany jako argument
func process(order: Order, log: Logger) { log.write("processing \(order.id)") }Wyzwanie
ŁatwyUzupełnij singleton Logger. Ma instancję static let shared, prywatny inicjalizator, tablicę entries z private(set) oraz log(_:level:), która przechowuje [INFO] message lub [ERROR] message (poziom to info lub error). errorCount jest właściwością obliczaną. Dostarczony kod wywołuje Logger.shared z dwóch różnych funkcji, więc obie muszą uzyskać dostęp do tej samej instancji.
Dostarczony kod odczytuje wiersze info,message lub error,message, przekazuje wiersze informacyjne do handleInfo, a wiersze błędów do handleError, a następnie wyświetla każdy wpis i errors: 1.
Twój kod umieść w plikach Logger.swift i Functions.swift. main.swift zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
// Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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)")
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasMetody i selfInicjalizatoryKlasy są referencjamiPowtórzenie — karta biblioteczna4Hermetyzacja
Kontrola dostępuTylko do odczytu z zewnątrzOchrona stanuInicjalizatory, które mogą zawieśćPodsumowanie — konto bankowe7Polimorfizm i typy generyczne
PolimorfizmRzutowanie typówFunkcje generyczneTypy generycznePodsumowanie – kalkulator kształtów2Struktury i typy wartościowe
StrukturySemantyka wartościMetody modyfikująceStruktura czy klasaPodsumowanie – element inwentarza5Dziedziczenie
PodklasyPrzesłanianie metodInicjalizatory i superfinal i hierarchiePodsumowanie — hierarchia pracowników8Standardowe protokoły
CustomStringConvertibleEquatableComparableHashablePodsumowanie — własne sortowanie11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Swift