Principios SOLID en Java: teoría y práctica de la A a la Z

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

Principios SOLID en Java: de la teoría a la práctica

\n\n

SOLID es el acrónimo de cinco principios fundamentales de la programación orientada a objetos, formulados por Robert Martin (Tío Bob). Estos principios ayudan a crear código flexible, mantenible y escalable. En este artículo, analizaremos cada principio con ejemplos en Java, mostraremos cómo se violan y cómo aplicarlos correctamente.

\n\n

¿Por qué son necesarios los principios SOLID?

\n

Sin SOLID, el código se convierte rápidamente en "espagueti". ¿Te has encontrado con una situación en la que cambiar una clase rompe otras tres? ¿O cuando un método hace demasiado? SOLID resuelve estos problemas. Cada principio es una regla que hace que el código sea:

\n
    \n
  • Resistente a cambios — los nuevos requisitos no rompen la lógica antigua.
  • \n
  • Comprensible — cada clase se encarga de una sola cosa.
  • \n
  • Comprobable — es fácil escribir pruebas unitarias.
  • \n
\n\n

1. Single Responsibility Principle (SRP) — Principio de responsabilidad única

\n

Enunciado: "Una clase debe tener una sola razón para cambiar".

\n

En palabras simples: una clase debe hacer solo una cosa. Si una clase tiene más de una responsabilidad, es difícil de mantener.

\n\n

Violación de SRP (código malo)

\n
public class OrderService {\n    public void createOrder(Order order) {\n        // Lógica de creación de pedido\n        saveToDatabase(order);\n        sendEmailConfirmation(order);\n    }\n\n    private void saveToDatabase(Order order) {\n        // Guardar en BD\n    }\n\n    private void sendEmailConfirmation(Order order) {\n        // Enviar email\n    }\n}
\n

Problema: la clase se encarga de la lógica de negocio, del trabajo con la BD y del envío de notificaciones. Un cambio en el servicio de email requerirá modificar OrderService.

\n\n

Implementación correcta de SRP

\n
public class OrderService {\n    private final OrderRepository repository;\n    private final EmailService emailService;\n\n    public OrderService(OrderRepository repo, EmailService email) {\n        this.repository = repo;\n        this.emailService = email;\n    }\n\n    public void createOrder(Order order) {\n        repository.save(order);\n        emailService.sendConfirmation(order);\n    }\n}\n\npublic class OrderRepository {\n    public void save(Order order) { /* lógica BD */ }\n}\n\npublic class EmailService {\n    public void sendConfirmation(Order order) { /* lógica email */ }\n}
\n

Ahora cada clase tiene una sola razón para cambiar. OrderService solo cambia cuando se modifica el proceso de negocio de creación de pedidos.

\n\n

2. Open/Closed Principle (OCP) — Principio de abierto/cerrado

\n

Enunciado: "Las clases deben estar abiertas para la extensión, pero cerradas para la modificación".

\n

Esto significa que debes agregar nueva funcionalidad mediante código nuevo, no modificando el existente.

\n\n

Violación de OCP (código malo)

\n
public class AreaCalculator {\n    public double calculateArea(Object shape) {\n        if (shape instanceof Rectangle) {\n            Rectangle r = (Rectangle) shape;\n            return r.width * r.height;\n        } else if (shape instanceof Circle) {\n            Circle c = (Circle) shape;\n            return Math.PI * c.radius * c.radius;\n        }\n        throw new IllegalArgumentException("Unknown shape");\n    }\n}
\n

Para agregar un triángulo, es necesario modificar el método calculateArea — esto viola OCP.

\n\n

Implementación correcta de OCP

\n
public interface Shape {\n    double calculateArea();\n}\n\npublic class Rectangle implements Shape {\n    private double width, height;\n    public Rectangle(double w, double h) { this.width = w; this.height = h; }\n    @Override\n    public double calculateArea() { return width * height; }\n}\n\npublic class Circle implements Shape {\n    private double radius;\n                

Blogs

Book Recommendations