Introducción: Por qué el código limpio es la clave del éxito de un proyecto
Tarde o temprano, todo desarrollador se enfrenta al código "sucio": nombres de variables sin sentido, funciones de cientos de líneas, bloques repetitivos y números mágicos. Este código es difícil de leer, complicado de mantener y prácticamente imposible de extender sin riesgo de romper toda la aplicación. El libro de Robert Martin "Clean Code" se ha convertido en la biblia para los programadores que buscan escribir código de calidad. En este artículo, analizaremos los principios clave de Clean Code en Java con ejemplos claros que te ayudarán a hacer tu código comprensible, fiable y fácil de mantener.
1. Nomenclatura: habla el lenguaje del negocio
El nombre de una variable, método o clase debe responder a las preguntas: "¿Qué es esto?" y "¿Para qué sirve?". Evita las abreviaturas de una sola letra y los términos abstractos.
Ejemplo incorrecto
int d; // tiempo desde el pedido (en días)List<String> lst = new ArrayList<>();void prc() { ... }Ejemplo correcto
int daysSinceOrder;List<String> customerNames = new ArrayList<>();void processPayment() { ... }Recomendaciones adicionales
- Clases — sustantivos:
Order,CustomerRepository. - Métodos — verbos o pares verbales:
saveOrder(),isValidEmail(). - Evita palabras "ruidosas":
Data,Info,Manager— si no aportan significado.
2. Funciones: cortas, claras, una sola tarea
Una función debe hacer solo una cosa y hacerla bien. La longitud ideal es de 10 a 15 líneas. Si la función no cabe en la pantalla, divídela.
Ejemplo incorrecto: función navaja suiza
public void processOrder(Order order) { // 1. Validación if (order == null || order.getItems().isEmpty()) { throw new IllegalArgumentException("Invalid order"); } // 2. Cálculo de descuento double discount = 0; if (order.getTotal() > 1000) discount = 0.1; // 3. Guardar en BD database.save(order); // 4. Enviar email emailService.sendConfirmation(order.getCustomerEmail());}Ejemplo correcto: separación de responsabilidades
public void processOrder(Order order) { validateOrder(order); applyDiscount(order); persistOrder(order); notifyCustomer(order);}
private void validateOrder(Order order) { if (order == null || order.getItems().isEmpty()) { throw new IllegalArgumentException("Invalid order"); }}
private void applyDiscount(Order order) { if (order.getTotal() > 1000) { order.setDiscount(0.1); }}
private void persistOrder(Order order) { database.save(order);}
private void notifyCustomer(Order order) { emailService.sendConfirmation(order.getCustomerEmail());}3. Evita la duplicación (DRY) y los números mágicos
El código repetitivo es el principal enemigo de la mantenibilidad. Si copias un bloque de código, es hora de extraerlo a un método o constante independiente.
Problema: números mágicos
if (age > 18) { ... } // ¿Qué es 18? ¿Edad mínima? ¿Umbral de descuento?Solución: constantes con nombre
private static final int MINIMUM_DRIVING_AGE = 18;// ...if (age > MINIMUM_DRIVING_AGE) { ... }Ejemplo de duplicación
// Malodouble totalForFirst = price1 * quantity1 * 0.95;double totalForSecond = price2 * quantity2 * 0.95;
// Buenodouble calculateLineTotal(double price, int quantity) { return price * quantity * 0.95;}double totalForFirst = calculateLineTotal(price1, quantity1);double totalForSecond = calculateLineTotal(price2, quantity2);