Diversity w polskim IT
Iveta Jurčíková
Iveta JurčíkováSenior Android Developer @ STRV

Jak mniej kompilować przy pomocy SOLID (na przykładzie Javy)

Dowiedz się, jak możesz mniej kompilować, opierając się przy tym na przykładzie w Javie, który korzysta z jednej z zasad SOLID.
4.05.20213 min
Jak mniej kompilować przy pomocy SOLID (na przykładzie Javy)

Opowiem tutaj tylko o jednej z zasad SOLID - i postaram się nie zanudzić Cię teorią. Ostatnio ponownie trafiłem na SOLID i chcę Ci pokazać kilka świetnych rzeczy, których tam wcześniej nie widziałem. Przenieśmy się trochę do przeszłości i stwórzmy od zera projekt Gradle. Napiszemy go w Javie. Nie wprowadzamy żadnej dodatkowej konfiguracji budowania. Strukturę projektu możesz zobaczyć na poniższym diagramie:


W momencie pisania tego artykułu najnowszą wersją Gradle było v6.8.3. Funkcję kompilacji przyrostowych włącza się domyślnie przy pomocy wtyczki Javy. 

Wyobraźcie sobie, że Client1 korzysta tylko z metody m1, Client2 z metody m2, a Client3 korzysta z metody m3 klasy Service. Jak myślicie, co się stanie, jeśli zmienimy ciało funkcji m3 i zrekompilujemy nasz projekt?

Można pomyśleć, że gdy zmiana ciała metody jest zmianą kompatybilną binarnie, to tylko Service zostanie ponownie skompilowane. Niestety to nie tak. W rzeczywistości cały projekt ulega ponownej kompilacji.

Ci, którzy załapali, o co chodzi, mają mój szacunek. 

Abyśmy mogli zobaczyć wynik bezpośrednio z Gradle, korzystamy z opcji listFiles do kompilacji w Javie - loguje ona nasze pliki do skompilowania.

tasks.withType(JavaCompile) {
    options.listFiles = true
}


Uruchamiamy kompilację plików źródłowych Java za pomocą kompilatora JDK, wywołując zadanie compileJava, które jest zwykle wykonywane przy każdym zadaniu kompilacji lub asemblacji.

./gradlew compileJava


Widzimy teraz, że wszystkie pliki źródłowe zostały ponownie skompilowane!

> Task :compileJava
Source files to be compiled:
/ISP_java/src/main/java/com/jurcik/ivet/service/Service.java
/ISP_java/src/main/java/com/jurcik/ivet/client/Client1.java
/ISP_java/src/main/java/com/jurcik/ivet/client/Client2.java
/ISP_java/src/main/java/com/jurcik/ivet/client/Client3.java

Dlaczego się tak dzieje? 

Z Gradle nie dzieje się nic złego. Otrzymany wynik to oczekiwane zachowanie Javy. Kompatybilność binarna nie ma wpływu na listę skompilowanych plików źródłowych.

Wszystkie deklaracje, które użytkownicy muszą zaimportować w kodzie źródłowym, tworzą zależność kodu źródłowego. Kod źródłowy Client1 zależy zatem od metod m2 i m3, mimo że ich nie wywołuje. Zależność ta oznacza, że zmiana kodu źródłowego m2 lub m3 w Service spowoduje rekompilację Client1, pomimo że ten nie zwraca uwagi na zmiany.

Interface Segregation Principle nam pomoże

Interface Segregation Principle (ISP) polega na tym, że żaden klient nie powinien być zmuszany do polegania na metodach, których nie używa.

Postępujmy zgodnie z tą zasadą, tworząc oddzielny interfejs dla każdej metody. Każdy interfejs udostępnia danemu elementowi Client tylko to, czego ten klient naprawdę potrzebuje. Strukturę ilustruje poniższy diagram.


Przyjrzymy się temu samemu pytaniu jeszcze raz. Jak myślisz, co się stanie, jeśli zmienimy ciało metody m3 od klasy Service, która jest zmianą kompatybilną binarnie, i ponownie skompilujemy projekt?

./gradlew compileJava


No i proszę!

> Task :compileJava
Source files to be compiled:
/ISP_java/src/main/java/com/jurcik/ivet/service/Service.java


Service jest jedyną rzeczą, która została ponownie skompilowana - wszystko dzięki wprowadzeniu interfejsów. 

Jak to wygląda w Kotlinie?

Kompilator Kotlina jest wystarczająco inteligentny, aby rekompilować tylko dotknięte pliki, śledząc zmiany Application Binary Interface („API” dla plików binarnych - więcej o tym procesie przeczytasz tutaj). Nie oznacza to jednak, że zasada ta jest przestarzała! Kompilator to tylko ułatwia. W każdym razie dobrze jest wiedzieć, że trzeba włożyć w to trochę więcej pracy.

Podsumowanie

Każdy programista, który zna programowanie obiektowe, pewnie słyszał o zasadach SOLID. Towarzyszą nam na co dzień, czasem nawet, jak tego nie widzimy. Pomimo że wszyscy mamy je z tyłu głowy, to warto jest poświęcić im trochę więcej czasu. Bo zasady SOLID mają znaczenie i nie kończą się na architekturze systemu. 


Oryginał tekstu w języku angielskim możesz przeczytać tutaj

<p>Loading...</p>