0Pricing
Swift Academy · Lekcja

Dlaczego warto stosować dependency injection

Oddzielanie tworzenia obiektów od ich użycia w celu ułatwienia testowania.

Dlaczego warto stosować dependency injection to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 1 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.

Dlaczego wstrzykiwanie zależności

Wstrzykiwanie zależności (DI) oznacza przekazywanie obiektowi potrzebnych mu elementów z zewnątrz zamiast pozwalania mu na samodzielne ich tworzenie. Dzięki temu komponenty są luźniej powiązane i łatwiej je testować.

Problem: silne powiązanie

Gdy typ samodzielnie tworzy współpracujące z nim obiekty, zostaje związany z ich konkretnymi klasami i nie można go rekonfigurować ani testować w izolacji.

class Logger {
    func log(_ m: String) { print("LOG: \(m)") }
}
class Service {
    let logger = Logger() // hard-coded dependency
    func run() { logger.log("running") }
}
Service().run()

Powiązania utrudniają testowanie

Ponieważ Service zawsze tworzy prawdziwy obiekt Logger, test nie może przechwycić ani podrobić danych wyjściowych dziennika. Zależność jest niewidoczna z zewnątrz.

class Logger { func log(_ m: String) { print(m) } }
class Service {
    let logger = Logger()
    func run() { logger.log("hello") }
}
// No way to swap Logger here.
Service().run()

Pomysł: wstrzyknąć zależność

Zamiast tego należy przekazać zależność z zewnątrz. To wywołujący decyduje, którą implementację dostarczyć, więc Service nie musi już tego wiedzieć.

class Logger { func log(_ m: String) { print("LOG: \(m)") } }
class Service {
    let logger: Logger
    init(logger: Logger) { self.logger = logger }
    func run() { logger.log("running") }
}
Service(logger: Logger()).run()

Korzyści z rozdzielenia

Dzięki wstrzykiwaniu ten sam Service działa z różnymi obiektami rejestrującymi, zarówno w środowisku produkcyjnym, jak i podczas testów, bez zmieniania jego kodu.

class Logger { var lines: [String] = []
    func log(_ m: String) { lines.append(m) } }
class Service {
    let logger: Logger
    init(logger: Logger) { self.logger = logger }
    func run() { logger.log("event") }
}
let l = Logger()
Service(logger: l).run()
print(l.lines)

Pojedyncza odpowiedzialność

DI wspiera zasadę pojedynczej odpowiedzialności: typ koncentruje się na swoim zadaniu, a pozostałe kwestie przekazuje wstrzykniętym obiektom współpracującym.

struct Mailer { func send(_ to: String) { print("Mail to \(to)") } }
struct SignupFlow {
    let mailer: Mailer
    func register(_ email: String) { mailer.send(email) }
}
SignupFlow(mailer: Mailer()).register("a@b.com")

Elastyczność

Obiekty można łączyć na nowe sposoby. Konfiguracja odbywa się na obrzeżach aplikacji, dzięki czemu jej rdzeń pozostaje elastyczny.

struct Engine { let power: Int }
struct Car {
    let engine: Engine
    func describe() { print("Power: \(engine.power)") }
}
Car(engine: Engine(power: 200)).describe()
Car(engine: Engine(power: 90)).describe()

Jawne zależności

Inicjalizator, który wymienia zależności, dokładnie dokumentuje potrzeby danego typu. Ukryte zależności tworzone samodzielnie zacierają ten kontrakt.

struct Repo { func load() -> [Int] { [1, 2, 3] } }
struct Report {
    let repo: Repo // visible dependency
    func total() -> Int { repo.load().reduce(0, +) }
}
print(Report(repo: Repo()).total())

Komponowanie zamiast konstruowania

DI zachęca do komponowania obiektów z zewnątrz. Niewielki główny punkt kompozycji składa cały graf, a pozostała część kodu po prostu otrzymuje to, czego potrzebuje.

struct DB { func count() -> Int { 42 } }
struct Stats { let db: DB; func show() { print(db.count()) } }
// Composition root:
let app = Stats(db: DB())
app.show()

Nie tylko dla dużych aplikacji

Korzyści odnoszą nawet niewielkie programy: wstrzyknięcie zależności umożliwia podmienianie zachowania i jasno pokazuje intencje bez dodatkowych frameworków.

struct Clock { func now() -> Int { 12 } }
struct Greeter {
    let clock: Clock
    func greet() { print(clock.now() < 12 ? "Morning" : "Afternoon") }
}
Greeter(clock: Clock()).greet()

Framework nie jest potrzebny

DI w Swift nie wymaga biblioteki. Wystarczą zwykłe inicjalizatory i protokoły. W kolejnych lekcjach pokazano wstrzykiwanie przez konstruktor, protokoły i mockowanie.

struct Adder { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct Calc {
    let adder: Adder
    func run() { print(adder.add(2, 3)) }
}
Calc(adder: Adder()).run()

Szybki test

Na czym polega główna idea wstrzykiwania zależności?

Podsumowanie

Wstrzykiwanie zależności dostarcza obiekty współpracujące z zewnątrz, zamiast tworzyć je wewnątrz, dzięki czemu zmniejsza powiązania, wyjaśnia zależności i umożliwia testowanie. W Swift nie wymaga frameworka. Następnie poznają Państwo najczęściej stosowaną formę: wstrzykiwanie przez konstruktor.

Często zadawane pytania

Czy lekcja „Dlaczego warto stosować dependency injection” jest bezpłatna?

Tak — pełny tekst „Dlaczego warto stosować dependency injection” 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 „Dlaczego warto stosować dependency injection”?

Oddzielanie tworzenia obiektów od ich użycia w celu ułatwienia testowania. Ć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 1 z 4.

Ile czasu zajmuje lekcja „Dlaczego warto stosować dependency injection”?

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