Clean Code en Swift: principios y ejemplos
El código limpio (Clean Code) no es solo un término de moda, sino una filosofía de desarrollo que impacta directamente en la velocidad de creación de funcionalidades, la cantidad de errores y el placer de trabajar. Para los desarrolladores de Swift que trabajan en aplicaciones iOS y macOS, es especialmente importante escribir código que sea fácil de leer y mantener, ya que los proyectos viven durante años y los equipos cambian. En este artículo analizaremos los principios fundamentales de Clean Code aplicados a Swift y veremos ejemplos concretos.
1. Nomenclatura: hable el lenguaje del dominio
La nomenclatura correcta es la base de un código legible. Los nombres de variables, funciones y clases deben responder a las preguntas "¿qué?" y "¿por qué?". Evite abreviaturas y nombres de una sola letra (excepto i en bucles cortos).
Ejemplo incorrecto:
func calc(a: Int, b: Int) -> Int { return a * b + 10}Ejemplo correcto:
func calculateTotalPriceWithShipping(itemPrice: Int, shippingCost: Int) -> Int { return itemPrice + shippingCost}Para variables booleanas, use prefijos is, has, should:
var isUserLoggedIn: Bool = falsevar hasCompletedOnboarding: Bool = trueLos nombres de clases deben ser sustantivos (UserManager, NetworkService), y las funciones, verbos o frases verbales (fetchData(), validateEmail()).
2. Funciones: pequeñas y con una sola responsabilidad
Cada función debe hacer exactamente una cosa y hacerla bien. La longitud ideal de una función es de 10 a 20 líneas. Si una función supera las 30 líneas, divídala en funciones más pequeñas.
Ejemplo incorrecto: una función que valida, guarda y envía una notificación.
func processUser(_ user: User) { // Validación guard !user.name.isEmpty else { return } guard user.age > 18 else { return } // Guardado CoreDataManager.shared.save(user) // Notificación NotificationCenter.default.post(name: .userDidRegister, object: nil)}Ejemplo correcto: división en tres funciones separadas.
func processUser(_ user: User) { guard isValid(user) else { return } saveUser(user) notifyUserRegistration()}
private func isValid(_ user: User) -> Bool { return !user.name.isEmpty && user.age > 18}
private func saveUser(_ user: User) { CoreDataManager.shared.save(user)}
private func notifyUserRegistration() { NotificationCenter.default.post(name: .userDidRegister, object: nil)}También evite una gran cantidad de parámetros. Si hay más de tres, agrúpelos en una estructura.
struct SearchConfig { let query: String let category: String? let page: Int let pageSize: Int}
func search(with config: SearchConfig) -> [Result] { ... }3. SOLID en Swift: ejemplos prácticos
Los principios SOLID son la piedra angular del código limpio en lenguajes orientados a objetos. Veamos dos principios clave con ejemplos en Swift.
Principio de responsabilidad única (SRP)
Una clase debe tener solo una razón para cambiar. No mezcle la lógica de red y la UI.
// Violación de SRPclass UserViewController: UIViewController { func fetchUser() { URLSession.shared.dataTask(with: URL(string: "...")!) { ... } } func updateUI() { ... }}
// Correcciónclass UserNetworkService { func fetchUser(completion: (User) -> Void) { ... }}
class UserViewController: UIViewController { let networkService = UserNetworkService() func loadUser() { networkService.fetchUser { [weak self] user in DispatchQueue.main.async { self?.updateU