The art of programming is the art of organizing complexity;
mastering multitude & avoiding its chaos as effectively as possible.
Modularyzacja w projektach stanowi jedną z kluczowych technik, które pozwalają na zachowanie czytelności, skalowalności oraz łatwości w utrzymaniu kodu. Wraz z rozwojem projektów, zwłaszcza tych o większym zakresie, staje się ona ważnym elementem zapewniającym porządek i przejrzystośći w strukturze kodu. Jednakże, wraz z rozwojem projektu, gdy wprowadzane są kolejne zmiany, a programiści przychodzą i odchodzą, łatwo zapomnieć o początkowych założeniach architektury. Z pomocą przychodzą testy automatyczne. Tylko co testować i jak je zrobić? Bez solidnych testów nie jesteśmy w stanie upewnić się, iż nasza struktura modułowa spełnia założenia, które sobie postawiliśmy.
Co testować
Pewne aspekty modułów, takie jak zależności międzymodułowe oraz cykle w języku java możemy testować za pomoc archunit. Biblioteka ta nie rozwiązuje jednak wszystkich problemów. Przyjrzyjmy się dwóm innym szczególnie istotnym przypadkom:
1. Równomierna dystrybucja kodu
Gdy mamy wiele modułów, ale jeden z nich zawiera znaczną większość kodu, modularyzacja traci swoje znaczenie. Przykładowo, jeżeli mamy 15 modułów, a jeden z nich zawiera aż 80% kodu, to nie możemy mówić o rzeczywistej modularyzacji, ponieważ niemal całość kodu jest zawarta w jednym module. Jest to sytuacja, którą należy wyeliminować poprzez automatyczne testowanie rozmiaru modułów.
2. Niektóre modóły powinny być szczególne małe
Ważne jest również zapewnienie, iż poszczególne moduły są niewielkie i stabilne pod kątem wprowadzanych zmian (jak często wprowadzamy zmiany). Na przykład, moduł typu „commons” powinien być niewielki i zawierać ogólną funkcjonalność, która jest często używana w różnych częściach projektu. jeżeli ten moduł staje się zbyt duży, może to prowadzić do problemów z zarządzaniem kodem i jego modyfikacjami. Oczywiście jest to przybliżenie, ponieważ ważniejsze jest minimalizowanie interfejsu modułu i zachowanie jego stabilności pod kątem zmian, co nie musi wiązać się z minimalizacją rozmiaru modułu.
Jak testować
Ponieważ opisane powyżej zagadnienia są dla mnie bardzo istotne postanowiłem je weryfikować w testach. Implementacja może być bardzo prosta i polegać na zliczaniu linii kodu w pakietach. Ku mojemu zaskoczeniu nie znalazłem gotowego narzędzia, które w szybki sposób pozwoliłoby sprawdzać rozmiar modułów.
Przygotowałem więc bibliotekę java, która pozwala na testowanie rozmiaru modułów – module-size-calculator. Biblioteka ta umożliwia analizę rozmiaru modułów w projekcie na podstawie liczby linii kodu (LOC).
Wystarczy zdefiniować zależność
<dependency> <groupId>pl.tfij</groupId> <artifactId>module-size-calculator</artifactId> <version>1.0.0</version> </dependency>Od teraz możemy pisać testy w stylu
ProjectSummary projectSummary = ModuleSizeCalculator.project("src/main/java") .withModule("com.example.module1") .withModule("com.example.module2") .analyze() .verifyEachModuleRelativeSizeIsSmallerThan(0.3) .verifyModuleRelativeSizeIsSmallerThan("com.example.commons", 0.1);Biblioteka pozwala na różnego rodzaju asercje rozmiaru modułów, a jeżeli coś nie zostało przewidziane można, na podstawie wygenerowanego raportu napisać klasyczną asercję w JUnit. Biblioteka pozwala także wygenerować raport w postacie wykresu Mermaid, który może następnie być dołączony np. do dokumentacji.
Po więcej szczegółów i przykładów zapraszam na github.
Przekaz na dziś
Modularyzacja jest kluczowym aspektem projektu. Testuj ją aby mieć pewność, iż nie zanika z czasem.