Api model na interfejsach

PM
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:30
0

Cześć,

czy spotkaliście z designem w którym objekty modelu api są zdefiniowane przez interfejsy ?

Mamy w projekcie libkę która jest wrapperem api do zewnętrznego serwisu. Objekty rq i rs zą zdefiniowne przez interfejsy :

np.

Kopiuj
interface Request{

	Long id();
	String phoneNumber();
	String name()
	String address();
}

Nie ma tu żadnego zachowania, tylko definicja pól.

Architekt bardzo broni tego rozwiązania bo niby jest prosty model i rozszerzalny itp.. ale brak konkretów

Ja widzę tylko wady, jak

  • brak możliwości łatwej serializacji (użycia objecMapper), nie działa to na interfejsach, przez co potrzebna jest dodatkowa logika mapująca objekty api.
  • implementacja objektów(rs, rq) po stronie wygląda dziwnie, ponieważ trzeba zaimplementować odpowiednie metody zamiast przekazać argumenty przez konstruktor.

Co sądzicie ?
Czy to ma sens ?

Maciej

AX
  • Rejestracja:ponad rok
  • Ostatnio:9 miesięcy
  • Postów:12
1

Do tej pory nie spotkałem się by ktoś tak robił. Jest to zaburzenie pewnej konwencji w imię dodatkowych narzędzi. Równie dobrze można pisać ciągiem kod bez metod albo wszystko robić public bo jest szybciej. Pytanie jak bardzo doświadczony jest architekt i czy ma dobre uzasadnienie do tego pomysłu. Jeżeli w Waszym przypadku działa to świetnie to narzędzie jest dla programisty, a nie programista dla narzędzia. Natomiast jeżeli jest to bardziej zachcianka to za jakiś czas będzie kolejna i kolejna i kod będzie cięższy do utrzymania. Z praktyki; czasem nadmiernie dodawało się kontruktory z uwagi na poszczególne DI, testy albo serializację bo inaczej nie szło ruszyć małym nakladem czasu.Takie interfejsy z polami to taka klasa abstrakcyjna, tylko że interfejsy można dziedziczyć w nieskonczoność, a klasę abstrakcyjną raz. Może warto poczytać "Przyczyny dziedziczenia klasy abstrakcyjnej tylko raz", może tam będzie coś co da Ci do myślenia. Mówię to w kontekście C#, w każdym języku jest trochę inaczej.

dalbajob
  • Rejestracja:prawie 2 lata
  • Ostatnio:5 miesięcy
  • Postów:149
3

Dziwnie to wygląda. Do takich rzeczy IMO tylko data classy / rekordy - bo to jest paczka danych, a nie jakiś zestaw metod

YA
  • Rejestracja:około 10 lat
  • Ostatnio:około 12 godzin
  • Postów:2372
1

Co jeśli w interfejsie pojawi się nowa metoda String gender(), która będzie miała jakąś domyślna implementację, a Ty nie jesteś zainteresowany tematyką gender() ? Wywali Ci to Twoją implementację? Co by było w przypadku, gdyby to była data class z konstruktorem, który oczekuje gender? Dopytałbym jednak architekta, czy zastosowanie buildera dla Request/Response nie rozwiązuje problemu i jaką dynamikę zmian przewiduje dla tych interfejsów. Być może wilk byłby syty i owca cała.

mustang_ex
  • Rejestracja:ponad rok
  • Ostatnio:16 dni
  • Postów:98
0

@p_maciek oczywiście że się spotkałem. Taka struktura jak ta co ją przedstawiłeś ma same zalety:

  • jest banalna w utrzymaniu.
  • jest skalowalna do w zasadzie dowolnej wielkości
  • jest banalna w optymalizacji
  • daje w zasadzie nieograniczone możliwości ekspansi poziomej jak i pionowej
  • można ją dowolnie dziedziczyć.

Jest spora grupa osób uparcie twierdząca że owa struktura nie ma zalet, natomiast ma cały szereg wad i oni tej struktury nie zastosują. Prawda jest jednak taka iż owa struktura jest coraz częściej wykorzystywana przez dużych graczy z powodzeniem.

edytowany 1x, ostatnio: mustang_ex
KL
  • Rejestracja:około rok
  • Ostatnio:około 9 godzin
  • Postów:491
2
mustang_ex napisał(a):

@p_maciek oczywiście że się spotkałem. Taka struktura jak ta co ją przedstawiłeś ma same zalety:

  • jest banalna w utrzymaniu.

Nie bardziej niz taka sama struktura zaimplementowana jako rekord.

  • jest skalowalna do w zasadzie dowolnej wielkości

Nie bardziej niz taka sama struktura zaimplementowana jako rekord.

  • jest banalna w optymalizacji

Nie bardziej niz taka sama struktura zaimplementowana jako rekord.

  • daje w zasadzie nieograniczone możliwości ekspansi poziomej jak i pionowej

Nie bardziej niz taka sama struktura zaimplementowana jako rekord.

  • można ją dowolnie dziedziczyć.

Nie bardziej niz taka sama struktura zaimplementowana jako rekord.

Jest spora grupa osób uparcie twierdząca że owa struktura nie ma zalet, natomiast ma cały szereg wad i oni tej struktury nie zastosują. Prawda jest jednak taka iż owa struktura jest coraz częściej wykorzystywana przez dużych graczy z powodzeniem.

To podasz jakies te zalety wzgledem zwyklego rekordu?

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 10 godzin
  • Postów:10094
1

Na podstawie tego co powiedziałeś to w zasadzie ciężko stwierdzić czy to dobrze czy nie dobrze. Musiałbyś opisać więcej rzeczy.

Sam pomysł żeby interfejsem na jakieś API były po prostu interfejsy abstrakcyjne ma szanse działać, jeśli się to dobrze zrobi.

yarel napisał(a):

Co jeśli w interfejsie pojawi się nowa metoda String gender(), która będzie miała jakąś domyślna implementację, a Ty nie jesteś zainteresowany tematyką gender() ? Wywali Ci to Twoją implementację? Co by było w przypadku, gdyby to była data class z konstruktorem, który oczekuje gender? Dopytałbym jednak architekta, czy zastosowanie buildera dla Request/Response nie rozwiązuje problemu i jaką dynamikę zmian przewiduje dla tych interfejsów. Być może wilk byłby syty i owca cała.

Ale te interfejsy za pewne nie byłyby implementowane przez autora. To miałby być tylko interfejs wejściowy, jak rozumiem.

Jak konsumujesz taki input, to w zasadzie co za różnica czy wołasz Response record; record.name czy Response interfejs; interfejs.name().

Natomiast jak mówimy o tym że to ma być wyjściowy interfejs, to problem jest w zasadzie ten sam co z recordem. Jeśli twórca interfejsu wejściowego chce dodać nowe pole (nie ważne czy pole w recordzie czy metodę w interfejsie), to tak czy tak tą daną trzeba dodać (Albo jako pole, albo jako metodę). Chyba że twórca chciałby robić jakieś "tricki" (nie warto) z domyślnymi wartościami, np. domyślne pole w recordzie, albo domyślna metoda w interfejsie, ale to jest słabe.

Więc moim zdaniem na to samo wychodzi.

edytowany 4x, ostatnio: Riddle
PM
  • Rejestracja:prawie 8 lat
  • Ostatnio:8 miesięcy
  • Postów:30
0

Dzieki za odpowiedzi. Mieliśmy w zespole deyskusje o tym. Ogólnie ktoś kiedyś zastosował taki design i próbowałem się dowiedzieć z czego to wynika ale nie dowiedziałem się niż poza tym że to jest api i taki design jest super prosty bo nie zawiera zbędnych rzeczy jak implementacje getterow, setterow. Cała implementacja jest przerzucona na klientów.
W przypadku naszego projektu ja zauważyłem tylko problemy jakie z tego wynikają np. brak możliwości łatwej serializacj/deserializacji czy zapiecia walidacji na polach api. Argument prostoty nie wg mnie nie wnosi nic istotnego.

Natomiast ciekawą rzecz poruszył @mustang_ex o skalowalności. Zaintrygowalo mnie to. Mozesz rozszerzyć co masz na myśli? Czy chodzi o to, że na tym samym api interfejsowym można np. oprzeć implementacje różnych model?. Np. dla protokolu REST z odnotacjami restowymi. To miałoby chyba sens...

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 10 godzin
  • Postów:10094
1
p_maciek napisał(a):.

W przypadku naszego projektu ja zauważyłem tylko problemy jakie z tego wynikają np. brak możliwości łatwej serializacj/deserializacji czy zapiecia walidacji na polach api.

Moim zdaniem to nie jest wada.

Jeśli api ma wspierać serializację, to powinno być to należycie przemyślane i zaprojektowanie.

Jak mówisz *skorzystamy z recordów, bo będzie się to dało łatwo serializować", to wtedy taka cecha doszła by praktycznie przypadkiem. Pewnie nie byłaby przetestowana odpowiednio, etc.

Miang
  • Rejestracja:około 7 lat
  • Ostatnio:3 minuty
  • Postów:1684
1
p_maciek napisał(a):

Cześć,

czy spotkaliście z designem w którym objekty modelu api są zdefiniowane przez interfejsy ?

masz Interfejs (zastanów się co to znaczy rozwinięcie skrótu API) zadeklarowany interfejsami

Mamy w projekcie libkę która jest wrapperem api do zewnętrznego serwisu. Objekty rq i rs zą zdefiniowne przez interfejsy :

  • brak możliwości łatwej serializacji (użycia objecMapper), nie działa to na interfejsach, przez co potrzebna jest dodatkowa logika mapująca objekty api.

ten zewnętrzny serwis byś serializował?

a spotkać się można w interfejsach do windowsowych dllek na przykład


dzisiaj programiści uwielbiają przepisywać kod z jednego języka do drugiego, tylko po to by z projektem nadal stać w miejscu ale na nowej technologii
edytowany 1x, ostatnio: Miang
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 18 godzin
  • Lokalizacja:Wrocław
0
Riddle napisał(a):

Jak mówisz *skorzystamy z recordów, bo będzie się to dało łatwo serializować", to wtedy taka cecha doszła by praktycznie przypadkiem. Pewnie nie byłaby przetestowana odpowiednio, etc.

Co jest przypadkowego w używaniu znanych bibliotek do serializacji danych?

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 10 godzin
  • Postów:10094
0
somekind napisał(a):
Riddle napisał(a):

Jak mówisz *skorzystamy z recordów, bo będzie się to dało łatwo serializować", to wtedy taka cecha doszła by praktycznie przypadkiem. Pewnie nie byłaby przetestowana odpowiednio, etc.

Co jest przypadkowego w używaniu znanych bibliotek do serializacji danych?

Jeśli coś ma być serializowane, to lepiej żeby to było widać explicitly, np. żeby był test pod to.

Jeśli nie, to ktoś mógłby chcieć kiedyś zrefaktorować record na klasę i ups, zepsuł serializacje.

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 18 godzin
  • Lokalizacja:Wrocław
0
Riddle napisał(a):

Jeśli coś ma być serializowane, to lepiej żeby to było widać explicitly, np. żeby był test pod to.

Ale to jest oczywiste, że kontrakt API jest serializowany, bo inaczej się danych do API przesłać nie da.

Jeśli nie, to ktoś mógłby chcieć kiedyś zrefaktorować record na klasę i ups, zepsuł serializacje.

Rekord to jest klasa, po prostu kompilator w locie dodaje jej kilka metod.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 10 godzin
  • Postów:10094
0
somekind napisał(a):
Riddle napisał(a):

Jeśli coś ma być serializowane, to lepiej żeby to było widać explicitly, np. żeby był test pod to.

Ale to jest oczywiste, że kontrakt API jest serializowany, bo inaczej się danych do API przesłać nie da.

No to skoro tak, to post do którego się odnosiła moja odpowiedź (na którą z kolei Ty odpowiedziałeś) nie ma sensu (ten: #1960094)

edytowany 1x, ostatnio: Riddle

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.