Inversão de dependências com abstrações de protocolos
Dependa de abstrações, não de implementações concretas, usando protocolos Swift como limites.
Inversão de dependências com abstrações de protocolos é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.
Princípio da Inversão de Dependência
Os módulos de alto nível não devem depender dos módulos de baixo nível. Ambos devem depender de abstrações, ou seja, protocolos.
// WITHOUT DIP:
class OrderService { let db = SQLiteDatabase() } // depends on concrete
// WITH DIP:
class OrderService { let db: Database } // depends on abstractionDefinição da Abstração
Extraia um protocolo que represente o contrato de que seu módulo de alto nível precisa.
protocol Database {
func save<T: Encodable>(_ value: T, key: String) throws
func load<T: Decodable>(key: String) throws -> T
}Implementações Concretas
Forneça várias implementações concretas por trás do protocolo: para produção, para testes e para alternativas futuras.
class SQLiteDatabase: Database { ... }
class InMemoryDatabase: Database { ... }
class KeychainDatabase: Database { ... }Injeção pelo Inicializador
Passe a abstração pelo inicializador — esse é o estilo de injeção mais explícito e testável.
class ProfileService {
private let db: Database
init(db: Database) { self.db = db }
}Por que não usar Singletons para tudo?
Singletons globais ocultam dependências, tornando o código difícil de testar e de compreender.
// Hard to test:
class Service { func run() { MySingleton.shared.doWork() } }
// Easy to test:
class Service { let dep: MyProtocol; func run() { dep.doWork() } }Abstrações com Protocolos no Swift
Os protocolos do Swift podem conter tipos associados, implementações padrão e composição — características ideais para abstrações completas.
protocol Cacheable {
associatedtype Key: Hashable
associatedtype Value
func get(_ key: Key) -> Value?
func set(_ key: Key, value: Value)
}Granularidade da Abstração
Segregação de Interface: prefira protocolos pequenos a protocolos extensos, para que as implementações forneçam apenas o que os chamadores precisam.
// 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 com Combine
Retorne AnyPublisher dos métodos do protocolo, para que o tipo do publicador subjacente permaneça oculto.
protocol UserStream {
func userUpdates() -> AnyPublisher<User, Never>
}DIP com async/await
Métodos de protocolo marcados com async throws são totalmente compatíveis com a concorrência estruturada do Swift.
protocol Analytics {
func track(event: String) async
}
struct FirebaseAnalytics: Analytics {
func track(event: String) async { /* Firebase call */ }
}DIP no Nível do Aplicativo
Configure as implementações concretas no ponto de entrada do aplicativo, a Raiz de Composição, mantendo todas as associações em um único lugar.
@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) }
}
}Testes com DIP
Nos testes, substitua as implementações reais por objetos simulados no ponto de injeção.
let mockDB = InMemoryDatabase()
let service = ProfileService(db: mockDB)
// Exercise service
XCTAssertEqual(try mockDB.load(key: "profile"), expectedProfile)Verificação Rápida
O que o Princípio da Inversão de Dependência afirma sobre os módulos de alto nível?
Recapitulação da lição
DIP: os módulos de alto nível dependem de abstrações definidas por protocolos; os tipos concretos as implementam. Extraia protocolos pequenos, injete-os pelos inicializadores e configure tudo na Raiz de Composição. Isso permite trocar implementações para testes, ativação de funcionalidades e requisitos futuros.
Perguntas Frequentes
A aula “Inversão de dependências com abstrações de protocolos” é grátis?
Sim — o texto completo de “Inversão de dependências com abstrações de protocolos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.
O que vou aprender em “Inversão de dependências com abstrações de protocolos”?
Dependa de abstrações, não de implementações concretas, usando protocolos Swift como limites. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Swift Academy?
Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Inversão de dependências com abstrações de protocolos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Swift Academy?
Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Camadas: domínio, dados e apresentação
- Padrões de caso de uso e repositório
- Inversão de dependências com abstrações de protocolos
- Integração das camadas sem um framework de DI