0Pricing
Swift Academy · Lekcja

Abstrakcje oparte na protokołach

Opieranie zależności na protokołach, a nie na typach konkretnych.

Abstrakcje oparte na protokołach to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Abstrakcje oparte na protokołach

Wstrzykiwanie protokołu zamiast konkretnego typu pozwala swobodnie podmieniać implementacje. Odbiorca zależy wyłącznie od zachowania, a nie od klasy.

Definiowanie protokołu

Należy opisać daną możliwość za pomocą protokołu. Jako zależność można przekazać dowolny typ, który jest z nim zgodny.

protocol Logging {
    func log(_ message: String)
}
print("Protocol describes behavior, not a concrete class.")

Zgodność konkretnego typu

Rzeczywista implementacja jest zgodna z protokołem. To zależność używana w środowisku produkcyjnym.

protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging {
    func log(_ m: String) { print("LOG: \(m)") }
}
ConsoleLogger().log("ready")

Zależność od protokołu

Typ właściwości odbiorcy to protokół, dlatego akceptuje ona dowolną zgodną wartość.

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()

Podmienianie implementacji

Ponieważ typem jest protokół, można przekazać inną zgodną implementację bez modyfikowania odbiorcy.

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()

Programowanie względem interfejsów

Jest to zasada „zależ od abstrakcji, nie od konkretów”. Kod wysokiego poziomu jest chroniony przed szczegółami niskiego poziomu.

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()

Wiele typów zgodnych z protokołem

Wiele typów może być zgodnych z tym samym protokołem, a każdy z nich może być dostosowany do innego kontekstu, takiego jak sieć, dysk lub pamięć.

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())

Protokoły z powiązanym zachowaniem

Protokoły mogą deklarować wiele metod, tworząc jasny kontrakt dla zależności.

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)

Ograniczenia generyczne

Można również wstrzykiwać zależność za pomocą parametru generycznego ograniczonego do protokołu, unikając narzutu związanego z typem egzystencjalnym.

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()

Stabilne kontrakty

Dopóki protokół pozostaje stabilny, można zmieniać wewnętrzne działanie implementacji bez przerywania działania odbiorców.

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())

Przygotowanie do mockowania

Co najważniejsze, protokoły pozwalają testom dostarczyć fikcyjną implementację zgodną z protokołem zamiast prawdziwej. Na tym skupia się następna lekcja.

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()

Szybki test

Dlaczego warto wstrzykiwać typ protokołu zamiast konkretnej klasy?

Podsumowanie

Wstrzykiwanie protokołu ukrywa konkretny typ, dzięki czemu można zastąpić go dowolnym typem zgodnym z protokołem. Jest to zgodne z zasadą „zależ od abstrakcji” i umożliwia stosowanie alternatywnych implementacji oraz, co najważniejsze, obiektów zastępczych w testach. Następnie: mockowanie zależności w testach.

Często zadawane pytania

Czy lekcja „Abstrakcje oparte na protokołach” jest bezpłatna?

Tak — pełny tekst „Abstrakcje oparte na protokołach” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Abstrakcje oparte na protokołach”?

Opieranie zależności na protokołach, a nie na typach konkretnych. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Abstrakcje oparte na protokołach”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dlaczego warto stosować dependency injection
  2. Wstrzykiwanie przez konstruktor
  3. Abstrakcje oparte na protokołach
  4. Mockowanie zależności w testach
← Powrót do Swift Academy