Protokollbaserade abstraktioner
Bero på protokoll, inte konkreta typer.
Protokollbaserade abstraktioner är en gratis lektion i Swift Academy på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Swift Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Swift Academy innehåller totalt 4 lektioner.
Protokollbaserade abstraktioner
Om du injicerar ett protokoll i stället för en konkret typ kan du fritt byta implementation. Den användande koden beror bara på beteendet, inte på klassen.
Definiera ett protokoll
Beskriv funktionen som ett protokoll. Alla typer som uppfyller protokollet kan tillhandahållas som beroendet.
protocol Logging {
func log(_ message: String)
}
print("Protocol describes behavior, not a concrete class.")Låt en konkret typ uppfylla protokollet
En riktig implementation uppfyller protokollet. Det är produktionsberoendet.
protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging {
func log(_ m: String) { print("LOG: \(m)") }
}
ConsoleLogger().log("ready")Förlita dig på protokollet
Den användande kodens egenskap har typen protokoll, så den accepterar alla värden som uppfyller protokollet.
protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging { func log(_ m: String) { print(m) } }
struct Service {
let logger: Logging // protocol, not ConsoleLogger
func run() { logger.log("running") }
}
Service(logger: ConsoleLogger()).run()Byta implementation
Eftersom typen är ett protokoll kan du skicka in en annan implementation som uppfyller protokollet utan att ändra den användande koden.
protocol Logging { func log(_ m: String) }
struct Loud: Logging { func log(_ m: String) { print(m.uppercased()) } }
struct Quiet: Logging { func log(_ m: String) {} }
struct Service { let logger: Logging; func run() { logger.log("hi") } }
Service(logger: Loud()).run()
Service(logger: Quiet()).run()Programmera mot gränssnitt
Detta är principen ”förlita dig på abstraktioner, inte konkreta implementationer”. Kod på hög nivå skyddas från detaljer på låg nivå.
protocol Storage { func save(_ v: Int) }
struct MemoryStore: Storage { func save(_ v: Int) { print("kept \(v)") } }
struct Manager { let store: Storage; func add() { store.save(1) } }
Manager(store: MemoryStore()).add()Flera typer som uppfyller protokollet
Flera typer kan uppfylla samma protokoll, där var och en passar för ett sammanhang som nätverk, disk eller minne.
protocol Source { func value() -> Int }
struct Fixed: Source { func value() -> Int { 10 } }
struct Doubler: Source { func value() -> Int { 20 } }
func use(_ s: Source) { print(s.value()) }
use(Fixed())
use(Doubler())Protokoll med associerat beteende
Protokoll kan deklarera flera metoder och därmed bilda ett tydligt kontrakt för beroendet.
protocol Cache {
func get(_ key: String) -> Int?
func set(_ key: String, _ v: Int)
}
struct Dict: Cache {
var store: [String: Int] = [:]
func get(_ k: String) -> Int? { store[k] }
mutating func set(_ k: String, _ v: Int) { store[k] = v }
}
var c = Dict(); c.set("a", 1)
print(c.get("a") ?? -1)Generiska begränsningar
Du kan även injicera via en generisk parameter som begränsas till protokollet och därmed undvika overhead för existentialtyper.
protocol Greeter { func greet() -> String }
struct English: Greeter { func greet() -> String { "Hello" } }
struct Welcome<G: Greeter> {
let greeter: G
func show() { print(greeter.greet()) }
}
Welcome(greeter: English()).show()Stabila kontrakt
Så länge protokollet förblir stabilt kan implementationerna ändras internt utan att den användande koden påverkas.
protocol Formatter { func format(_ n: Int) -> String }
struct Plain: Formatter { func format(_ n: Int) -> String { "\(n)" } }
struct Padded: Formatter { func format(_ n: Int) -> String { String(format: "%03d", n) } }
func render(_ f: Formatter) { print(f.format(7)) }
render(Plain())
render(Padded())Möjliggör mocking
Det viktiga är att protokoll gör det möjligt för tester att tillhandahålla en falsk implementation i stället för den riktiga. Det är fokus för nästa lektion.
protocol Network { func fetch() -> String }
struct Real: Network { func fetch() -> String { "server data" } }
struct VM { let net: Network; func load() { print(net.fetch()) } }
VM(net: Real()).load()Snabb kontroll
Varför injicera en protokolltyp i stället för en konkret klass?
Sammanfattning
Genom att injicera ett protokoll abstraheras den konkreta typen bort, så att alla typer som uppfyller protokollet kan ersätta den. Detta följer principen ”förlita dig på abstraktioner” och möjliggör alternativa implementationer och, framför allt, testdoubles. Nästa avsnitt handlar om att mocka beroenden i tester.
Lär dig Swift med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 122
- Lektioner
- 409
Vanliga frågor
Är lektionen ”Protokollbaserade abstraktioner” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Swift Academy, inklusive ”Protokollbaserade abstraktioner”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Swift Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Protokollbaserade abstraktioner”?
Bero på protokoll, inte konkreta typer. Ni övar på Swift Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Swift Academy?
Du behöver inga förkunskaper. Utbildningen i Swift Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Protokollbaserade abstraktioner”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Swift Academy-lektionen?
Ja. Varje Swift Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Varför dependency injection
- Constructor injection
- Protokollbaserade abstraktioner
- Mocka beroenden i tester