Dependency Inversion Principle (DIP) – zasada odwrócenia zależności brzmi następująco:
Wysokopoziomowe moduły nie powinny zależeć od modułów niskopoziomowych – zależności między nimi powinny wynikać z abstrakcji.
Ta zasada mówi, że klasy nie powinny być od siebie zależne. Podczas tworzenia aplikacji należy posługiwać się interfejsami, a nie implementacjami (czyli klasy powinny być zależne od abstrakcji). Klasy zawierające logikę biznesową (wysokopoziomowe moduły) nie powinny być zależne od klas niskopoziomowych.
Przykład: W ustawieniach drukarki możemy wybrać opcję drukowania w kolorze lub czarno-biało.
public class Printer {
private ColorPrint colorPrint;
private BlackPrint blackPrint;
public Printer(ColorPrint colorPrint, BlackPrint blackPrint) {
this.colorPrint = colorPrint;
this.blackPrint = blackPrint;
}
public void print(PrintType printType){
switch(printType){
case Black: blackPrint.print();
break;
case Color: colorPrint.print();
break;
default:
break;
}
}
}
public enum PrintType {
Black,
Color
}
public class BlackPrint {
public void print(){
System.out.println("black printing");
}
}
public class ColorPrint {
public void print(){
System.out.println("color printing");
}
}
W tym przypadku klasa Printer jest uzależniona od klas niższego poziomu – BlackPrint i ColorPrint. Aby nie łamać zasady DIP należy oprzeć działanie tych klas na wspólnym interfejsie, do którego obiektu będziemy odwoływać się w klasie Printer. Obiekt klas BlackPrint lub ColorPrint będzie „wstrzykiwany” do klasy Printer.
public class PrinterDIP {
private IPrint print;
public PrinterDIP(IPrint print) {
this.print = print;
}
public void print(){
print.print();
}
}
public interface IPrint {
void print();
}
public class BlackPrint implements IPrint{
@Override
public void print() {
System.out.println("black printing");
}
}
public class ColorPrint implements IPrint{
@Override
public void print() {
System.out.println("color printing");
}
}