terminal

codeando_simple

terminal

menu

terminal

search_module

guest@codeandosimple: ~/system/search $ grep -r "" .

Press [ENTER] to execute search

Status

Engine: Ready

Database: Online

Index: V2.1.0_LATEST

bash — cat dependency-inversion.md
guest@codeandosimple: ~/blog/solid $ cat dependency-inversion.md

SOLID - DEPENDENCY INVERSION PRINCIPLE_

// "La energía y la persistencia conquistan todas las cosas" - Benjamin Franklin

El Dependency Inversion Principle (DIP) o Principio de Inversión de Dependencias establece que:

  • Los módulos de alto nivel no deberían depender de módulos de bajo nivel. Ambos deberían depender de abstracciones.
  • Las abstracciones no deberían depender de detalles. Los detalles deberían depender de abstracciones.
play_circle

Reproducir video explicativo

En términos más simples... si usamos una clase, en alguna parte del código, y esa clase la extendemos (heredamos), tenemos que poder reemplazarla con cualquiera de las clases hijas, y el programa debe seguir siendo válido.

# ¿Inversión, Abstracciones y Detalles?

Inversión: Cambiar la dirección tradicional de las dependencias en la programación orientada a objetos.

Abstracciones: Interfaces o clases abstractas que definen contratos de comportamiento.

Detalles: Partes específicas y concretas de la implementación de un sistema, como pueden ser Base de Datos, componentes de Interfaz de Usuario.

El Dependency Inversion Principle apunta a reducir el acoplamiento entre el código de alto nivel (políticas, decisiones) y el de bajo nivel (detalles, implementaciones), lo que lleva a sistemas más flexibles y mantenibles.

# ¿Por qué es importante?

Flexibilidad

Facilita el cambio de detalles de implementación sin afectar el código de alto nivel.

Reusabilidad

Los módulos de alto nivel se vuelven más reutilizables al no estar atados a implementaciones específicas.

Mantenibilidad

Mejora la mantenibilidad al disminuir el acoplamiento entre distintas partes del código.

# Síntomas de que no se cumple

Podemos identificar cuándo no estamos respetando el Dependency Inversion Principle:

  • El código de alto nivel está directamente vinculado a implementaciones específicas de bajo nivel.
  • Cambios en los detalles de implementación de bajo nivel afectan el código de alto nivel.
  • Dificultad para cambiar o intercambiar componentes de bajo nivel debido a las dependencias rígidas.

Ejemplo

Imaginemos un sistema de notificaciones para una aplicación.

Sin Dependency Inversion Principle

El sistema de notificaciones está directamente acoplado a una implementación específica de envío de mensajes.

public class NotificationService {
    private EmailService emailService;
    public NotificationService() {
        this.emailService = new EmailService(); // Acoplamiento directo
    }
    public void sendNotification(User user, String message) {
        emailService.sendEmail(user, message);
    }
}

Cambiar a otro método de notificación requeriría modificar NotificationService.

Con Dependency Inversion Principle

Definimos una abstracción para el envío de mensajes y hacemos que NotificationService dependa de esta abstracción.

public interface MessageService {
    void sendMessage(User user, String message);
}
public class EmailService implements MessageService {
    public void sendMessage(User user, String message) {
        // Implementación específica para enviar un email
    }
}
public class NotificationService {
    private MessageService messageService;
    public NotificationService(MessageService service) {
        this.messageService = service; // Dependencia de una abstracción
    }
    public void sendNotification(User user, String message) {
        messageService.sendMessage(user, message);
    }
}

Conclusiones

Al implementar el Dependency Inversion Principle (DIP), NotificationService no depende directamente de EmailService sino de la abstracción MessageService.

Esto significa que podemos cambiar la forma en que se envían los mensajes (por ejemplo, a SMS o notificaciones push) sin tener que modificar NotificationService.

Resumen

El Principio de Inversión de Dependencias es vital para crear sistemas flexibles y desacoplados. Fomenta el diseño de módulos de alto nivel que no dependen de los de bajo nivel, sino de abstracciones, lo que facilita cambios futuros y mejora la mantenibilidad. DIP promueve un diseño de software robusto, donde las modificaciones en detalles de implementación tienen un impacto mínimo en el código de alto nivel, haciendo que el sistema sea más adaptable y fácil de evolucionar.