Clean Code em Swift: princípios e exemplos na prática

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

Clean Code em Swift: princípios e exemplos na prática

\n\n

Código limpo (Clean Code) não é apenas um termo da moda, mas uma habilidade fundamental para o desenvolvedor profissional. No ecossistema Swift (iOS/macOS), a qualidade do código impacta diretamente a velocidade de desenvolvimento, a quantidade de bugs e a facilidade de manutenção do projeto. Neste artigo, vamos analisar os princípios-chave do Clean Code aplicados ao Swift e mostrar sua implementação com exemplos práticos.

\n\n

1. Nomenclatura: fale a linguagem do domínio

\n\n

Um bom nome para variável, função ou classe substitui comentários. Em Swift, com seu rico sistema de tipos e valores opcionais, a nomenclatura correta é especialmente importante.

\n\n

Exemplo ruim:

\n
func calc(a: [String: Any]) -> Double {\n    var x = 0.0\n    for (_, v) in a {\n        if let n = v as? Double {\n            x += n\n        }\n    }\n    return x\n}
\n\n

Exemplo bom (Clean Code):

\n
func calculateTotalPrice(of products: [Product]) -> Double {\n    return products.reduce(0) { $0 + $1.price }\n}
\n\n

Princípios de nomenclatura em Swift:

\n
    \n
  • Clareza é mais importante que brevidade: remove(at:) é melhor que rem(at:).
  • \n
  • Use substantivos para tipos: UserViewController, NetworkManager.
  • \n
  • Verbos para funções: fetchData(), saveToCache().
  • \n
  • Variáveis booleanas: comece com is, has, should — isEnabled, hasContent.
  • \n
  • Evite abreviações: backgroundColor em vez de bgColor.
  • \n
\n\n

2. Princípio da Responsabilidade Única (SRP) em Swift

\n\n

Cada classe, estrutura ou função deve ter apenas um motivo para ser alterada. No desenvolvimento iOS, isso é especialmente relevante para ViewControllers, que frequentemente se tornam "objetos divinos".

\n\n

Violando o SRP (ViewController típico):

\n
class ProfileViewController: UIViewController {\n    @IBOutlet weak var nameLabel: UILabel!\n    @IBOutlet weak var avatarImageView: UIImageView!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        // Carregamento de dados\n        let url = URL(string: "https://api.example.com/user")!\n        let data = try! Data(contentsOf: url)\n        let json = try! JSONSerialization.jsonObject(with: data) as! [String: Any]\n        nameLabel.text = json["name"] as? String\n        \n        // Carregamento do avatar\n        let imageUrl = URL(string: json["avatar"] as! String)!\n        let imageData = try! Data(contentsOf: imageUrl)\n        avatarImageView.image = UIImage(data: imageData)\n        \n        // Salvando no cache\n        UserDefaults.standard.set(json, forKey: "cachedUser")\n    }\n}
\n\n

Refatoração seguindo o SRP:

\n
// 1. Serviço separado para trabalhar com rede\nclass UserNetworkService {\n    func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {\n        // ... lógica de rede\n    }\n}\n\n// 2. Gerenciador de cache separado\nclass UserCacheManager {\n    func saveUser(_ user: User) {\n        // ... lógica de cache\n    }\n}\n\n// 3. ViewModel para lógica de negócios\nclass ProfileViewModel {\n    private let networkService = UserNetworkService()\n    private let cacheManager = UserCacheManager()\n    \n    func loadProfile(completion: @escaping (User) -> Void) {\n        networkService.fetchUser { [weak self] result in\n            switch result {\n            case .success(let user):\n                self?.cacheManager.saveUser(user)\n                completion(user)\n            case .failure:\n                // Carrega do cache em caso de erro\n                if let cachedUser = self?.cacheManager.lo                

Blogs

Book Recommendations