Definicja
Zasada odwrócenia zależności (DIP – Dependency Inversion Principle) to jedna z pięciu zasad projektowych SOLID. Jej kluczowe założenia to:
- Moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu. Oba powinny zależeć od abstrakcji.
- Abstrakcje nie powinny zależeć od szczegółów. To szczegóły powinny zależeć od abstrakcji.
Dzięki zastosowaniu DIP logika aplikacji jest odseparowana od szczegółowych implementacji, co zwiększa jej elastyczność, testowalność oraz ułatwia rozbudowę.
Przykład programu przed wdrożeniem DIP
public class LightBulb {
public void turnOn() {
System.out.println("LightBulb is turned on");
}
public void turnOff() {
System.out.println("LightBulb is turned off");
}
}
public class Switch {
private LightBulb lightBulb;
public Switch(LightBulb lightBulb) {
this.lightBulb = lightBulb;
}
public void flip(boolean on) {
if (on) {
lightBulb.turnOn();
} else {
lightBulb.turnOff();
}
}
}
public class Main {
public static void main(String[] args) {
LightBulb lightBulb = new LightBulb();
Switch lightSwitch = new Switch(lightBulb);
lightSwitch.flip(true);
lightSwitch.flip(false);
}
}
W powyższym przykładzie klasa Switch jest ściśle powiązana z klasą LightBulb. Oznacza to, że każda zmiana w implementacji LightBulb może wymagać modyfikacji klasy Switch. Taki kod jest trudny w utrzymaniu i mało elastyczny.
Kod po zastosowaniu zasady DIP
public interface Switchable {
void turnOn();
void turnOff();
}
public class LightBulb implements Switchable{
@Override
public void turnOn() {
System.out.println("LightBulb is turned on");
}
@Override
public void turnOff() {
System.out.println("LightBulb is turned off");
}
}
public class Switch {
private Switchable switchable;
public Switch(Switchable switchable) {
this.switchable = switchable;
}
public void flip(boolean on) {
if(on) {
switchable.turnOn();
} else {
switchable.turnOff();
}
}
}
public class Main {
public static void main(String[] args) {
Switchable lightBulb = new LightBulb();
Switch lightSwitch = new Switch(lightBulb);
lightSwitch.flip(true);
lightSwitch.flip(false);
}
}
Podsumowanie
Dzięki zastosowaniu DIP:
- Klasa
Switchnie zależy od konkretnej implementacji (LightBulb), lecz od interfejsu (Switchable). - Można łatwo podmienić
LightBulbna inną klasę, np.Fan,Heater, bez zmian w klasieSwitch. - Kod jest bardziej elastyczny, testowalny i łatwiejszy w utrzymaniu.
