@Riddle:
W Inversion of Control chodzi po prostu o to, żeby użyć czegoś, w takim sposób żeby nie mieć zależności na to coś w swoim kodzie źródłowym
No i to jest właściwa definicja.
@Sebastian Zakrzewski:
Uciekasz myślami w jakieś pierdoły, klasy, interface'y, pakiety i doszukujesz się 5-ego dna w rzeczy banalnej.
Jak sobie w swojej klasie (metodzie, pakiecie whatever..) napiszę:
private final MyRepository repository = new MyRepository();
To ten mój "moduł" staje się wprost zależny od konkretej implementacji. (dla czepialskich - tak da się to obejść, ale nie zaciemniajmy).
Jeżeli zrobię sobie to tak:
private final IRepository repository = new MyRepository();
to niby mam interface, ale nadal new
powoduje, że mam sztywne połączenie do konkretnej implementacji tego interface'u
Mogę zrobić tak:
public class MyClass{
private final MyRepository repository;
public MyClass(MyRepository repository){
this.repository = repository;
}
}
public class MyController{
public void doSomething(){
var repository = new MyRepository();
var myClass = new MyClass(repository)
}
}
To już jest lepiej niż na początku, bo mogę w tym miejscu wstrzyknąć np. klasę dziedziczącą po MyRepository
, co powoduje, że mam mniej powodów do zmiany dla MyClass, ale wciąż moje możliwości wpłynięcia na to z czego poskładana jest moja aplikacja są ograniczone.
Załóżmy, że wpada jakiś pomysł, że zamiast MySQL mamy użyć MsSQL - dalej jestem w ciemnej d... bo MyClass zbyt restrykcyjnie określa wymagania co do obiektów, które przyjmuje jako swoje zależności. Dlatego robimy tak:
public class MyClass{
private final IRepository repository;
public MyClass(IRepository repository){
this.repository = repository;
}
}
public class MyController{
public void doSomething(){
var repository = new MsRepository();
var myClass = new MyClass(repository)
}
}
Dzięki temu, ani MyClass nie jest zależne od Myrepository, Ta implementacja może nawet nie istnieć w momencie kiedy tworzysz MyClass i możesz się nigdy nie dowiedzieć, że powstała, bo zrobi ją ktoś kiedyś, jak już będziesz pracować winnej firmie.
Użycie interface nie jest warunkiem niezbędnym do tego, żeby mieć "odwrócone sterowanie". Jest to po prostu najpopularniejsze, ale wciąż jedynie jedno z możliwych narzędzi, które można wykorzystać do uzuskania efektu IoC.
W tej zasadzie (i w wielu innych), chodzi o bardzo prostą rzecz. W programowaniu obiektowym należy tworzyć wiele małych (S) bytów, które mogą być łatwo rozszerzane, ale nie ma powodów do ich zmiany (O), mogą być wymieniane, jeżeli tylko spełniają jasno zdefiniowany kontrakt (L), który określa to co naprawdę niezbędne (I), a składanie tych klocków przekazujemy poza nie same (D)