Mysle ze najlepiej bedzie wyjasnic to na przykladach, gdyz interfejsy to niby dosc prosty temat ale zajelo mi troche czasu zanim naprawde zaczalem dostrzegac korzysci z uzywania ich.
1. "If w lepszym wydaniu" - kiedys mialem za zadanie zbudowac mechanizm ktory pomoze wielkiej korporacji zatrudniajacej kilka tysiecy pracownikow w rekrutacji i znajdywaniu odpowiednich osob na konkretne stanowisko. Kazdy pracownik mial swoj wlasny profil na ktorym mogl miedzy innymi deklarowac jakie umiejetnosci posiada a inni pracownicy mogli to potwierdzac "lajkujac" jego umiejetnosci. Kazda posada miala swoj profil na ktorym mozna bylo dowiedziec sie o zakresie obowiazkow i wymaganych umiejetnosciach waznych w roznym stopniu. Rekruter mogl wejsc na dany profil a system skanowal, kalkulowal i dopasowywal ludzi do tej posady. W zaleznosci od profilu i jeszcze kilku innych rzeczy, kalkulacja przebiegala w inny sposob. Mozna byloby nawalic mnostwo IFow i ogarnac temat w malo elegancki sposob. Mozna tez to zrobic inaczej. Stworzylem sobie prosty interfejs IScoringSystem z jedna metoda Calculate. Nastepnie stworzylem kilka klas implementujacych ten interfejs ktore robily obliczenia w rozny sposob w zalesnosci od typu profilu. Robiac to w ten sposob, kazda logika jest odseparowana do innej klasy, jesli zajdzie potrzeba dodania kolejnego przypadku to po prostu dodam nowa klase z implementacja, zwroc uwage na to ze dzieki odseparowaniu, dodajac nowa logike, nie musze dotykac istniejacych klas czyli przestrzegana jest druga zasada SOLID. Polecam o nich poczytac.
2. Moduly ktore maja jakies zaleznosci, powinny zalezec od abstrakcji (interface) a nie od konkretnej implementacji. Interface to jest cos w rodzaju kontraktu pomiedzy klasami. Zalozmy ze w swojej aplikacji masz jakis serwis ktory pobiera cos z bazy danych, robi jakies obliczenia i wysyla je do UI. Serwis nie powinien sam pobierac danych, powinien miec modul pod spodem np. repozytorium ktore jest odpowiedzialne TYLKO za gadanie z baza danych (Single Responsibility) Uzywajac interface pomiedzy nimi, jedyna zaleznosc jaka ma serwis to to zeby mu podac jakas klase ktora implementuje ta zaleznosc (wypelnia kontrakt) - nie obchodzi go w jaki sposob dane sa pobierane z bazy danych, moze to byc jakis ORM albo nawet czysty ADO z np stored procedure. Nie ma to dla serwisu zadnego znaczenia.
3. Lubie tez bardzo interfejsy za to ze dzieki nim moge bardzo fajnie rozdzielac prace w zespole. Np mam projekt w ktorym potrzebuje zapisac produkt, wyswietlic wszystkie produkty, wyswietlic produkt po ID. Robie interface IProductRepository z 3 metodami Create, GetAll, GetById a nastepnie prosze kogos o zaimplementowanie go. Ja w tym czasie moge budowac wyzszy modul ktory bedzie zalezny od tego wlasnie interfejsu ale nie bardzo mnie obchodzi w jakis sposob zostanie on zaimplementowany.
4. Wyobraz sobie zespol budujacy gre komputerowa. Pojawia sie problem zeby gra chodzila na kazdej mozliwej konfiguracji komputera. Tworzy sie warstwe abstrakcji odpowiedzialna np za renderowanie grafiki a pozniej rozne implemenracje dla danej konfiguracji. Wyzszy modul ma gdzies logike wyswietlania, on jest tylko zalezny od interfejsu do wyswietlania grafiki.
Mam nadzieje ze dalem troche swiatla na ten temat. Pamieraj jednak ze (przynajmniej wedlug mnie) interfejsy przydaja sie w wiekszych projektach, albo takich gdzie jest plan ze beda rozwijane przez kilka dobrych lat, wiec beda ciagle rozbudowywane i ulepszane. Interfejsy wtedy beda nie raz ratowac Ci zycie i kod bedzie znacznie latwiejszy do ogarniecia. Jesli natomiast robisz cos bardzo malego , sam badz w parze z kolega, czesto interfejsy dodaja tylko niepotrzebnego szumu. Trzeba uzywac ich madrze i tylko jesli zauwazysz ze jest taka potrzeba w przeciwnym wypadku jest to sztuka dla sztuki czyli tzw over engineering.
Pozdrawiam serdecznie