SOLID jest to zestaw zasad dobrego programowania obiektowego. Stanowią fundament projektowania oprogramowania które mogą pomóc programistom tworzyć bardziej zorganizowane, elastyczne i łatwe w utrzymaniu systemy.
Piąta zasada SOLID jest to zasada odwróconej zależności(ang. dependency inversion principle) sformułowana przez Roberta C. Martin.
Jaka jest Definicja ?
Zgodnie z zasadą odwróconej zależności, moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu, ale oba rodzaje modułów powinny zależeć od abstrakcji. Zatem, wszystkie zależności powinny zależeć od abstrakcji, a nie od konkretnego typu.
Jak to osiągnąć?
Używając klas abstrakcyjnych lub interfejsów unikniemy bezpośrednich zależności od konkretnych implementacji. Do ustawiania zmiennych powinniśmy korzystać z wstrzykiwania zależności aby przekazywać odpowiednie zależności zamiast tworzyć je wewnątrz modułów, klas.
W przykładzie zaprezentowanym poniżej klasa Kawiarnia zależy bezpośrednio od konkretnej implementacji Latte, co jest niezgodne z zasadą odwróconej zależności. Ponadto, w przypadku chęci zmiany bądź rozszerzenia zamówienia o dodatkową kawę konieczna byłaby modyfikacja kodu w klasie Kawiarnia.
public class Kawiarnia {
public Latte przygotujLatte;
public Herbatnik przygotujHerbatnik;
public Kawiarnia(){
przygotujLatte = new Latte();
}
public void przygotujZamówienie(){
przygotujLatte.przygotuj();
}
public class App
{
public static void main( String[] args )
{
Kawiarnia kawiarnia = new Kawiarnia();
kawiarnia.przygotujZamówienie();
}
}Zastosowanie odwróconej zależności umożliwia nam uniknięcie tego problemu. Wprowadzenie interfejsu IKawa pozwala bazować na typie abstrakcyjnym, a klasa Kawiarnia zależy już wyłącznie od interfejsu IKawa. Zastosowany wzorzec wstrzykiwania zależności przyczynił się do tego, że klasa Kawiarnia nie wie nic o klasie Latte. Mimo to pośrednio pracuje na niej poprzez interfejs IKawa.
public interface IKawa {
public void przygotuj();
}
public class Latte implements IKawa {
public void przygotuj(){
System.out.println("Latte");
}
}
public class Kawiarnia {
private IKawa kawa;
public Kawiarnia(IKawa kawa){
this.kawa = kawa;
}
public void przygotujZamówienie(){
this.kawa.przygotuj();
}
}
public class App
{
public static void main( String[] args )
{
IKawa kawa = new Latte();
Kawiarnia kawiarnia = new Kawiarnia(kawa);
kawiarnia.przygotujZamówienie();
}
}