Aby rozwinąć bardzo dobrą odpowiedź Vadima, odpowiem na pytanie „czy to kontrowersyjne” pytaniem „nie, nie bardzo”.
Ogólnie rzecz biorąc, segregacja interfejsów jest dobra, ponieważ zmniejsza ogólną liczbę „powodów zmiany” różnych zaangażowanych obiektów. Podstawową zasadą jest to, że gdy interfejs z wieloma metodami musi zostać zmieniony, powiedzmy, aby dodać parametr do jednej z metod interfejsu, wówczas wszyscy odbiorcy interfejsu muszą przynajmniej zostać ponownie skompilowani, nawet jeśli nie użyli zmienionej metody. „Ale to tylko rekompilacja!”, Słyszę, jak mówisz; może to być prawda, ale pamiętaj, że zwykle wszystko, co rekompilujesz, musi zostać wypchnięte jako część poprawki oprogramowania, bez względu na to, jak znacząca jest zmiana w pliku binarnym. Reguły te zostały pierwotnie opracowane na początku lat 90., gdy średnia komputerowa stacja robocza była mniej wydajna niż telefon w kieszeni, płonęło połączenie modemowe o szybkości 14,4 kb, a 3,5 „1,44 MB” dyskietek było głównym nośnikiem wymiennym. Nawet w obecnej erze 3G / 4G użytkownicy Internetu bezprzewodowego często mają plany transmisji danych z ograniczeniami, więc po wydaniu aktualizacji im mniej plików binarnych, które trzeba pobrać, tym lepiej.
Jednak, podobnie jak wszystkie dobre pomysły, segregacja interfejsu może się pogorszyć, jeśli zostanie niewłaściwie wdrożona. Po pierwsze, istnieje możliwość, że segregując interfejsy, utrzymując obiekt, który implementuje te interfejsy (spełniając zależności), względnie niezmieniony, możesz otrzymać „Hydrę”, krewnego anty-wzorca „Boski Obiekt”, w którym wszechwiedząca, wszechpotężna natura obiektu jest ukryta przed zależnymi od wąskich interfejsów. Skończysz z wielogłowym potworem, który jest co najmniej tak trudny do utrzymania, jak Boski Obiekt, plus koszty utrzymania wszystkich jego interfejsów. Nie ma dużej liczby interfejsów, których nie powinieneś przekraczać, ale każdy interfejs zaimplementowany w jednym obiekcie powinien być poprzedzony odpowiedzią na pytanie: „Czy ten interfejs przyczynia się do obiektu”
Po drugie, interfejs dla każdej metody może nie być konieczny, pomimo informacji SRP. Możesz skończyć z „kodem ravioli”; tak wiele kawałków wielkości kęsa, że trudno jest prześledzić, aby dowiedzieć się, gdzie dokładnie się dzieje. Nie jest również konieczne dzielenie interfejsu na dwie metody, jeśli wszyscy obecni użytkownicy tego interfejsu potrzebują obu metod. Nawet jeśli jedna z klas zależnych potrzebuje tylko jednej z dwóch metod, ogólnie dopuszczalne jest, aby nie dzielić interfejsu, jeśli jego metody koncepcyjnie mają bardzo wysoką spójność (dobre przykłady to „metody antonimiczne”, które są ze sobą dokładnie przeciwieństwami).
Segregacja interfejsu powinna opierać się na klasach zależnych od interfejsu:
Jeśli od interfejsu zależy tylko jedna klasa, nie segreguj. Jeśli klasa nie używa jednej lub więcej metod interfejsu i jest to jedyny konsument interfejsu, istnieje duże prawdopodobieństwo, że nie powinieneś narażać tych metod w pierwszej kolejności.
Jeśli istnieje więcej niż jedna klasa zależna od interfejsu, a wszystkie osoby zależne używają wszystkich metod interfejsu, nie segreguj; jeśli musisz zmienić interfejs (w celu dodania metody lub zmiany podpisu), wszyscy obecni konsumenci zostaną dotknięci zmianą niezależnie od tego, czy segregujesz, czy nie (chociaż jeśli dodajesz metodę, której co najmniej jedna osoba zależna nie będzie potrzebować, rozważ ostrożnie, jeśli zmiana powinna zostać zaimplementowana jako nowy interfejs, być może dziedziczący po istniejącym).
Jeśli istnieje więcej niż jedna klasa zależna od interfejsu i nie używają one tych samych metod, jest to kandydat do segregacji. Spójrz na „spójność” interfejsu; czy wszystkie metody wspierają jeden, bardzo konkretny cel programowania? Jeśli możesz zidentyfikować więcej niż jeden główny cel interfejsu (i jego implementatorów), rozważ podzielenie interfejsów wzdłuż tych linii, aby utworzyć mniejsze interfejsy z mniejszą liczbą „powodów do zmiany”.