Introducción: Por qué el código limpio no es un lujo, sino una necesidad
Cada desarrollador se ha encontrado al menos una vez con código que es imposible de entender sin una taza de café y meditación. Variables con nombres como a, b, temp, métodos de 500 líneas de largo y comentarios como «aquí hay magia, no toques» son señales claras de que el proyecto se está convirtiendo en «legacy». Clean Code (Código Limpio) es una filosofía y un conjunto de prácticas que hacen que el código sea legible, fácil de mantener y extensible.
En este artículo, analizaremos los principios clave de Clean Code en el lenguaje Java con ejemplos concretos. Aprenderá cómo escribir código que usted mismo y sus colegas agradecerán leer dentro de seis meses.
Principio 1: Nombres que hablan
El nombre de una variable, método o clase debe responder a tres preguntas: qué es, para qué sirve y cómo se usa. Un mal nombre es la principal fuente de confusión.
Ejemplo malo
public List<Integer> getList(int a) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < a; i++) { list.add(i * 2); } return list;}¿Qué hace este método? ¿Qué es a? ¿Devuelve una lista de números pares? ¿O simplemente multiplica algo por dos?
Ejemplo bueno (Clean Code)
public List<Integer> generateEvenNumbers(int count) { List<Integer> evenNumbers = new ArrayList<>(); for (int i = 0; i < count; i++) { evenNumbers.add(i * 2); } return evenNumbers;}Ahora todo está claro sin comentarios: el método genera una lista de números pares de una longitud determinada.
Reglas de nomenclatura
- Clases: sustantivos (
User,PaymentProcessor) - Métodos: verbos (
saveUser(),calculateTotal()) - Variables: sustantivos con significado (
userName,totalPrice) - Evite: abreviaturas (
usrNm), nombres de una sola letra (excepto contadores de buclei,j)
Principio 2: Métodos pequeños con una sola responsabilidad
Un método debe hacer solo una cosa y hacerla bien. Si un método se puede describir con la conjunción «Y» (primero hace A, Y luego B), entonces debe dividirse.
Ejemplo malo: monolito
public void processOrder(Order order) { // Validación if (order.getItems().isEmpty()) { throw new IllegalArgumentException("Order is empty"); } // Cálculo del costo double total = 0; for (Item item : order.getItems()) { total += item.getPrice() * item.getQuantity(); } // Envío de email EmailService.send(order.getCustomerEmail(), "Your order total: " + total); // Guardado en BD orderRepository.save(order);}Este método hace 4 cosas: valida, calcula, envía un correo y guarda. Si algo se rompe, habrá que buscar la causa en todo el método.
Ejemplo bueno: métodos limpios
public void processOrder(Order order) { validateOrder(order); double total = calculateTotal(order); sendConfirmationEmail(order, total); saveOrder(order);}
private void validateOrder(Order order) { if (order.getItems().isEmpty()) { throw new IllegalArgumentException("Order cannot be empty"); }}
private double calculateTotal(Order order) { return order.getItems().stream() .mapToDouble(item -> item.getPrice() * item.getQuantity()) .sum();}
private void sendConfirmationEmail(Order order, double total) { String message = "Your order total: " + total; EmailService.send(order.getCustomerEmail(), message);}
private void saveOrder(Order order) { orderRepository.save(order);}Cada método es un ladrillo. Se le