Codigo limpio y refactorización

El Principio de Inversión de Dependencias (DIP) establece que los módulos de alto nivel no deberían depender de módulos de bajo nivel; ambos deberían depender de abstracciones. Además, las abstracciones no deben depender de los detalles, sino que los detalles deben depender de las abstracciones.

  • ¿Por qué es importante?
    Este principio promueve un diseño desacoplado, donde los cambios en los módulos de bajo nivel no afectan a los módulos de alto nivel. Facilita la extensibilidad y la testabilidad del código.

Ejemplo 1: Sin Cumplir DIP

Código Malo (Violación del DIP)

Problema: El módulo de alto nivel Notificador depende directamente del módulo de bajo nivel EnviarCorreo. Si necesitamos cambiar la forma de enviar notificaciones (por ejemplo, usar SMS o push notifications), tendremos que modificar la clase Notificador, rompiendo el principio.

1public class EnviarCorreo {
2    public void enviar(String mensaje) {
3        System.out.println("Enviando correo: " + mensaje);
4    }
5}
6
7public class Notificador {
8    private EnviarCorreo correo = new EnviarCorreo();
9
10    public void notificar(String mensaje) {
11        correo.enviar(mensaje);
12    }
13}

Código Bueno (Aplicando DIP)

Solución: Ahora Notificador depende de la abstracción ServicioNotificacion, no de la implementación concreta EnviarCorreo. Esto permite cambiar la forma de enviar notificaciones sin modificar la clase Notificador.

1public interface ServicioNotificacion {
2    void enviar(String mensaje);
3}
4
5public class EnviarCorreo implements ServicioNotificacion {
6    @Override
7    public void enviar(String mensaje) {
8        System.out.println("Enviando correo: " + mensaje);
9    }
10}
11
12public class Notificador {
13    private ServicioNotificacion servicio;
14
15    public Notificador(ServicioNotificacion servicio) {
16        this.servicio = servicio;
17    }
18
19    public void notificar(String mensaje) {
20        servicio.enviar(mensaje);
21    }
22}

Ejemplo 2: Extensión sin Modificación

Supongamos que ahora queremos enviar notificaciones por SMS además de correo.

Beneficio: Gracias a la abstracción ServicioNotificacion, podemos agregar nuevas formas de notificación sin modificar el código existente de Notificador.

1public class EnviarSMS implements ServicioNotificacion {
2    @Override
3    public void enviar(String mensaje) {
4        System.out.println("Enviando SMS: " + mensaje);
5    }
6}
7
8public class Main {
9    public static void main(String[] args) {
10        ServicioNotificacion servicio = new EnviarSMS();
11        Notificador notificador = new Notificador(servicio);
12        notificador.notificar("Hola, este es un mensaje SMS");
13    }
14}

Beneficios de Aplicar el DIP

  1. Desacoplamiento: Los módulos de alto nivel no dependen directamente de los módulos de bajo nivel.
  2. Facilidad de cambio: Las nuevas funcionalidades se pueden agregar sin modificar el código existente.
  3. Mayor testabilidad: Las dependencias pueden ser simuladas (mocked) durante las pruebas.

Siguiendo el Principio de Inversión de Dependencias (DIP), obtendrás un diseño más modular, flexible y mantenible. 😊

  • Loading...