¿Cuál es la mejor forma de modelar datos? Desde los Struct de c++ nos venimos preguntando esto. Vamos a ver algunas opciones modernas que nos provee la plataforma java.
Cuando trabajamos con objetos que representan datos (DTOs, Value Objects, etc.), distintos lenguajes ofrecen soluciones para evitar el boilerplate.
En este post comparamos:
- Records en Java
- Clases tradicionales
- Lombok
- Data classes en Kotlin
- Case classes en Scala
1. Clase tradicional (Java)
public class Persona {
private final String nombre;
private final int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public String getNombre() { return nombre; }
public int getEdad() { return edad; }
@Override public boolean equals(Object o) { ... }
@Override public int hashCode() { ... }
@Override public String toString() { ... }
}
Ventajas
- Total control
- Compatible con todo (JPA, frameworks)
Desventajas
- Mucho boilerplate
- Propenso a errores
2. Records (Java)
public record Persona(String nombre, int edad) {}
Ventajas
- Ultra conciso
- Inmutabilidad garantizada
- Sin dependencias
Desventajas
- Menos flexible
- No sirve bien con JPA
- No herencia
3. Lombok (@Data)
import lombok.Data;
@Data
public class Persona {
private String nombre;
private int edad;
}
Ventajas
- Reduce mucho código
- Mutable o inmutable (configurable)
Desventajas
- Dependencia externa
- "Magia" en compilación (puede confundir)
- Problemas en tooling/debug
4. Data Classes (Kotlin)
data class Persona(val nombre: String, val edad: Int)
Ventajas
- Muy conciso
- Inmutable por defecto
- copy() incluido
- Destructuring
val (nombre, edad) = persona
Desventajas
- Requiere usar Kotlin
- Interoperabilidad Java no siempre perfecta
5. Case Classes (Scala)
case class Persona(nombre: String, edad: Int)
Ventajas
- Inmutables
- Pattern matching nativo
- copy() automático
- Muy expresivas
persona match {
case Persona(nombre, edad) => println(nombre)
}
Desventajas
- Curva de aprendizaje
- Ecosistema más complejo
Y entonces? Y ninguno es super mejor, pero podemos tener estas reglas:
Java Records
Ideal para:
- DTOs simples
- APIs REST
- Código moderno sin dependencias
Son el "mínimo viable elegante" en Java.
Lombok
Ideal para:
- Proyectos legacy
- Equipos que ya lo usan
Soluciona el problema… pero no es parte del lenguaje.
Kotlin
La mejor experiencia general para modelado de datos.
- copy()
- destructuring
- null-safety
Es claramente superior en ergonomía.
Scala
El más poderoso conceptualmente.
- Pattern matching real
- Inmutabilidad fuerte
- Integración con FP
Pero más complejo.
Clases Java
Siguen siendo necesarias cuando:
- Usás JPA
- Necesitás mutabilidad
- Requerís control total
Si estás en Java moderno → Records
Si querés máxima productividad → Kotlin
Si buscás poder expresivo → Scala
Si estás en legacy → Lombok o clases
