Clean Code en Go: principios y ejemplos en la práctica
El código limpio (Clean Code) no es solo una tendencia, sino una necesidad para cualquier desarrollador profesional. En el mundo de Go, donde la simplicidad y la legibilidad están integradas en la filosofía del lenguaje, seguir los principios del código limpio es especialmente importante. En este artículo, analizaremos los principios clave de Clean Code en Go con ejemplos prácticos que le ayudarán a escribir código que sea fácil de leer, mantener y ampliar.
1. Nombres de variables y funciones
En Go, los nombres deben ser cortos pero informativos. Cuanto menor sea el ámbito de una variable, más corto puede ser su nombre. Este es uno de los principios básicos de Clean Code en Go.
Ejemplo incorrecto:
func f(a int, b int) int { var x int = a + b return x}Ejemplo correcto:
func Sum(a, b int) int { result := a + b return result}Observe: la función se llama Sum, no f. La variable result indica inmediatamente su propósito. En Go, se usa camelCase para variables locales y PascalCase para entidades exportadas (públicas).
2. Funciones pequeñas y responsabilidad única
Cada función en Go debe hacer solo una cosa. Este es el principio de responsabilidad única (Single Responsibility Principle). Si una función realiza varias tareas, divídala en funciones más pequeñas.
Ejemplo incorrecto: la función hace demasiado:
func ProcessUserData(user User) error { // Validación if user.Name == "" { return errors.New("empty name") } // Guardar en BD err := db.Save(user) if err != nil { return err } // Enviar email err = email.SendWelcome(user.Email) if err != nil { return err } return nil}Ejemplo correcto: separación de responsabilidades:
func ValidateUser(user User) error { if user.Name == "" { return errors.New("empty name") } return nil}
func SaveUser(user User) error { return db.Save(user)}
func SendWelcomeEmail(email string) error { return email.SendWelcome(email)}
func ProcessUserData(user User) error { if err := ValidateUser(user); err != nil { return err } if err := SaveUser(user); err != nil { return err } return SendWelcomeEmail(user.Email)}Este código es fácil de probar, depurar y modificar. Cada función tiene un propósito claro.
3. Manejo de errores en Go
En Go, los errores son valores. Uno de los principales principios de Clean Code en Go es siempre verificar los errores y no ignorarlos. Use el patrón "early return" para reducir la anidación.
Ejemplo incorrecto: ignorar el error:
data, _ := ioutil.ReadFile("config.json")// usamos data sin verificar el errorEjemplo correcto:
data, err := os.ReadFile("config.json")if err != nil { return fmt.Errorf("failed to read config: %w", err)}// trabajamos con dataUse fmt.Errorf con el marcador %w para envolver errores. Esto permite mantener la cadena de llamadas y facilita la depuración.
4. Evite la anidación profunda
La anidación profunda hace que el código sea ilegible. En Go, se usan guard clauses (cláusulas de guarda) y retornos tempranos.
Ejemplo incorrecto:
func GetUserRole(userID int) (string, error) { if userID > 0 { user, err := db.FindUser(userID) if err == nil { if user.IsActive { return user.Role, nil } else { return "", errors.New("user is inactive") } } else { return "", err }