DevCezz

Programistyczny blog dla Ciebie

isp
Wzorce

SOLID – Interface segregation principle

Przedostatnia zasada mnemoniku SOLID. Według tej wytycznej interfejsy należy odpowiednio segregować. Nie jest zalecane tworzenie interfejsu “od wszystkiego”. Powinno się je konstruować w taki sposób, aby miały tylko jedną odpowiedzialność (Single Responsible Principle). Klas implementujących dany interfejs nie należy zmuszać do implementowania funkcjonalności, których nie potrzebują. Naruszono by w ten sposób zasadę Barbary Liskov (Liskov Substitution Principle). Można więc powiedzieć, że jest to reguła korzystająca z dobrodziejstw dwóch innych wytycznych.

Interface segregation principle picture
Należy dzielić duże interfejsy na mniejsze

Można powiedzieć, że interfejs jest kontraktem zawieranym pomiędzy wywołującym a klasą. Jeśli będzie on zbyt długi to łatwo się w nim pogubić (tak jak w prawdziwym życiu). Z tego powodu reguła Interface segregation principle zaleca, aby takie kontrakty zmniejszać, aby miały tylko jedną odpowiedzialność. W ten sposób uzyskujemy luźne powiązania pomiędzy poszczególnymi elementami, a co za tym idzie uzyskujemy łatwość testowania, refaktoringu oraz utrzymania kodu. Przejdźmy zatem do przykładu łamiącego zasadę Segregacji Interfejsów:

public interface Tasks {
	void organizeMeetings();
	void motivateTeam();
}

public class OrganizationManager implements Tasks {

	public void organizeMeetings() {
		// organize meetings
	}

	public void motivateTeam() {
		throw new TypeOfWorkNotSupportedException();
	}
}

public class MotivationManager implements Tasks {

	public void organizeMeetings() {
		throw new TypeOfWorkNotSupportedException();
	}

	public void motivateTeam() {
		// motivate team
	}
}

Załóżmy sytuację, w której wiele innych projektów korzysta z tego interfejsu w podobny sposób. Klasy go implementujące tak naprawdę potrzebują tylko jedną metodę z dwóch dostępnych. Przypuśćmy, że nagle przychodzi wymaganie, które karze nam zrobić zmianę w tym konkretnym interfejsie. W rezultacie w każdym projekcie trzeba obsłużyć to nowe ulepszenie co wiąże się z wieloma zmianami. Z tego powodu zasada Segregacji Interfejsów ma sens, ponieważ znacznie ułatwia nam pracę.

public interface OrganizationTasks {
	void organizeMeetings();
}

public interface MotivationTasks {
	void motivateTeam();
}

public class OrganizationManager implements OrganizationTasks {

	public void organizeMeetings() {
		// organize meetings
	}
}

public class MotivationManager implements MotivationTasks {

	public void motivateTeam() {
		// motivate team
	}
}

W ten sposób unikniemy niepotrzebnych zmian we wszystkich projektach. Dodatkowo atutem jest to, że zadania są odpowiednio posegregowane. Kod jest łatwiejszy do zarządzania i utrzymania.

Podsumowanie

Według mnie zasada Segregacji Interfejsów jest zwieńczeniem dwóch innych reguł. Trzymanie się jej pozwala nam nie tworzyć klas „od wszystkiego„. Jak wszystko, tak i Interface segregation principle nie uchroni nas przed całym złem. Jednak moim zdaniem warto brać ją pod uwagę podczas pisania kodu źródłowego. Z pewnością nasze klasy będą czytelniejsze i łatwiejsze w utrzymaniu. Warto więc się zastanowić czy dobrze rozumiem tę regułę i wiem jak poprawnie ją stosować.

Jak zawsze będę wdzięczny za to, że przekażesz mi swoją opinię na poruszony wyżej temat. Z chęcią zapoznam się również z jakimiś innymi przypadkami łamania zasady Segregacji Interfejsów i próbą ich naprawienia. Zachęcam Cię do wyrażenia swojego zdania w komentarzu bądź wysłania go do mnie bezpośrednio na maila!

Podziel się tym z innymi!