Padrões de Projeto em Swift: da Teoria à Prática
Padrões de projeto são soluções comprovadas para problemas típicos no desenvolvimento. Para um desenvolvedor iOS em Swift, dominar padrões não é apenas um diferencial no currículo, mas uma necessidade. Eles ajudam a escrever código limpo, reutilizável e testável. Neste artigo, vamos abordar 5 padrões principais com exemplos reais em Swift.
1. Singleton (Instância Única)
Um dos padrões mais populares em iOS. Garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela.
Implementação em Swift
class NetworkManager { static let shared = NetworkManager() private init() {} // impede a criação de outras instâncias
func requestData(from url: URL) { // lógica da requisição print("Requisição para \\(url.absoluteString)") }}
// UsoNetworkManager.shared.requestData(from: URL(string: "https://api.example.com")!)Quando usar: para gerenciar recursos compartilhados (rede, banco de dados, UserDefaults). Desvantagem: dificulta os testes unitários, portanto, não deve ser abusado.
2. Factory Method (Método Fábrica)
Define uma interface para criar um objeto, mas permite que subclasses alterem o tipo do objeto criado. É ideal quando não se sabe antecipadamente qual objeto será necessário.
Exemplo: criação de elementos de UI
protocol Button { func render()}
class iOSButton: Button { func render() { print("Botão no estilo iOS") }}
class macOSButton: Button { func render() { print("Botão no estilo macOS") }}
enum Platform { case iOS, macOS}
class ButtonFactory { static func createButton(for platform: Platform) -> Button { switch platform { case .iOS: return iOSButton() case .macOS: return macOSButton() } }}
// Usolet button = ButtonFactory.createButton(for: .iOS)button.render() // Botão no estilo iOS3. Observer (Observador)
Permite que objetos se inscrevam em eventos e recebam notificações sobre mudanças. Em Swift, é implementado nativamente através de NotificationCenter e Combine.
Exemplo com NotificationCenter
extension Notification.Name { static let userDidLogin = Notification.Name("userDidLogin")}
class AuthManager { func login() { // lógica de login NotificationCenter.default.post(name: .userDidLogin, object: nil) }}
class ProfileViewController { init() { NotificationCenter.default.addObserver( self, selector: #selector(updateUI), name: .userDidLogin, object: nil ) }
@objc func updateUI() { print("Atualizando perfil após login") }
deinit { NotificationCenter.default.removeObserver(self) }}Alternativa moderna: use Combine (iOS 13+) com @Published e PassthroughSubject para programação reativa.
4. Delegate (Delegado)
Um dos padrões fundamentais do Cocoa Touch. Permite que um objeto delegue a execução de tarefas a outro. É amplamente usado no UIKit (por exemplo, UITableViewDelegate).
Criando seu próprio delegado
protocol DownloadDelegate: AnyObject { func didFinishDownloading(data: Data) func didFailWithError(error: Error)}
class Downloader { weak var delegate: DownloadDelegate?
func download(from url: URL) { // simulação de download let data = Data() delegate?.didFinishDownloading(data: data) }}
class ViewController: UIViewController, DownloadDelegate { let downloader = Downloader()
override fu
```