Princípios SOLID em Swift: teoria e prática do A ao Z

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução aos princípios SOLID em Swift

\n

Todo desenvolvedor iOS, mais cedo ou mais tarde, enfrenta o problema do "código espaguete": classes incham, mudanças em um lugar quebram todo o aplicativo e os testes se tornam um pesadelo. A solução para esses problemas está na base do design orientado a objetos — os princípios SOLID. Essas cinco regras, formuladas por Robert Martin, ajudam a criar código flexível, sustentável e escalável em Swift. Neste artigo, vamos analisar cada princípio, da teoria aos exemplos práticos para iOS/macOS.

\n

Independentemente de você estar escrevendo em UIKit, SwiftUI ou AppKit, SOLID é uma base universal. Vamos mergulhar nos detalhes.

\n\n

1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única

\n

Teoria

\n

Uma classe deve ter apenas um motivo para mudar. Em outras palavras, cada módulo é responsável por exatamente uma funcionalidade. Se o seu ViewController gerencia a UI, processa requisições de rede e faz parsing de JSON — ele viola o SRP.

\n

Prática em Swift

\n

Vamos considerar um exemplo típico — carregar e exibir dados do usuário.

\n
// ❌ Ruim: violação do SRP\nclass UserViewController: UIViewController {\n    func loadUser() {\n        // Requisição de rede\n        let url = URL(string: "https://api.example.com/user")!\n        URLSession.shared.dataTask(with: url) { data, _, _ in\n            let user = try? JSONDecoder().decode(User.self, from: data!)\n            DispatchQueue.main.async {\n                self.updateUI(with: user)\n            }\n        }.resume()\n    }\n    \n    func updateUI(with user: User?) {\n        // Atualização da UI\n    }\n}
\n
// ✅ Bom: separando responsabilidades\nclass UserService {\n    func fetchUser(completion: @escaping (User?) -> Void) {\n        let url = URL(string: "https://api.example.com/user")!\n        URLSession.shared.dataTask(with: url) { data, _, _ in\n            let user = try? JSONDecoder().decode(User.self, from: data!)\n            completion(user)\n        }.resume()\n    }\n}\n\nclass UserViewController: UIViewController {\n    let userService = UserService()\n    \n    func loadUser() {\n        userService.fetchUser { [weak self] user in\n            DispatchQueue.main.async {\n                self?.updateUI(with: user)\n            }\n        }\n    }\n    \n    private func updateUI(with user: User?) {\n        // Atualização da UI\n    }\n}
\n

Conclusão: Agora UserService é responsável apenas pela rede, e UserViewController — pela UI. Mudanças na lógica de rede não afetam o controlador.

\n\n

2. Open-Closed Principle (OCP) — Princípio Aberto/Fechado

\n

Teoria

\n

As classes devem estar abertas para extensão, mas fechadas para modificação. Em vez de alterar o código existente, adicionamos novo código através de herança ou protocolos. Em Swift, a ferramenta ideal para isso são os protocolos e extensões.

\n

Prática em Swift

\n

Imagine que estamos escrevendo um módulo para calcular descontos em uma loja online.

\n
// ❌ Ruim: ao adicionar um novo desconto, é necessário modificar a classe\nclass DiscountCalculator {\n    func calculate(price: Double, type: String) -> Double {\n        if type == "seasonal" {\n            return price * 0.9\n        } else if type == "loyalty" {\n            return price * 0.85\n        }\n        return price\n    }\n}
\n
// ✅ Bom: usando protocolo para extensão\nprotocol DiscountStrategy {\n    func applyDiscount(to price: Double) -> Double\n}\n\nstruct SeasonalDiscount: DiscountStrategy {\n    func applyDiscount(to price: Double) -> Double {\n        price * 0.9\n    }\n}\n\nstruct LoyaltyDiscount: DiscountStrategy {\n    func applyDiscount(to price: Double) -> Double {\n        price * 0.85\n    }\n}\n\nclass DiscountCalculator {\n    func calculate(price: Double, strategy: DiscountStrategy) -> Double {\n        strategy.                

Blogs

Book Recommendations