Revisión de código en Swift: cómo dejar de enfurecer a tus colegas y escribir código de nivel senior
¿Alguna vez has enviado un Pull Request y una hora después recibiste 15 comentarios del líder técnico? «¿Force unwrap? ¿En serio?», «¿Y dónde está el manejo de errores?», «Ese controlador de flujo lleva tres días en memoria». ¿Te suena familiar? Bienvenido al mundo de la revisión de código en Swift, un lugar donde incluso los desarrolladores experimentados a veces se sienten como becarios.
En este artículo he recopilado los comentarios más frecuentes que los seniors dejan en las code review. Analizaremos ejemplos reales de código, antipatrones y cómo corregirlos. Esto no es teoría aburrida, es experiencia de combate de cientos de revisiones que te ayudará a escribir código que no provoque ganas de reescribirlo todo desde cero. ¡Allá vamos!
1. Force Unwrap: primer amor y mayor dolor
Empecemos con lo más básico pero eterno. Force unwrap (!) es como conducir sin cinturón de seguridad. Parece cómodo, pero una frenada brusca y terminas en traumatología.
Código malo (típico de junior):
func getUserName() -> String { let name: String? = UserDefaults.standard.string(forKey: "user_name") return name!}¿Qué dirá un senior? «¿Y si no hay nada en UserDefaults? Crash. Siempre. Añade guard let o defaultValue.»
Código bueno:
func getUserName() -> String { guard let name = UserDefaults.standard.string(forKey: "user_name") else { return "Invitado" } return name}Excepción: Force unwrap solo es aceptable en un caso: cuando estás 146% seguro de que el valor existe. Por ejemplo, al trabajar con IBOutlets que estarán garantizadamente inicializados. Pero incluso aquí, un senior recomendará usar private var label: UILabel! — es una convención, no un parche.
2. Números mágicos y cadenas: el código no debe ser un acertijo
Lo segundo que salta a la vista en una revisión de código Swift son las constantes mágicas. «¿Por qué exactamente 0.75? Ah, es el coeficiente de animación... ¿Cuál exactamente?». Si escribes números y cadenas directamente en el código, obligas a tus colegas a jugar al detective.
Código malo:
if user.age > 18 { showAdultContent()}button.layer.cornerRadius = 12let url = "https://api.example.com/v1/users"¿Qué dirá un senior? «18 es un número mágico. Ponlo en una constante. La URL, en un enum. cornerRadius, en una constante de estilo. El código debe leerse como un libro, no como un cifrado.»
Código bueno:
private enum Constants { static let adultAgeLimit = 18 static let defaultCornerRadius: CGFloat = 12 static let baseURL = "https://api.example.com/v1"}
enum APIEndpoint { case users var url: String { switch self { case .users: return Constants.baseURL + "/users" } }}
if user.age > Constants.adultAgeLimit { showAdultContent()}3. Memory Leaks: cómo colgar la aplicación accidentalmente
La revisión de código en Swift rara vez pasa sin discutir los retain cycles. A los seniors les encanta este tema porque muestra si entiendes cómo funciona ARC. El antipatrón más popular es capturar self en un closure sin referencia weak.
Código malo:
class NetworkManager { func fetchData(completion: @escaping (Data) -> Void) { URLSession.shared.dataTask(with: url) { data, _, _ in self.process(data) // self capturado fuertemente completion(data) } }}¿Qué dirá un senior? «Estás manteniendo una referencia fuerte a self dentro del closure. Mientras el closure esté vivo, el objeto no se liberará. Añade [weak self] y verifica si es nil. O usa [unowned self] si sabes con certeza que self sobrevivirá al closure.»
Código bueno:
func fetchDa