Zasady SOLID – (D – dependency inversion principle) – Zasada odwrócenia zależności

Zasada odwrócenia zależności (ang. DIP – dependency inversion principle) mówi, że wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych – oba powinny zależeć od abstrakcji.

Abstrakcje nie powinny zależeć od szczegółów, zaś szczegóły (konkretne implementacje) powinny zależeć od abstrakcji.

Przykład programu przed zastosowaniem zasady DIP:

// Klasa wysokopoziomowa, która zależy od konkretnej implementacji niskopoziomowej
class LightSwitch {
    private Bulb bulb;

    public LightSwitch() {
        this.bulb = new IncandescentBulb();
    }

    public void toggle() {
        if (bulb.isOn()) {
            bulb.turnOff();
        } else {
            bulb.turnOn();
        }
    }
}

// Klasa niskopoziomowa, którą zależy od klas wysokopoziomowych
class Bulb {
    private boolean isOn;

    public void turnOn() {
        isOn = true;
        System.out.println("Bulb turned on");
    }

    public void turnOff() {
        isOn = false;
        System.out.println("Bulb turned off");
    }

    public boolean isOn() {
        return isOn;
    }
}

// Konkretna implementacja żarówki
class IncandescentBulb extends Bulb {
    // Specyficzne dla żarówki zachowania
}

W tym przykładzie klasa LightSwitch (moduł wysokopoziomowy) bezpośrednio tworzy instancję konkretnego typu IncandescentBulb (moduł niskopoziomowy). Zasada DIP jest łamana, ponieważ klasa wysokopoziomowa zależy bezpośrednio od konkretnej implementacji klasy niskopoziomowej.

Przykład programu po zastosowaniu zasady DIP:

// Interfejs abstrakcyjny dla żarówki
interface Bulb {
    void turnOn();
    void turnOff();
    boolean isOn();
}

// Klasa wysokopoziomowa, która zależy od abstrakcji
class LightSwitch {
    private Bulb bulb;

    public LightSwitch(Bulb bulb) {
        this.bulb = bulb;
    }

    public void toggle() {
        if (bulb.isOn()) {
            bulb.turnOff();
        } else {
            bulb.turnOn();
        }
    }
}

// Konkretna implementacja żarówki
class IncandescentBulb implements Bulb {
    private boolean isOn;

    public void turnOn() {
        isOn = true;
        System.out.println("Bulb turned on");
    }

    public void turnOff() {
        isOn = false;
        System.out.println("Bulb turned off");
    }

    public boolean isOn() {
        return isOn;
    }
}

W tym przykładzie klasa LightSwitch teraz przyjmuje obiekt Bulb w konstruktorze, co pozwala na wstrzykiwanie zależności. Teraz klasa wysokopoziomowa zależy od abstrakcji Bulb (interfejsu), a nie od konkretnych implementacji. To spełnia zasadę Dependency Inversion Principle.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *