2012-07-31 20 views
33

Niedawno natknąłem się na ten javalobby post http://java.dzone.com/articles/how-changing-java-package na temat pakowania kodu java według funkcji.Czy podejście do poszczególnych elementów jest dobre?

Podoba mi się ten pomysł, ale mam kilka pytań na temat tego podejścia. Zadałem pytanie, ale nie dostałem zadowalającej odpowiedzi. Mam nadzieję, że ktoś na StackOverflow może wyjaśnić moje pytania.

Podoba mi się pomysł pakietu za pomocą funkcji, który znacznie skraca czas przemieszczania się między pakietami, podczas gdy kodowanie i wszystkie powiązane elementy będą w jednym miejscu (pakiet). Ale co z interakcjami między usługami w różnych pakietach?

Załóżmy, że budujemy aplikację blogową i umieszczamy wszystkie operacje związane z użytkownikami (kontrolery/usługi/repozytoria) w pakiecie com.mycompany.myblog.users. I wszystkie operacje związane z wpisami na blogu (kontrolery/usługi/repozytoria) w pakiecie com.mycompany.myblog.posts.

Teraz chcę wyświetlić profil użytkownika wraz ze wszystkimi wpisami, które opublikował. Czy powinienem zadzwonić pod numer myblog.posts.PostsService.getPostsByUser(userId) z myblog.users.UserController.showUserProfile()?

Co ze sprzężeniem między paczkami?

Również tam, gdzie czytam o pakiecie według funkcji, wszyscy mówią, że jest to dobra praktyka. Dlaczego więc wielu autorów książek, a nawet frameworków zachęca do grupowania według warstw? Po prostu ciekawi :-)

Odpowiedz

16

Odpowiedział gdzieś: Spójrz na wujek Bob

Package Design Principles

Wyjaśnia przyczyny i motywacji tych zasad.

EDYCJA: Miałem pisemną oryginalną odpowiedź ponad 2 lata wstecz. Ale się nie zmieniło, ponieważ zostało zaakceptowane. Ale zmieniając go, aby każdy nowy użytkownik mógł skorzystać i uniknąć zgnilizny linków zgodnie z sugestią @bPraktik.

Klasy, które zostaną ponownie użyte razem, powinny być spakowane razem, aby opakowanie mogło być traktowane jako rodzaj kompletnego produktu dostępnego dla Ciebie. A te, które są ponownie używane razem powinny być oddzielone od tych, z których nie są ponownie używane. Na przykład twoje klasy narzędziowe Logowania niekoniecznie są używane razem z klasami plików. Dlatego spakuj wszystkie, rejestrując je osobno. Ale klasy rejestrowania mogą być ze sobą powiązane. Stwórz więc coś w rodzaju kompletnego produktu do logowania, powiedzmy, dla braku lepszego nazwy, które jest używane do logowania commons w słoju (re) używanym i innym osobnym, kompletnym produkcie dla narzędzi użytkowych, ponownie dla braku lepszej nazwy, powiedzmy wspólnoty. io.jar. Jeśli zaktualizujesz bibliotekę commons-io, aby wypowiadać obsługę java nio, niekoniecznie będziesz chciał wprowadzić zmiany w bibliotece rejestrowania. Więc rozdzielenie ich jest lepsze.

Teraz powiedzmy, że chciałeś, aby twoje klasy narzędzi do rejestrowania obsługiwały logi strukturalne, np. Do analizy logów za pomocą narzędzi takich jak splunk. Niektórzy klienci narzędzia do rejestrowania mogą chcieć zaktualizować swoją nowszą wersję; niektóre inne nie. Kiedy więc wydasz nową wersję, spakuj wszystkie klasy, które są potrzebne i ponownie wykorzystaj je do migracji. Tak więc niektórzy klienci twoich klas użytkowych mogą bezpiecznie usunąć twój stary słoik z dziennikiem commons i przejść do słoju commons-logging-new. Niektóre inne klienty nadal są w porządku ze starszym słojem. Jednak żaden klient nie musi mieć obu tych słoików (nowych i starych) tylko dlatego, że zmusił ich do korzystania z niektórych klas dla starszych słoi pakowanych.

Unikaj zależności cyklicznych. zależność od b; b na c; c na d; ale d zależy od a. Scenariusz oczywiście odstrasza, ponieważ bardzo trudno będzie zdefiniować warstwy lub moduły itp. I nie można ich zmieniać niezależnie od siebie nawzajem.

Można również spakować swoje klasy w taki sposób, że jeśli warstwa lub moduł ulegnie zmianie, inne moduły lub warstwy nie muszą się koniecznie zmieniać. Tak więc, na przykład, jeśli zdecydujesz się przejść ze starego środowiska MVC do uaktualnienia API, to tylko widok i kontroler mogą wymagać zmian; twój model nie.

+2

Dobrze połączony artykuł, ale zaktualizuj tę odpowiedź, aby uniknąć zgniotu. – bPratik

+0

@bPratik zaktualizowany. – Atul

10

Istnieje wiele innych aspektów innych niż holowniczy do projektowania pakietu Proponuję spojrzeć na OOAD priciples, zwłaszcza pakietów priciples projektowe jak

rep Release Reuse Zasada równoważności granulka ponowne użycie jest granulatem wydania.

CCP Zasada wspólnego zamknięcia Klasy, które się zmieniają, są pakowane razem.

CRP Zasada wspólnego ponownego wykorzystania Klasy używane razem są spakowane razem.

ADP Zasada zależności zależnych od acyklicznych Wykres zależności pakietów nie może zawierać żadnych cykli.

SDP Zależność stabilna Zasada Zależnie od kierunku stabilności.

SAP Zasada trwałej abstrakcji Abstrakcyjność zwiększa się wraz ze stabilnością.

uzyskać więcej informacji można przeczytać book „Agile Software Development, zasady, wzorce i praktyki”

10

osobiście jak podejście I „pakiet przez funkcję”, chociaż trzeba zastosować sporo wyroku na gdzie narysować granice paczki. Z pewnością jest to wykonalne i rozsądne podejście w wielu okolicznościach.

Prawdopodobnie powinieneś uzyskać połączenie pomiędzy pakietami i modułami za pomocą publicznych interfejsów - dzięki temu sprzęgło będzie czyste i łatwe w zarządzaniu.

Pakiet "blogów" doskonale nadaje się do połączenia z pakietem "użytkownicy", o ile używa do tego dobrze zaprojektowanych publicznych interfejsów.

Jedną dużą radą, jeśli pójdziemy w dół takie podejście: być bardzo troskliwi o swoich zależnościach, a w szczególności uniknąć zależności kołowych między pakietami. Dobry projekt powinien wyglądać jak drzewo zależności - z wyższymi poziomami funkcjonalności w zależności od zestawu wspólnych usług, które zależą od bibliotek funkcji użytkowych itp. W pewnym stopniu zacznie to wyglądać jak architektoniczne "warstwy" z frontem. kończą pakiety wywołujące usługi back-end.

Powiązane problemy