Mejores Prácticas
## Objetivos de Aprendizaje
- Escribir Java limpio y mantenible
- Seguir convenciones de nomenclatura
- Dominar la depuración
- Aplicar pruebas efectivas
## Estilo de Código
### Convenciones de Nomenclatura
```java
// Clases: PascalCase
public class BankAccount { }
// Variables y métodos: camelCase
int accountBalance;
void calculateInterest() { }
// Constantes: UPPER_SNAKE_CASE
static final int MAX_RETRIES = 3;
// Paquetes: minúsculas
package com.company.project;
```
### Formato
```java
// Usar 4 espacios para indentación
// Longitud de línea: máximo ~100 caracteres
// Una declaración por línea
int age;
String name;
// Llaves siempre
if (condition) {
doSomething();
} else {
doOther();
}
```
## Encapsulación
### Siempre Usarla
```java
// Bueno: campos privados, getters/setters públicos
public class Person {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) {
if (age >= 0) this.age = age;
}
}
// Malo: campos públicos
public class Person {
public String name; // ¡Sin encapsulación!
}
```
## Objetos Inmutables
### Cuando Sea Posible
```java
// Clase inmutable
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
}
```
## Manejo de Nulos
### Verificaciones de Nulo
```java
// Objects.requireNonNull
public void setName(String name) {
this.name = Objects.requireNonNull(name, "Name cannot be null");
}
// Optional (Java 8+)
public Optional getNickname() {
return Optional.ofNullable(nickname);
}
// Verificación de String
if (name != null && !name.isEmpty()) { }
// Text Blocks Java 15+
String json = """
{"name": "Alice"}
""";
```
## Mejores Prácticas de Colecciones
### Tipos de Interface
```java
// Usar tipo interface
List list = new ArrayList<>();
Map map = new HashMap<>();
Set set = new HashSet<>();
// No usar tipo concreto en el lado izquierdo
// ArrayList list = new ArrayList<>(); // Menos flexible
```
### Operador Diamante
```java
// Java 7+
List list = new ArrayList<>();
// Sin diamante (verboso)
List list = new ArrayList();
```
## Manejo de Excepciones
### Excepciones Específicas
```java
// Bueno
try {
Integer.parseInt(str);
} catch (NumberFormatException e) {
// Manejar número inválido
}
// Malo - captura todo
try {
Integer.parseInt(str);
} catch (Exception e) { }
```
### No Tragar Excepciones
```java
// Malo
try {
doSomething();
} catch (Exception e) {
// Fallo silencioso - ¡malo!
}
// Bueno - registrar y relanzar o manejar
try {
doSomething();
} catch (Exception e) {
logger.error("Operation failed", e);
throw new RuntimeException(e);
}
```
## Manejo de Strings
### Usar StringBuilder
```java
// Para múltiples concatenaciones
StringBuilder sb = new StringBuilder();
for (String word : words) {
sb.append(word).append(" ");
}
String result = sb.toString();
// No: result += word + " "; // Crea muchas cadenas intermedias
```
### Métodos de String
```java
// Verificar contenido
str.contains("abc");
str.startsWith("Hello");
str.endsWith("World");
// Seguro contra nulos
Objects.toString(obj, "default");
```
## Rendimiento
### Evitar Objetos Innecesarios
```java
// Malo - crea muchas cadenas
String result = "";
for (String s : list) {
result += s + ",";
}
// Bueno
StringBuilder sb = new StringBuilder();
for (String s : list) {
if (sb.length() > 0) sb.append(",");
sb.append(s);
}
String result = sb.toString();
```
### Usar Primitivos Cuando Sea Posible
```java
// Usar int no Integer cuando no necesites null
int count = 0; // Primitivo
Integer count = null; // Solo si necesitas null
```
## Pruebas Efectivas
### Pruebas Unitarias
```java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3));
}
@Test
void testDivideByZero() {
Calculator calc = new Calculator();
assertThrows(ArithmeticException.class,
() -> calc.divide(1, 0));
}
}
```
## Documentación
### Javadoc
```java
/**
* Calculates the area of a rectangle.
*
* @param width the width of the rectangle
* @param height the height of the rectangle
* @return the area (width * height)
* @throws IllegalArgumentException if width or height is negative
*/
public double rectangleArea(double width, double height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Dimensions must be positive");
}
return width * height;
}
```
## toString Efectivo
```java
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
// O (Java 16+)
record Person(String name, int age) { }
```
## Logging
### Usar Logger
```java
import java.util.logging.Logger;
public class MyClass {
private static final Logger logger = Logger.getLogger(MyClass.class.getName());
public void doSomething() {
logger.info("Starting operation");
// código
logger.warning("Potential issue");
}
}
```
## Resumen
- Usar nombres significativos
- Encapsular: campos privados, métodos públicos
- Preferir objetos inmutables
- Manejar nulo explícitamente
- Usar tipos interface para variables
- Capturar excepciones específicas
- Nunca tragar excepciones silenciosamente
- Usar StringBuilder para múltiples concatenaciones
- Escribir pruebas unitarias
- Documentar APIs públicas con Javadoc
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →