Principios SOLID en Java: teoría y práctica para código limpio

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

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) {

Blogs

Book Recommendations