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.service
a 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
- Rzeczy, które zmieniają się razem, są pakowane razem
- 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 web
podpakiet, aby usługa internetowa ws
lub rest
pakiet 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
- Czysta architektura, wujek Bob Martin
- Architektura heksagonalna (alias Ports and Adapters), Alistair Cockburn
- Ups, gdzie poszła moja architektura, Oliver Gierke
- Zasady OOD, wujek Bob Martin
- Błędy przy stosowaniu DDD, Udi Dahan
- Ograniczone konteksty, Martin Fowler
- Styl kodowania widoczny w architekturze, Simon Brown
Książki
- Rosnące oprogramowanie obiektowe oparte na testach
- Architektura aplikacji Java: wzorce modułowości z przykładami wykorzystującymi OSGi (Robert C. Martin Series)
- Projektowanie oparte na domenach: radzenie sobie ze złożonością w sercu oprogramowania
- Architektura oprogramowania dla programistów
- Wdrażanie projektowania opartego na domenach