Abstrações Baseadas em Protocolos
Dependa de protocolos, não de tipos concretos.
Abstrações Baseadas em 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.
Abstrações Baseadas em Protocolos
Injetar um protocolo em vez de um tipo concreto permite trocar livremente as implementações. O consumidor depende apenas do comportamento, não da classe.
Definindo um Protocolo
Descreva a capacidade como um protocolo. Qualquer tipo em conformidade pode ser fornecido como dependência.
protocol Logging {
func log(_ message: String)
}
print("Protocol describes behavior, not a concrete class.")Colocando um Tipo Concreto em Conformidade
Uma implementação real está em conformidade com o protocolo. Ela é a dependência de produção.
protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging {
func log(_ m: String) { print("LOG: \(m)") }
}
ConsoleLogger().log("ready")Dependendo do Protocolo
O tipo da propriedade do consumidor é o protocolo, portanto ela aceita qualquer valor em conformidade.
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()Trocando Implementações
Como o tipo é um protocolo, você pode passar outra implementação em conformidade sem alterar o consumidor.
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()Programando para Interfaces
Este é o princípio de "depender de abstrações, não de concretizações". O código de alto nível fica protegido dos detalhes de baixo nível.
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()Vários Tipos em Conformidade
Vários tipos podem estar em conformidade com o mesmo protocolo, cada um adequado a um contexto, como rede, disco ou memória.
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())Protocolos com Comportamento Associado
Os protocolos podem declarar vários métodos, formando um contrato claro para a dependência.
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)Restrições Genéricas
Você também pode injetar por meio de um parâmetro genérico restrito ao protocolo, evitando a sobrecarga de existenciais.
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()Contratos Estáveis
Enquanto o protocolo permanecer estável, as implementações poderão mudar internamente sem interromper os consumidores.
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())Preparando a Simulação
É importante que os protocolos permitam que os testes forneçam um tipo simulado no lugar do tipo real. Esse é o foco da próxima lição.
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()Verificação Rápida
Por que injetar um tipo de protocolo em vez de uma classe concreta?
Recapitulação
Injetar um protocolo abstrai o tipo concreto, permitindo substituir qualquer tipo em conformidade. Isso segue o princípio de "depender de abstrações" e possibilita implementações alternativas e, principalmente, dublês de teste. A seguir: simulando dependências em testes.
Perguntas Frequentes
A aula “Abstrações Baseadas em Protocolos” é grátis?
Sim — o texto completo de “Abstrações Baseadas em 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 “Abstrações Baseadas em Protocolos”?
Dependa de protocolos, não de tipos concretos. 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 “Abstrações Baseadas em 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
- Por que Usar Injeção de Dependências
- Injeção pelo Inicializador
- Abstrações Baseadas em Protocolos
- Simulação de Dependências em Testes