Struktura aplikacji Java: podział poziomy i pionowy

15

Trochę debaty na temat początkowej struktury projektu (przy użyciu Maven / Eclipse) dla dużej aplikacji Java.

Opcja 1:

entities (i.e. the whole database using Hibernate classes-first)
services (i.e. sets of read/write operations on the entities)
app (perhaps split up more further down the line)

Opcja 2:

area1-entities
area1-services
area1-app
area2-entities
area2-services
area2-app
...
(where area1, area2 etc. are functional areas of the system)

Wariant 2 wyraźnie przyniesie znacznie więcej projektów / modułów Maven i oznacza, że ​​klasy, które wygenerowałyby bazę danych, są rozdzielone między wiele projektów. Czy ktoś może doradzić zalety / wady każdego podejścia?

Steve Chambers
źródło
3
Ani. IMHO (zaczynamy) powinniśmy przestać oddzielać się od technicznych warstw, które po prostu prowadzą do dużej kuli błota. Zamiast tego pakiet funkcjonalnie. Tylko obszar 1 / obszar 2, który powinien zawierać rdzeń Twojej aplikacji (podmioty, usługi (podzielone na interfejs publiczny i pakiet prywatnego wdrożenia), repozytoria (w razie potrzeby). Teraz powinieneś połączyć swoją warstwę WWW / ws / messaging z tym rdzeniem. chcę
Nadal jest opiniowany :). Ale dopracuję trochę, aby znaleźć odpowiedź.
Dzięki, ale to pytanie dotyczy raczej struktury projektu niż struktury pakietu
Steve Chambers

Odpowiedzi:

29

Sugerowałbym nie robić żadnej z nich.

Próba wymuszenia warstw technicznych za pomocą struktury pakietu prowadzi do dużego splątania w aplikacji. Nie wspominając już o tym, że tak bardzo staramy się ukryć wszystko za interfejsem usługi, a pierwszą rzeczą, którą robimy (głównie z powodu opakowania), jest zrobienie wszystkiego public class. Staje się to bolesne, gdy istnieje techniczna separacja między pakietem x.y.z.servicea x.y.z.repository, a teraz wszystko może uzyskać dostęp do repozytorium. Bum tam jest twoja enkapsulacja w warstwie serwisowej.

Zamiast tego powinieneś zastosować bardziej funkcjonalne i oparte na cebuli podejście ( czysta architektura , architektura heksagonalna ). Jest to również zgodne z zasadą jednolitej odpowiedzialności (w przypadku zastosowania do paczki), a także zgodnie z zasadami pakowania

  1. Rzeczy, które zmieniają się razem, są pakowane razem
  2. Rzeczy, które są używane razem, są pakowane razem

Oliver Gierke napisał fajny post na temat pakowania elementów razem w Javie. Simon Brown napisał bardziej ogólną historię na ten temat.

Chciałbym dążyć do stworzenia podstawowej struktury pakietu, takiej jak poniżej, aby utrzymać rdzeń twojej aplikacji:

x.y.z.area1
x.y.z.area2

Teraz, jeśli masz interfejs sieciowy, dodajesz na przykład webpodpakiet, aby usługa internetowa wslub restpakiet przechowywał tylko to. Zasadniczo łączy się z rdzeniem.

x.y.z.area1.web
x.y.z.area1.ws
x.y.z.area2.rest

Teraz możesz rozważyć ponowne użycie obiektów z twojego rdzenia na inne warstwy, ale IMHO lepiej jest użyć określonej domeny dla tej warstwy. Podobnie jak w przypadku mapowania Object to SQL istnieje (często) niedopasowanie tego, co chcemy pokazać na ekranie lub użyć jako XML w usłudze sieciowej oraz w jaki sposób implementowana jest logika biznesowa. W zależności od złożoności domeny biznesowej i internetowej można je uznać za oddzielne domeny problemowe do rozwiązania, które wymagają połączenia, w zasadzie 2 różne konteksty ograniczone .

Aby użyć wyceny z zasobu CQRS

Nie można stworzyć optymalnego rozwiązania do wyszukiwania, raportowania i przetwarzania transakcji przy użyciu jednego modelu.

Nie próbuj umieszczać wszystkiego w jednym modelu (domena), oddziel obowiązki. Prawdopodobnie uzyskasz więcej (mniejszych) klas, ale czystsze oddzielenie warstw aplikacji.

Ostatnia uwaga

Pamiętaj, że tworzenie architektury decyduje o kompromisach między jednym rozwiązaniem a drugim. Zależy to w dużej mierze od złożoności domeny i powinno wynikać głównie z wymagań funkcjonalnych aplikacji. Wpływają na to jednak ograniczenia niefunkcjonalne (wydajność, bezpieczeństwo) i środowiskowe (język, platforma, doświadczenie). Architektura, podobnie jak kodowanie, nigdy się nie kończy, każde nowe wymaganie może (a może powinno?) Doprowadzić do przeprojektowania aplikacji.

Zrzeczenie się

Tak, starałem się również umieścić wszystko w jednym modelu i tak, próbowałem również zastosować separację techniczną w swoich aplikacjach. Jednak po kilku latach doświadczenia w tworzeniu splątanych warstw aplikacji (początkowo wydaje się to dobrym pomysłem, potem aplikacja zaczyna się rozwijać ...) pomyślałem, że musi być inny sposób.

Spinki do mankietów

  1. Czysta architektura, wujek Bob Martin
  2. Architektura heksagonalna (alias Ports and Adapters), Alistair Cockburn
  3. Ups, gdzie poszła moja architektura, Oliver Gierke
  4. Zasady OOD, wujek Bob Martin
  5. Błędy przy stosowaniu DDD, Udi Dahan
  6. Ograniczone konteksty, Martin Fowler
  7. Styl kodowania widoczny w architekturze, Simon Brown

Książki

  1. Rosnące oprogramowanie obiektowe oparte na testach
  2. Architektura aplikacji Java: wzorce modułowości z przykładami wykorzystującymi OSGi (Robert C. Martin Series)
  3. Projektowanie oparte na domenach: radzenie sobie ze złożonością w sercu oprogramowania
  4. Architektura oprogramowania dla programistów
  5. Wdrażanie projektowania opartego na domenach
M. Deinum
źródło
1
Dobra
1
Dobry, dodał jeszcze kilka do mojej oryginalnej odpowiedzi.
1
To zdecydowanie najlepsza książka o designie, którą przeczytałem;) Możesz wspomnieć o książce Vaughna Vernona, bardzo dobra również: amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/…
Mik378
@ M.Deinum +1 Świetny w celach informacyjnych!
1
@ Mik378 Mam obie książki w mojej cyfrowej bibliotece wśród wielu innych.