Dependency Inversion mit Protokollabstraktionen
Arbeiten Sie mit Abstraktionen statt konkreten Implementierungen und nutzen Sie Swift-Protokolle als Grenzen.
Dependency Inversion mit Protokollabstraktionen ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Dependency-Inversion-Prinzip
Module auf höherer Ebene sollten nicht von Modulen auf niedrigerer Ebene abhängen. Beide sollten von Abstraktionen (Protokollen) abhängen.
// WITHOUT DIP:
class OrderService { let db = SQLiteDatabase() } // depends on concrete
// WITH DIP:
class OrderService { let db: Database } // depends on abstractionDie Abstraktion definieren
Leiten Sie ein Protokoll ab, das den Vertrag erfasst, den Ihr Modul auf höherer Ebene benötigt.
protocol Database {
func save<T: Encodable>(_ value: T, key: String) throws
func load<T: Decodable>(key: String) throws -> T
}Konkrete Implementierungen
Stellen Sie mehrere konkrete Implementierungen hinter dem Protokoll bereit: für die Produktion, für Tests und für zukünftige Alternativen.
class SQLiteDatabase: Database { ... }
class InMemoryDatabase: Database { ... }
class KeychainDatabase: Database { ... }Injektion über den Initializer
Übergeben Sie die Abstraktion über den Initializer – dies ist die expliziteste und am besten testbare Art der Injektion.
class ProfileService {
private let db: Database
init(db: Database) { self.db = db }
}Warum nicht überall Singletons?
Globale Singletons verbergen Abhängigkeiten und erschweren es, Code zu testen und nachzuvollziehen.
// Hard to test:
class Service { func run() { MySingleton.shared.doWork() } }
// Easy to test:
class Service { let dep: MyProtocol; func run() { dep.doWork() } }Protokollabstraktionen in Swift
Swift-Protokolle können associated types, Standardimplementierungen und Kompositionen enthalten – ideal für leistungsfähige Abstraktionen.
protocol Cacheable {
associatedtype Key: Hashable
associatedtype Value
func get(_ key: Key) -> Value?
func set(_ key: Key, value: Value)
}Granularität von Abstraktionen
Interface Segregation: Bevorzugen Sie schmale Protokolle gegenüber überladenen, damit Implementierungen nur das bereitstellen müssen, was Aufrufer benötigen.
// Fat (avoid):
protocol DataStore {
func save(...); func load(...); func delete(...); func query(...); func migrate()
}
// Narrow (prefer):
protocol Readable { func load<T>(...) throws -> T }
protocol Writable { func save<T>(...) throws }DIP mit Combine
Geben Sie aus Protokollmethoden AnyPublisher zurück, damit der zugrunde liegende Publisher-Typ verborgen bleibt.
protocol UserStream {
func userUpdates() -> AnyPublisher<User, Never>
}DIP mit async/await
Protokollmethoden mit async throws sind vollständig mit der strukturierten Nebenläufigkeit von Swift kompatibel.
protocol Analytics {
func track(event: String) async
}
struct FirebaseAnalytics: Analytics {
func track(event: String) async { /* Firebase call */ }
}DIP auf App-Ebene
Verdrahten Sie konkrete Implementierungen am Einstiegspunkt der App (Composition Root), sodass alle Bindings an einer Stelle erfolgen.
@main
struct MyApp: App {
let db: Database = SQLiteDatabase()
let repo: UserRepository = RemoteUserRepository(db: db)
let useCase = FetchUserUseCase(repo: repo)
var body: some Scene {
WindowGroup { ContentView(useCase: useCase) }
}
}Testen mit DIP
Ersetzen Sie in Tests die echten Implementierungen an der Injektionsstelle durch Mocks oder Stubs.
let mockDB = InMemoryDatabase()
let service = ProfileService(db: mockDB)
// Exercise service
XCTAssertEqual(try mockDB.load(key: "profile"), expectedProfile)Kurze Überprüfung
Was besagt das Dependency-Inversion-Prinzip über Module auf höherer Ebene?
Zusammenfassung der Lektion
DIP: Module auf höherer Ebene hängen von Protokollabstraktionen ab; konkrete Typen implementieren diese. Leiten Sie schmale Protokolle ab, injizieren Sie Abhängigkeiten über Initializer und verdrahten Sie alles im Composition Root. Dadurch lassen sich Implementierungen für Tests, Feature-Flags und zukünftige Anforderungen austauschen.
Häufig gestellte Fragen
Ist die Lektion „Dependency Inversion mit Protokollabstraktionen“ kostenlos?
Ja — der vollständige Text von „Dependency Inversion mit Protokollabstraktionen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Dependency Inversion mit Protokollabstraktionen“?
Arbeiten Sie mit Abstraktionen statt konkreten Implementierungen und nutzen Sie Swift-Protokolle als Grenzen. Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Swift Academy zu starten?
Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Dependency Inversion mit Protokollabstraktionen“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?
Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Schichten: Domain, Daten und Präsentation
- Use-Case- und Repository-Pattern
- Dependency Inversion mit Protokollabstraktionen
- Schichten ohne DI-Framework verbinden