Patrones de diseño en Swift: guía práctica para desarrolladores iOS/macOS
Los patrones de diseño (design patterns) son soluciones probadas para problemas típicos en el desarrollo de software. Para los desarrolladores iOS/macOS, conocer los patrones en Swift es una habilidad obligatoria que permite crear aplicaciones escalables, testeables y mantenibles. En este artículo analizaremos 4 patrones clave con ejemplos de código reales.
1. Singleton (Instancia única)
Uno de los patrones más populares en el desarrollo iOS. Garantiza que una clase tenga solo una instancia y proporciona un punto de acceso global a ella. Se utiliza para gestionar recursos compartidos: UserDefaults, NetworkManager, Database.
Implementación de Singleton en Swift
class NetworkManager { static let shared = NetworkManager() private init() { } func fetchData(from url: URL) { // lógica de la solicitud print("Datos obtenidos de \\(url)") }}
// UsoNetworkManager.shared.fetchData(from: URL(string: "https://api.example.com")!)Importante: En Swift 5.5+ use actor para seguridad en hilos:
actor SettingsManager { static let shared = SettingsManager() private var settings: [String: String] = [:] func setValue(_ value: String, forKey key: String) { settings[key] = value } func getValue(forKey key: String) -> String? { return settings[key] }}2. Factory Method (Método de fábrica)
Define una interfaz para crear objetos, pero permite que las subclases modifiquen el tipo de objetos creados. Es ideal para crear diferentes tipos de componentes de UI o modelos de datos.
Ejemplo: creación de botones para diferentes plataformas
protocol Button { func render()}
class iOSButton: Button { func render() { print("Mostrando botón iOS con esquinas redondeadas") }}
class macOSButton: Button { func render() { print("Mostrando botón macOS con degradado") }}
protocol ButtonFactory { func createButton() -> Button}
class iOSButtonFactory: ButtonFactory { func createButton() -> Button { return iOSButton() }}
class macOSButtonFactory: ButtonFactory { func createButton() -> Button { return macOSButton() }}
// Usolet factory: ButtonFactory = iOSButtonFactory()let button = factory.createButton()button.render() // "Mostrando botón iOS con esquinas redondeadas"3. Observer (Observador)
Permite que los objetos se suscriban a eventos y reciban notificaciones sobre cambios. En Swift se implementa mediante NotificationCenter, Combine o didSet.
Implementación mediante Combine (iOS 13+)
import Combine
class WeatherStation { @Published var temperature: Double = 0.0 func updateTemperature(_ temp: Double) { temperature = temp }}
class WeatherDisplay { var subscriptions = Set<AnyCancellable>() let station = WeatherStation() func startObserving() { station.$temperature .sink { [weak self] newTemp in print("Temperatura cambiada: \\(newTemp)°C") self?.updateUI(with: newTemp) } .store(in: &subscriptions) } private func updateUI(with temp: Double) { // Actualización de la interfaz }}Implementación clásica mediante protocolo
protocol Observer: AnyObject { func update(value: Int)}
class Subject { private var observers = [Observer]() func attach(_ observer: Observer) { observers.append(observer) } func detach(_ observer: Observer) { observers.removeAll { $0 === obs