Logika biznesowa w Springu, adnotacja @Service

0

Mam kilka pytań odnośnie warstwy biznesowej w springu. Tutoriale dostępne w internecie to zazwyczaj najprostsze CRUD-y i trudno znaleźć tam odpowiedzi.
Czy ta warstwa zawsze jest "pośrednikiem" między kontrolerami a repozytorium?
Czy jak mam klasę która jest odpowiedzialna stricte za jakieś obliczenia to też mam ją oznaczać jako @Service?
Czy te serwisy mogą od siebie wzajemnie zależeć i jeśli tak to jak wystawia się "interfejs" między taką warstwą a kontrolerami? Zakładam, że nie wszystkie te klasy powinny być dostępne.

2

Poza drobnymi różnicami, wszelkie te adnotacje są pochodnymi @Component, co oznacza tylko tyle że tak oznaczone klasy będą wrzucone do kontenera DI i będzie je można wstrzyknąć do innych klas. Problem z tymi wszystkimi tutorialami jest jeszcze jeden - wszystkie narzucają nie do końca najlepszą architekturę, czyli właśnie podział na repository/service/controller.
Co do Twoich pytań:
-to zależy, jeżeli mowa o prostych query jak find, findAll, IMO nie zawsze ma sens bawienie się w robienie sztucznej warstwy serwisów pomiędzy. Jeżeli jednak jakaś logika występuje po drodze, to warto zrobić warstwę pośrednią

-jak wspomniałem wyżej, zależy czy będziesz ją wstrzykiwać do innych serwisów, tworzyć przez new, czy w ogóle zrobisz statyczne utlity methods. W pierwszym przypadku musisz ją jakoś oznaczyć. @Service wskazuje że to klasa która wykonuje jakąś logikę biznesową, więc obliczenia jak najbardziej pod to podchodzą.

-oczywiście, że mogą od siebie zależeć, w każdym bardziej rozbudowanym CRUDzie to występuje. Fajnym przykładem interfejsu między infrastrukturą (controller), a domeną (serwisy z logiką biznesową) jest fasada i podejście hexagonalne, polecam przesłuchać na YT - Modularity and hexagonal architecture in real life, warto też poczytać o Clean Architecture. Bardzo fajnie tłumaczy i rozjaśnia jak można budować aplikacje webowe, nieco inaczej niż w 99% tutoriali ;)

2
Schaft napisał(a):

Czy ta warstwa zawsze jest "pośrednikiem" między kontrolerami a repozytorium?

Niestety nie rozumiem pytania. Co masz na myśli przez "pośrednik"?
W Service powinno być to co nie zależy od konkretnej bazy danych (bo to jest w Repozytorium) oraz to co nie zależy od konkretnej implementacji widoku i obsługi widoku (bo to jest w kontrolerze). Czasem może to być coś więcej niż sama goła logika biznesowa

Schaft napisał(a):

Czy jak mam klasę która jest odpowiedzialna stricte za jakieś obliczenia to też mam ją oznaczać jako @Service?

Jeśli jest to bezstanowy obiekt który ma być zarządzany przez springa to tak

Schaft napisał(a):

Czy te serwisy mogą od siebie wzajemnie zależeć i jeśli tak to jak wystawia się "interfejs" między taką warstwą a kontrolerami? Zakładam, że nie wszystkie te klasy powinny być dostępne.

Np za pomocą wzorca fasada

0
Kamil Żabiński napisał(a):
Schaft napisał(a):

Czy ta warstwa zawsze jest "pośrednikiem" między kontrolerami a repozytorium?

Niestety nie rozumiem pytania. Co masz na myśli przez "pośrednik"?
W Service powinno być to co nie zależy od konkretnej bazy danych (bo to jest w Repozytorium) oraz to co nie zależy od konkretnej implementacji widoku i obsługi widoku (bo to jest w kontrolerze). Czasem może to być coś więcej niż sama goła logika biznesowa

Schaft napisał(a):

Czy jak mam klasę która jest odpowiedzialna stricte za jakieś obliczenia to też mam ją oznaczać jako @Service?

Jeśli jest to bezstanowy obiekt który ma być zarządzany przez springa to tak

Schaft napisał(a):

Czy te serwisy mogą od siebie wzajemnie zależeć i jeśli tak to jak wystawia się "interfejs" między taką warstwą a kontrolerami? Zakładam, że nie wszystkie te klasy powinny być dostępne.

Np za pomocą wzorca fasada

bezstanowy, co dokładnie znaczy to w tym kontekście? Po czym poznać, że obiekt serwisu powinien byc zarządzane przez Springa, a kiedy nie?
Przez "pośrednika" chodziło mi o to czy jak do jakichś obliczeń nie potrzebuje odwoływać sie do bazy danych to czy mogę w tym kontekście nazwać to warstwą biznesową i oznaczyć poprzez @Service

1

Po czym poznać, że obiekt serwisu powinien byc zarządzane przez Springa, a kiedy nie?

Tutaj nie ma jakiegoś panaceum, są różne szkoły. Jedni powiedzą ze cała logika ma lecieć w bezstanowych serwisach, inni że wręcz przeciwnie, wszystko powinno opierać się o obiekty domenowe, a serwisy powinny co najwyzej to spinać infrastrukturalnie. Ile osób tyle opinii.

0

Ostatnio w swoim projekcie też miałem ten problem. W serwisie miałem pewne obliczenia, więc jest to logika biznesowa, a ta powinna być niezależna od frameworka, więc taki serwis nie powinien mieć adnotacji @Service. Problem pojawia się, kiedy w danym serwisie chcemy odwołać się do innego serwisu. Z @Service w springu możemy sobie wtedy wstrzyknąć to łatwo przez konstruktor, ale bez tej adnotacji? Pisać sobie jakąś klasę ApplicationServices, która będzie trzymać utowrzone obiekty serwisów i to wstrzykiwać w każdy serwis? Niby działa, ale trochę wynajdowanie koła na nowo i dodatkowa robota przy dodawaniu każdego nowego serwisu...

0

Nie ma czegos takiego jak "bezstanowy obiekt".
To jakas enterprajsowa hybryda serwisow i obiektow (np domenowych).

0
Shalom napisał(a):

Po czym poznać, że obiekt serwisu powinien byc zarządzane przez Springa, a kiedy nie?

Tutaj nie ma jakiegoś panaceum, są różne szkoły. Jedni powiedzą ze cała logika ma lecieć w bezstanowych serwisach, inni że wręcz przeciwnie, wszystko powinno opierać się o obiekty domenowe, a serwisy powinny co najwyzej to spinać infrastrukturalnie. Ile osób tyle opinii.

Co oznacza bezstanowy serwis? Obiekt domenowy to obiekt wyciągnięty z bazy danych (obiekt powstały na bazie klasy oznaczonej @Entity)?

1

Obiekt bezstanowy to instancja klasy Void

2

Co oznacza bezstanowy serwis?

Oznacza coś co operuje na podanych danych, bez utrzymywania żadnego wewnętrznego "stanu" związanego z wykonywanymi zadaniami. Zwykle jest bezpieczne wielowątkowo i idempotentne.

Obiekt domenowy to obiekt wyciągnięty z bazy danych (obiekt powstały na bazie klasy oznaczonej @Entity)?

Nie. Obiekty @Entity to zwykle DTO/struktury danych. Obiekt domenowy jest związany z logiką biznesową aplikacji. Logika aplikacji jest zawarta w takich obiektach i wszelkie operacje są modelowane jako interakcje między takimi obiektami.

1

Musisz wyjść z mindsetu architektury 3-warstwowej premiującej anemiczny model danych. Tak naprawdę cała logika aplikacji powinna być w serwisach (a więc to nie są tylko przelotki), a najlepiej w encjach (bogatych, nie tych @Entity). Poczytaj o Clean architecture, DDD taktycznym oraz architekturze portów i adapterów.

0

Mógłby ktoś podesłać przykład jakiegoś projektu, który miałby bardziej zaawansowaną warstwe logiki i wykorzystywał encje domenowe? Znalazłem kilka na githubie, ale w nich logika jest zaimplementowana w klasach @Entity, a wydaje mi się, że nie jest to za bardzo poprawne

1

@systemy: co to wnosi do dyskusji? Podesłałeś jakieś tutoriale do Hibernate/JPA i Spring Boot, kiedy wątek dotyczy pisania logiki biznesowej w bogstych encjach domenowych niezależnie od technologii.

1 użytkowników online, w tym zalogowanych: 0, gości: 1