Code Review em Swift: o que verificar e como dar feedback na prática
\n\nCode review não é apenas uma formalidade, mas uma ferramenta poderosa para melhorar a qualidade do código, disseminar conhecimento dentro da equipe e prevenir bugs. No entanto, se a revisão for feita de forma superficial ou, ao contrário, muito agressiva, pode causar mais mal do que bem. Neste artigo, vamos analisar exatamente o que observar ao revisar código Swift para iOS e macOS, e como formular feedback para que seja útil e não magoe os colegas.
\n\n1. Arquitetura e design: olhando para a raiz
\n\nAntes de mergulhar nos detalhes da implementação, avalie a arquitetura geral da solução. Um bom código não é apenas sintaxe, mas também estrutura.
\n\n- \n
- Princípio da Responsabilidade Única (SRP): A classe/função não está tentando fazer demais? Por exemplo, o ViewController não está misturando lógica de negócios com requisições de rede? \n
- MVVM / MVC / VIPER: O código está de acordo com o padrão escolhido? Se o projeto usa MVVM, a ViewModel não deve importar
UIKit. \n - Gerenciamento de dependências: Está sendo usada injeção de dependência (DI) ou os objetos são criados internamente? Dependências rígidas dificultam os testes. \n
- Gerenciamento de memória: Há vazamentos? Verifique closures
@escaping, referências fortes aselfe possíveis ciclos de retenção. \n
// Ruim: referência forte a self em uma closure\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { data, _, _ in\n self.onComplete?() // Vazamento! A closure mantém uma referência forte a self\n }.resume()\n }\n}\n\n// Bom: usando [weak self]\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { [weak self] data, _, _ in\n DispatchQueue.main.async {\n self?.onComplete?()\n }\n }.resume()\n }\n}\n\n2. Segurança de tipos e opcionais: usando o poder do Swift
\n\nSwift é uma linguagem com tipagem forte, e o code review deve refletir isso. Evite "código ObjC em um invólucro Swift".
\n\n- \n
- Force unwrapping: Existe
!onde poderia ser evitado? Useguard letouif let. \n - Enumerações (Enums): Elas estão sendo usadas em vez de constantes de string? Por exemplo, para status de resposta ou tipos de erro. \n
- Result type: O erro é tratado através de
Result<Success, Failure>em vez de retornar um valor opcional e um erro separado? \n - Generic: O uso de genéricos é adequado? Às vezes, eles complicam o código desnecessariamente. \n
// Ruim: force unwrap e constantes de string\nfunc getUser(id: String!) -> User? {\n if id == "admin" {\n return User(name: "Admin")\n }\n return nil\n}\n\n// Bom: enum e extração segura\nenum UserType: String {\n case admin\n case regular\n}\n\nfunc getUser(id: String?) -> User? {\n guard let userId = id, let userType = UserType(rawValue: userId) else {\n return nil\n }\n // ... lógica\n return User(name: userType.rawValue)\n}\n\n3. Performance e trabalho com UI: preservando a bateria e os FPS
\n\nPara aplicações iOS/macOS, a suavidade das animações e a eficiência energética são críticas. Preste atenção a:
\n\n- \n
- Main Thread: Todas as atualizações de UI devem ocorrer na thread principal. Verifique se não há chamadas a
UIViewouNSViewa partir de filas em segundo plano. \n - Cálculos pesados: Cálculos complexos não estão sendo executados na thread principal?