Mogę tylko powiedzieć wam moją opinię organizacji w tej sprawie. My są w procesie przechodzenia do modułów dla każdego pojedynczego projektu, że pracujesz. To, co budujemy, to w zasadzie mikro-usługi + niektóre biblioteki klienckie. W przypadku mikroserwisów przejście na modules
ma w jakiś sposób niższy priorytet: kod tam jest już w jakiś sposób odizolowany w kontenerze dockera, więc „dodawanie” tam modułów nie wydaje się (nam) bardzo ważne. Ta praca jest podejmowana powoli, ale ma niski priorytet.
Z drugiej strony biblioteki klienckie to zupełnie inna historia. Nie mogę ci powiedzieć, jaki bałagan mamy czasami. Wyjaśnię jedną kwestię, której wcześniej nienawidziłem jigsaw
. Udostępniasz interfejs klientom, z których każdy może korzystać. To interface
jest automatycznie public
- wystawiane na świat. Zwykle robię wtedy kilka package-private
klas, które nie są widoczne dla klientów, które używają tego interfejsu. Nie chcę, aby klienci tego używali, jest to wewnętrzne. Brzmi dobrze? Źle.
Pierwszym problemem jest to, że gdy te package-private
klasy rosną i chcesz mieć więcej klas, jedynym sposobem na ukrycie wszystkiego jest utworzenie klas w tym samym pakiecie:
package abc:
-- Usage.java
-- HelperUsage.java
-- FactoryUsage.java
....
Kiedy rośnie (w naszych przypadkach tak), te pakiety są o wiele za duże. Przechodzisz do oddzielnego pakietu, o którym mówisz? Jasne, ale wtedy tak będzie HelperUsage
i FactoryUsage
tak będzie public
i od początku staraliśmy się tego unikać.
Problem numer dwa: każdy użytkownik / dzwoniący naszych klientów może utworzyć tę samą nazwę pakietu i rozszerzyć te ukryte klasy. Zdarzyło nam się to już kilka razy, zabawne czasy.
modules
rozwiązuje ten problem w piękny sposób: public
tak naprawdę public
już nie jest ; Mogę uzyskać friend
dostęp za pośrednictwem exports to
dyrektywy. To znacznie ułatwia cykl życia naszego kodu i zarządzanie nim. I uciekamy od piekła klas. Oczywiście maven/gradle
załatwimy to głównie dla nas, ale kiedy pojawi się problem, ból będzie bardzo realny. Może być też wiele innych przykładów.
To powiedziawszy, przejście nie jest (nadal) łatwe. Przede wszystkim wszyscy w zespole muszą być wyrównani; po drugie są przeszkody. Dwa największe, jakie wciąż widzę, to: jak oddzielić każdy moduł, na podstawie czego konkretnie? Nie mam jeszcze jednoznacznej odpowiedzi. Po drugie split-packages
, och, ta piękna „ta sama klasa jest eksportowana przez różne moduły”. Jeśli tak się stanie z twoimi bibliotekami, istnieją sposoby na złagodzenie; ale jeśli są to biblioteki zewnętrzne ... nie jest to takie proste.
Jeśli polegasz na jarA
i jarB
(oddzielnych modułach), ale oba eksportują abc.def.Util
, możesz się zaskoczyć. Istnieją jednak sposoby rozwiązania tego problemu. W jakiś sposób bolesne, ale możliwe do rozwiązania.
Ogólnie rzecz biorąc, od czasu migracji do modułów (i nadal to robimy), nasz kod stał się znacznie czystszy. A jeśli Twoja firma jest firmą, która stawia na kod, ma to znaczenie. Z drugiej strony byłem zaangażowany w firmy, które były postrzegane przez starszych architektów jako „zbyt drogie”, „brak realnej korzyści”.