Pattern Singleton
Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 42 di 57.
Un modello di progettazione è una soluzione collaudata a un problema di progettazione comune. Il modello singleton garantisce che una classe abbia esattamente un'istanza, raggiungibile da qualsiasi punto. In Swift è una static let che contiene l'istanza, più un private init affinché nessuno possa crearne un'altra:
final class Settings {
static let shared = Settings()
var theme = "light"
private init() {}
}
Settings.shared.theme = "dark"
print(Settings.shared.theme)Output:
darkOgni utilizzo di Settings.shared fa riferimento allo stesso oggetto, quindi una modifica apportata in una parte del programma è visibile ovunque. static let viene creato in modo lazy al primo utilizzo e in sicurezza anche quando più thread si avviano contemporaneamente:
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)Output:
3
truePoiché l'inizializzatore è privato, Settings() non viene compilato al di fuori della classe, il che mantiene la promessa di avere «una sola» istanza:
// let other = Settings() // errore: l'inizializzatore 'Settings' è inaccessibile a causa del livello di protezione 'private'Usa i singleton con parsimonia. Un singleton è uno stato globale: qualsiasi codice può modificarlo e i test non possono partire facilmente da una copia pulita. Sono adatti a elementi che sono davvero unici per programma, come un logger o la configurazione dell'app; passare un oggetto come parametro è spesso più chiaro.
// Più facile da testare: il logger viene passato come parametro
func process(order: Order, log: Logger) { log.write("processing \(order.id)") }Sfida
FacileCompleta il singleton Logger. Ha un’istanza static let shared, un inizializzatore privato, un array private(set) di entries e log(_:level:), che memorizza [INFO] message oppure [ERROR] message (il livello è info o error). errorCount è una proprietà calcolata. Il codice fornito chiama Logger.shared da due funzioni diverse, quindi entrambe devono raggiungere la stessa istanza.
Il codice fornito legge righe info,message oppure error,message, invia le righe info a handleInfo e quelle di errore a handleError, quindi stampa ogni voce e errors: 1.
Il tuo codice va inserito in Logger.swift e Functions.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
// Codice di input/output fornito: lascialo così com'è
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)")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiMetodi e selfInizializzatoriLe classi sono riferimentiRiepilogo - Tessera della biblioteca4Incapsulamento
Controllo degli accessiSola lettura dall’esternoProteggere lo statoInizializzatori che possono fallireRiepilogo - Conto bancario7Polimorfismo e tipi generici
PolimorfismoCasting dei tipiFunzioni genericheTipi genericiRipasso - Calcolatore di forme2Struct e tipi valore
Le structSemantica dei valoriMetodi mutantiStruct o classeRiepilogo - Articolo di inventario5Ereditarietà
SottoclassiSovrascrivere i metodiInizializzatori e superfinal e gerarchieRiepilogo - Gerarchia dei dipendenti8Protocolli standard
CustomStringConvertibleEquatableComparableHashableRiepilogo - Ordinamento personalizzato11Progetto: Gestione della biblioteca
Libri e utentiPrestito dei libriEsercitati da solo: Playground Swift