Wstrzykiwanie zależności z serwisów do bibliotek - czy to dobra praktyka?

0

Cześć,
mam taki problem. Jest kilka serwisów, które dzielą wspólną bibliotekę. Wygląda to tak, że współdzielona biblioteka common-lib jest dodana jako dependency do danej aplikacji/serwisu, który po prostu ma ją na liście swoich dependencji np. w pom.xml. Serwis wykorzystuje DI ze springa. Dajmy na to ten serwis nazywa się MyService
I teraz w MyService mamy klasę dajmy na to zaimplementowany serwis
@Service

public class SomeService extends AbstractSomeService {

      public SomeService(ServiceFromCommonLibrary serviceFromCommonLibrary){
        super(serviceFromCommonLibrary)
      }

      public void someLogic(){
          logic()
      }
}

A w bibliotece mamy klasę abstrakcyjną, oraz klasę ServiceFromCommonLibrary.
@Slf4J

public abstract class AbstractSomeService{

      private ServiceFromCommonLibrary serviceFromCommonLibrary

      public SomeService(ServiceFromCommonLibrary serviceFromCommonLibrary){
        this.serviceFromCommonLibrary = serviceFromCommonLibrary;
      }

      public logic(){
        log("Some repeated log");
        this.serviceFromCommonLibrary.whaterver();
      }

}

Małe wyjąsnienie dlaczego tak to wygląda. Na poziomie biblioteki common-lib nie ma włączonego autoscanowania zależności, brak "standardowej" klasy Application z metodą main. Więc tam wstrzykiwania zależności nie ma. Natomiast na poziomie serwisu już oczywiście wszystkie funkcjonalności springa są dostępne. To co tu się dzieje to po prostu tworzona jest insancja serwisu ServiceFromCommonLibrary na poziomie serwisu MyService. Następnie ta utworzona instancja jest przekazana do współdzielonej biblioteki common-lib.

Takie coś działa. Jednak chciałbym zapytać, czy to rozwiązanie to jest dobra praktyka czy może anty-wzorzec? Ja osobiście bardzo chciałbym się tego pozbyć z kodu. Moim zdaniem chyba lepiej duplikować jest tą logikę z metody logic, niż tworzyć instancje serwisów na poziomie aplikacji, które następnie są niejako forwardowane do biblioteki i tam używane.

Będę wdzięczny za odpowiedź na to pytanie, najlpiej podpartą jakimiś linkami. Próbowałem znaleźć posty na temat tego problemu ale bezskutecznie. Jeśli się powtórzyłem i to już jest na forum to przeprasza.

Pozdrawiam

2

Czyli takie trochę template method po prostu? Dla mnie dziwnym jest tutaj głównie to że macie jakiś domenowy serwis który siedzi w jakimś commons. Dla mnie to jest sygnał ze może dzieje sie tu coś dziwnego i to powinien być osobny mikroserwis.

1

Generalnie rozbudowane dziedziczenie zawsze prędzej czy później generuje problemy coupling itd. dlatego lepiej iść w stronę kompozycji by default.

0

@Shalom: Tak no wiem, że raczej w micro serwisach raczej się nawet duplikuje kod niż tworzy jakieś wspólne biblioteki. Tutaj jednak bardziej mi chodzi nie o samą klasę abstrakcyjną czy wydzieloną bibliotekę. Chcę się upewnić, czy injectowanie serwisu na poziomie jednej aplikacji i przekazywanie instancji tego serwisu do drugiej aplikacji to czasami nie jest anty-wzorzec?

1
tdk1982 napisał(a):

@Shalom: Tak no wiem, że raczej w micro serwisach raczej się nawet duplikuje kod niż tworzy jakieś wspólne biblioteki. Tutaj jednak bardziej mi chodzi nie o samą klasę abstrakcyjną czy wydzieloną bibliotekę. Chcę się upewnić, czy injectowanie serwisu na poziomie jednej aplikacji i przekazywanie instancji tego serwisu do drugiej aplikacji to czasami nie jest anty-wzorzec?

Przekazywanie serwisu wydaje się dziwne ... po to się serwisy robi, aby była pewna dynamika (teraz ten, za chwile inny równoważny, z innego noda), a co wazniejsze serwis ma nie mieć (widocznego) stanu, więc dlaczego go przekazywać? *) Niech kod kliencki sam sobie uzyska (dostanie wstrzyknięte, obojętne)

*) inaczej mówiąc, martwię sie o Towj serwis.

2

Nie widzę tam nic jakiegoś bardzo dziwnego. Weźmy np. taki przykład:

  1. Mamy mikroserwis który komunikuje się z innymi, więc bierze sobie jakieś zależności some-service-client.jar, other-service-client.jar itd.
  2. Dla wszystkich tych klientów mamy jakąś wpólną "bazę", bo robimy tam jakieś template method i część logiki przychodzi "z zewnątrz". Załóżmy prostą sytuację np. ze każdy taki klient oczekuje że dostanie jako zależność jakiś "logger". Typ loggera definiuje ktoś kto "używa" danego klienta (np. może po prostu normalnie pisać do pliku/na konsole, ale może też pisać gdzieś do jakiejs bazy danych informacje o wszystkich requestach które są wysyłane)
  3. W naszym mikroserwisie mamy jakis SomeMicroserviceAdapter który wrapuje bibliotekę some-service-client, tworzy obiekt SomeServiceClient i wrzuca mu odpowiedni logger.

Na oko masz właśnie taką strukturę i jak dla mnie to jest zupełnie ok.

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