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
- Dlaczego warto stosować dependency injection
- Wstrzykiwanie przez konstruktor
- Abstrakcje oparte na protokołach
- Mockowanie zależności w testach