Introducción: por qué SOLID es importante para el desarrollador Java
En el mundo de la programación orientada a objetos, el mantenimiento y la extensión del código se vuelven cada vez más complejos con el tiempo. Sin una arquitectura clara, incluso un proyecto pequeño se convierte en una "gran bola de barro", donde cambiar una función rompe otras diez. Aquí es donde vienen al rescate los principios SOLID — cinco reglas fundamentales de diseño de clases formuladas por Robert Martin (Tío Bob).
Para el desarrollador Java, SOLID no es solo teoría, sino una herramienta práctica. Java, como lenguaje fuertemente tipado con un potente sistema de interfaces y herencia, es ideal para implementar estos principios. En este artículo, analizaremos cada principio desde el punto de vista teórico y mostraremos ejemplos de código vivo en Java que se pueden aplicar inmediatamente en un proyecto.
1. Single Responsibility Principle (Principio de Responsabilidad Única)
Teoría
SRP establece: una clase debe tener una sola razón para cambiar. En otras palabras, la clase debe ser responsable de una funcionalidad única y claramente definida. Si una clase hace demasiado, se vuelve difícil de probar, modificar y reutilizar.
Práctica en Java
Consideremos una violación típica de SRP: una clase que simultáneamente gestiona los datos del usuario y envía notificaciones:
// ❌ Violación de SRPpublic class User { private String name; private String email;
public void saveToDatabase() { // Guardar en BD }
public void sendWelcomeEmail() { // Enviar email }}La solución correcta es dividir la responsabilidad en dos clases:
// ✅ Cumplimiento de SRPpublic class User { private String name; private String email; // Getters y setters}
public class UserRepository { public void save(User user) { // Guardar en BD }}
public class EmailService { public void sendWelcomeEmail(User user) { // Enviar email }}Conclusión: cada clase ahora tiene una sola razón para cambiar. User cambia solo cuando cambia la estructura de datos, UserRepository — cuando cambia la lógica de la BD, EmailService — cuando cambian las plantillas de correo.
2. Open-Closed Principle (Principio de Abierto/Cerrado)
Teoría
OCP afirma: las clases deben estar abiertas para la extensión, pero cerradas para la modificación. Esto significa que la nueva funcionalidad debe añadirse mediante herencia o composición, sin tocar el código ya probado.
Práctica en Java
Imagina que tienes una calculadora de descuentos para diferentes tipos de clientes:
// ❌ Violación de OCPpublic class DiscountCalculator { public double calculateDiscount(String customerType, double amount) { if (customerType.equals(\"Regular\")) { return amount * 0.1; } else if (customerType.equals(\"Premium\")) { return amount * 0.2; } return 0; }}Al añadir un nuevo tipo de cliente (por ejemplo, "Gold"), habría que modificar la clase existente. La solución es usar polimorfismo:
// ✅ Cumplimiento de OCPpublic interface DiscountStrategy { double calculate(double amount);}
public class RegularDiscount implements DiscountStrategy { @Override public double calculate(double amount) { return amount * 0.1; }}
public class PremiumDiscount implements DiscountStrategy { @Override public double calculate(double amount) { return amount * 0.2; }}
public class DiscountCalculator { private DiscountStrategy strategy;
public DiscountCalculator(DiscountStrategy strategy) { this.strategy = strategy; }
public double calculate(double amount) {