0Pricing
Swift Academy · Lección

Abstracciones basadas en protocolos

Dependa de protocolos, no de tipos concretos.

Abstracciones basadas en protocolos es una lección gratuita de Swift Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Swift Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Swift Academy incluye 4 lecciones en total.

Abstracciones basadas en protocolos

Inyectar un protocol en lugar de un tipo concreto permite intercambiar libremente las implementaciones. El consumidor depende únicamente del comportamiento, no de la clase.

Definir un protocolo

Describa la capacidad mediante un protocolo. Cualquier tipo que se ajuste a él puede proporcionarse como dependencia.

protocol Logging {
    func log(_ message: String)
}
print("Protocol describes behavior, not a concrete class.")

Ajustar un tipo concreto al protocolo

Una implementación real se ajusta al protocolo. Es la dependencia de producción.

protocol Logging { func log(_ m: String) }
struct ConsoleLogger: Logging {
    func log(_ m: String) { print("LOG: \(m)") }
}
ConsoleLogger().log("ready")

Depender del protocolo

El tipo de la propiedad del consumidor es el protocol, por lo que acepta cualquier valor que se ajuste a él.

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()

Intercambiar implementaciones

Como el tipo es un protocolo, puede pasar una implementación distinta que se ajuste a él sin modificar el 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()

Programar contra interfaces

Este es el principio de «depender de abstracciones, no de concreciones». El código de alto nivel queda protegido de los detalles de bajo nivel.

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()

Varios tipos conformes

Varios tipos pueden ajustarse al mismo protocolo, cada uno adecuado para un contexto como la red, el disco o la memoria.

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 con varios comportamientos

Los protocolos pueden declarar varios métodos, formando un contrato claro para la dependencia.

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)

Restricciones genéricas

También puede inyectar mediante un parámetro genérico restringido al protocolo, evitando la sobrecarga de los existenciales.

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 estables

Mientras el protocolo se mantenga estable, las implementaciones pueden cambiar internamente sin romper los 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())

Preparar el mocking

Lo más importante es que los protocolos permiten que las pruebas proporcionen un tipo conforme simulado en lugar del real. Ese será el tema de la próxima lección.

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()

Comprobación rápida

¿Por qué inyectar un tipo de protocolo en lugar de una clase concreta?

Resumen

Inyectar un protocol abstrae el tipo concreto, por lo que se puede sustituir por cualquier tipo conforme. Esto sigue el principio de «depender de abstracciones» y permite usar implementaciones alternativas y, sobre todo, dobles de prueba. Siguiente tema: simular dependencias en las pruebas.

Preguntas frecuentes

¿La lección «Abstracciones basadas en protocolos» es gratis?

Sí — el texto completo de «Abstracciones basadas en protocolos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Swift Academy, actualiza a CoddyKit PRO. El curso de Swift Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Abstracciones basadas en protocolos»?

Dependa de protocolos, no de tipos concretos. Practicas Swift Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Swift Academy?

No se requiere experiencia previa. Swift Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Abstracciones basadas en protocolos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Swift Academy?

Sí. Cada lección de Swift Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Por qué utilizar inyección de dependencias
  2. Inyección mediante inicializador
  3. Abstracciones basadas en protocolos
  4. Simulación de dependencias en pruebas
← Volver a Swift Academy