Referencja do metody w klasie generycznej.

Referencja do metody w klasie generycznej.
Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

Witam,
Szukam pomocy, gdyż mam problem z przerobieniem klasy na generyczną, a dokładniej referencją do niej metody.
Jako dodatek, ale nie jest to dla mnie wymagane fajnie by było, gdyby była możliwość przypisania referencji do metody na podstawie klasy, czyli :
Podajemy jako parametr klasa1 i jest tutaj np refleksja(tak to się chyba nazywa) MetodaKlasa1Metoda.
Chyba, że całkowicie inaczej powinienem to zrobić, bo się inaczej do tego zabieram.

Poniżej kod, jak to wygląda, a problem leży w implementacji generyka w klasie GetQueryUserDetailService

Kopiuj
public abstract class GetQueryAbstractService<B, R> {

    @PersistenceContext
    protected EntityManager entityManager;

    protected abstract Class<B> getClazz();

    protected abstract Predicate getPredicate(Predicate predicate, CriteriaBuilder builder, Root r, List<SearchCriteria> params);

    protected abstract List<R> getDtos(CriteriaQuery<B> query);

    public List<R> execute(String search) {
        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<B> query = builder.createQuery(getClazz());
        final Root r = query.from(getClazz());

        List<SearchCriteria> params = new ArrayList<>();
        if (search != null) {
            Pattern pattern = Pattern.compile("(\\w+?)(:|<|>)(\\w+?),");
            Matcher matcher = pattern.matcher(search + ",");
            while (matcher.find()) {
                params.add(new SearchCriteria(matcher.group(1), matcher.group(2), matcher.group(3)));
            }
        }

        Predicate predicate = builder.conjunction();
        predicate = getPredicate(predicate, builder, r, params);
        query.where(predicate);

        return getDtos(query);
    }
}
Kopiuj
@Service
public class GetQueryUserDetailService extends GetQueryAbstractService<UserDetail, UserDetail.UserDetailDto> {

    @Override
    protected Class<UserDetail> getClazz() {
        return UserDetail.class;
    }

    @Override
    protected Predicate getPredicate(Predicate predicate, CriteriaBuilder builder, Root r, List<SearchCriteria> params) {
        UserSearchQueryCriteriaConsumer searchConsumer = new UserSearchQueryCriteriaConsumer(predicate, builder, r);
        params.forEach(searchConsumer);
        return searchConsumer.getPredicate();
    }

    @Override
    protected List<UserDetail.UserDetailDto> getDtos(CriteriaQuery<UserDetail> query) {
        return entityManager
                .createQuery(query)
                .getResultStream()
                .map(UserDetail::toUserDetailDto)
                .collect(Collectors.toList());
    }
}

Mam problem z : map(UserDetail::toUserDetailDto) , chyba że to nie działa, bo źle podaję genęryki.
Oczywiście, żeby kod był sprawny, to nie implementowałem powyżej wartości generycznych, żeby nie zrobić burdelu w kodzie.

Za pomoc/ wskazówki z góry dziękuje.

edytowany 1x, ostatnio: Nowak Adam
Nowak Adam
Dokładnie chodzi mi o przerobienie klasy GetQueryUserDetailService , żeby przyjmowała klasę generyczną np T Oraz, żebym mógł sobie na spokojnie przemapowować,czyli np : .map(T::toKlasaMap) lub o ile jest możliwe map(T::R)
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

Tak linijka będzie działa, pod warunkiem że w UserDetail masz funkcje:

Kopiuj
public class UserDetail {
    public UserDetailDto toUserDetailDto() {

albo jeśli jest statyczna

Kopiuj
public class UserDetail {
    public static UserDetailDto toUserDetailDto(UserDetail ) {

Jeśli nie, to nie będzie działać. Najlepiej pokaż kod UserDetail.

QuantumComp
QuantumComp
  • Rejestracja:ponad 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:40
0

Nie wiem czy to nie moja godzina, czy inny powód, ale za nic nie potrafię zrozumieć tego co napisałeś 😶

Nowak Adam
postarałem się opisać bardziej, nie mogłem edytować, to dodałem komentarz
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

@QuantumComp:

TomRiddle napisał(a):

Najlepiej pokaż kod UserDetail.

Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

Kurde, może faktycznie mogłem to napisać po rusku ,postaram się to inaczej opisać.

@TomRiddle ten kod działa, wraz z mapowaniem, tylko ja chcę to przerobić na klasę generyczną, czyli w tym przypadku by było:
.map(T::R)

@QuantumComp up

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

@Nowak Adam: aaa. tak się nie da.

Nowak Adam
to tłumaczy czemu nie działało xd
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
1

Musisz albo wydzielić interfejs, albo przekazać Function<R,U> jako parametr.

Nowak Adam
Byłbyś w stanie napisać jakiś pseudo kod, czy coś, bo nie wiem, czy rozumiem. Mam po prostu stworzyć osobną klasę generyczną, której zadanie będzie tylko przekazanie R,U jako parametr? A wtedy tamtą funkcją przerobić, żeby przyjmowała od niej ten parametr ?
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
1
Nowak Adam napisał(a):

Byłbyś w stanie napisać jakiś pseudo kod, czy coś, bo nie wiem, czy rozumiem. Mam po prostu stworzyć osobną klasę generyczną, której zadanie będzie tylko przekazanie R,U jako parametr? A wtedy tamtą funkcją przerobić, żeby przyjmowała od niej ten parametr ?

Tak na prawdę to zależy od tego co chcesz zrobić. Czy te parametry które chcesz przekazać tymi generykami mają zawsze tą samą metodę? Np wszystkie mają mapToDto()? Czy mają różne? np mapToDto, mapToCount(), mapToTable(), mapToView(), etc.

Nowak Adam
Właśnie wszędzie jest ta sam schemat czyli np : Klasa1 a tam toKlasa1Dto Klasa2 a tam toKlasa2Dto etc
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
3
Nowak Adam napisał(a):

Właśnie wszędzie jest ta sam schemat czyli np : Klasa1 a tam toKlasa1Dto Klasa2 a tam toKlasa2Dto etc

No to masz dwie opcje.

Albo zrobić nowy interfejs generyczny (interface Klasa<R> { R map() }) , że każda z Twoich klas Klasa1, Klasa2 go będzie implementowała (tzn Klasa1 implements Klasa, Klasa2 implements Klasa, etc.)

Albo, możesz przekazać parametr do swojej klasy abstrakcyjnej.

Nowak Adam
dzięki, jutro na spokojnie nad tym przysiadne.
99xmarcin
  • Rejestracja:około 5 lat
  • Ostatnio:5 miesięcy
  • Postów:2420
1

Można też trochę inaczej podejść do tego co napisał @TomRiddle, czyli zrobić sobie interfejs Mapper<FROM,TO> z metodą TO map(FROM obj) i taki interfejs przekazywać jako dodatkowy parametr do GetQueryAbstractService. Jeżeli być skorzystał z jakiejś biblioteki do mapowania opartej o refleksje (nie powiem że to polecam) to dało by radę obejść się i bez tego parametru.

Alternatywnie możesz dołożyć extra metodę abstrakcyjną która wykona wspomniane tutaj mapowanie typu:

Kopiuj
abstract DTO map(ENTITY entityt);

Dla masochistów: da radę to również zrobić refleksją, gdzie na podstawie klasy encji i docelowego DTO budujesz interfejs Function<A,R> - ale będzie to wolne i podatne na błędy.

PS. Pattern warto skompilować raz na poziomie klasy. O ile dobrze pamiętam skompilowane Patterny są thread-safe...


Holy sh*t, with every month serenityos.org gets better & better...
ĆK
użycie refleksji to -2 bez refleksji :)
ĆK
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:59
0
Kopiuj
public class User extends BaseEntity {

	@Override
	public UserDto toDto() {
		System.out.println(this);
		return new UserDto() {};
	}
}

public abstract class BaseService<E extends BaseEntity> {

	public BaseDto toDto(E entity) {
		return Stream.of(entity).map(BaseEntity::toDto).findFirst().get();
	}
}

dao.User@3af49f1c

Nowak Adam
Nie w tym tkwi problem :/ W wcześniejszych komentarzach starałem się to bardziej sprecyzować
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

@ćk: Burn it with fire. Po co dziedziczenie?

99xmarcin
Gorzej, encja ma referencje do DTO czyli na wspak... :scream:
ĆK
BaseEntity? Może być interfejsem. Czy nie rozumiem?
ĆK
Zobacz UserDetail z pierwszego posta. Tak, chciał :) .map(UserDetail::toUserDetailDto)
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 8 godzin
  • Postów:1875
0

Co Ci w ogóle daje wprowadzenie takiej hierarchii klas? Jakiś własny framework piszesz?

Been there, done that. Kiedyś też robiłem coś podobnego i szczerze odradzam ten kierunek :) Zamiast tworzyć normalny soft zespół będzie rozwiązywał puzzle z generykami.


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
Zobacz pozostałe 2 komentarze
Nowak Adam
@Charles_Ray: Nie Framework, ale chcę ugryźć w przejrzysty sposób wyciąganie danych poprzez GET z encji.
Charles_Ray
Nic z tego nie rozumiem :) pole z encji wyciąga się poprzez encja.getNazwaPola();
Nowak Adam
@Charles_Ray: no tak, ale w tej encji mam statyczną klasę, w której mam DTO wspomnianej encji.
Charles_Ray
Ale to już na poziomie idei jest zle, co wskazali poprzednicy. Przecież DTO może zawierać pola spoza tej jednej encji
Nowak Adam
No tak, u mnie zawiera, ale są to głównie rzeczy powiązane relacjami, hmm chyba napiszę od nowa ten post. Bo kiepski ze mnie tłumacz
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Generalnie takie generyki moga mieć sens conajwyżej w CRUDach do todo-list :P W prawdziwym programowaniu tego typu rzeczy nie mają racji bytu. Jeśli już niestety masz JPA to wywołuj EntityManager w danym DAO albo użyj Spring Data JPA. Takie generyczne rozwiązania sa słabe bo
1)Są mało czytelne
2)Tak czy owak musisz jakoś customizować pytania, np.robiąc fetch joiny
Generalnie dużo więcej problemów niż zysków.
No i nie ma czegoś takiego jak jeden "DTOs" odpowiadajacy jednej encji. Możesz mieć np. encję bazodanową Issue, ale możesz jakiś Issue i IssueWithComments


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
Nowak Adam
@scibi92: To jak w takim razie najlepiej mam wyciągać dane z różnych encji? W sensie chodzi mi o najoptymalniejszy sposób, gdzie mam różne encje z różnymi zawartościami etc. Szukałem dobrego rozwiązania i to wydawało mi się optymalne.
S9
Nie odpowiadaj w komentarzu.
ĆK
działają w systemach za miliony euro (świadek)
S9
@ćk - no i? A jak są klasy na 20 tysięcy lini w takich systemach to tez znaczy że są spoko?
Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

@scibi92: oki, myślałem, że tak będzie przejrzyściej, to w takim razie w jaki sposób powinienem ugryźć powyższy temat. Szukałem informacji, ale powyższy kod to wg mnie była najlepsza opcja.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Z encji wyciągasz dane getterami, przy czym należy uważać żeby były wywoływane w ramach transakcji. A operacje "niskopoziomowe" takie jak wczytanie listy encji przemyciłbym do jakiegoś DAO, ale nie generycznego. Encje zaś dalej mapuje sie na jakieś obiekty DTO/domenowe, ale nie powinno się robić założenia że jedna encja = jedno DTO.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
ĆK
"Z encji wyciągasz dane getterami, przy czym należy uważać żeby były wywoływane w ramach transakcji." Bełkot :D
S9
Aha
Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

@scibi92: Znaczy aktualnie 1 encja = 1 DTO to tylko dlatego, że po prostu nie potrzebuje więcej, bo mogę bez problemu dołożyć kolejne.
Napiszę od nowa ten post, żeby się dodatkowo poradzić.

Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

Postarałem się wyjaśnić na nowo temat w nowym poście, proszę moderację o usunięcie, bądź zablokowanie, albo po prostu zostawienie, wg waszego uznania.
Za problemy przepraszam.

ĆK
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:59
0

Daj spokój. Ile w twoim problemie pomogli "architekci"? Jakiś bełkot widzę.

Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

Znaczy ja akurat nawet praw nie mam do oceniania, bo ja tu proszę o pomoc.
Napisałem post, bo nie do końca rozumiem po prostu odpowiedzi , zdaje sobię sprawę, że część to braki wiedzy, ale gdzieś tam może też być problem, że źle to wytłumaczyłem.

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0
Nowak Adam napisał(a):

Znaczy ja akurat nawet praw nie mam do oceniania, bo ja tu proszę o pomoc.

Napisałem post, bo nie do końca rozumiem po prostu odpowiedzi , zdaje sobię sprawę, że część to braki wiedzy, ale gdzieś tam może też być problem, że źle to wytłumaczyłem.

Napisałem Ci, że masz dwie opcje do wyboru.

Musisz jakoś zmapować jeden typ na drugi, i gdzieś musi być logika do tego. Albo w implementacji pierwszego typu generycznego, albo dostarczona jako zewnętrzny, trzeci parametr.

Jedno jest specyfikacją implementacji w compile timie (interfejsy, dopisanie sygnatur), albo w runtime (przekazanie parametru).

ĆK
"jakoś" "gdzieś" "albo"x4 :D
Riddle
@ćk: Podałem bardzo dokładną odpowiedź Albo w implementacji pierwszego typu generycznego, albo dostarczona jako zewnętrzny, trzeci parametr..
ĆK
Podałeś bełkot, udowodnij kodem.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0
cŻ napisał(a):

Podałeś bełkot, udowodnij kodem.

To się nazywa nomenklatura programistyczna. To że jest dla Ciebie niezrozumiała, nie znaczy że jest bełkotem.

To jest aktualny kod autora postu.

Kopiuj
class Mapper<A, B> {
   public List<B> map(List<A> from) {
      return from.stream()
         .map(obiekt -> {
            return MagicznyMapper(from); // ofc nie będzie działać
         })
         .collect(toList());
   }
}

class First { }
class FirstDto { }
class Second { }
class SecondDto { }

Ma dwie opcje.

Albo dodać mapowanie w implementacji pierwszego typu generycznego (pierwsza część "bełkotu"):

Kopiuj
var mapperFirst = new Mapper<First, FirstDto>();
var mapperSecond = new Mapper<Second, SecondDto>();

class Mapper<A extends Int<B>, B> { // A to pierwszy typ generyczny - interfejs
   public List<B> map(List<A> from) {
      return from.stream()
         .map(obiekt -> {
            return obiekt.map();
         })
         .collect(toList());
   }
}

class First implements Int<FirstDto> { public FirstDto map() { return new FirstDto(); }} // a to jego implementacja
class FirstDto { }

class Second implements Int<SecondDto> { public SecondDto map() { return new SecondDto(); }}
class SecondDto { }

interface Int<B> { 
   B map();
}

...w implementacji pierwszego typu generycznego jest mapowanie.

Albo, przekazać trzeci parametr i w ten sposób dostarczyć mapowanie

Kopiuj
public class Application {
   public static void main(String[] args) {
      var mapperFirst = new Mapper<First, FirstDto>(first -> new FirstDto());  // parametr dostarczający implementację
      var mapperSecond = new Mapper<Second, SecondDto>(second -> new SecondDto());
   }
}

class Mapper<A, B> {
   private final Function<A, B> mapper;

   Mapper(Function<A, B> mapper) {
      this.mapper = mapper;
   }

   public List<B> map(List<A> from) {
      return from.stream()
         .map(obiekt -> {
            return mapper.apply(obiekt);
         })
         .collect(toList());
   }
}

class First { }
class FirstDto { }
class Second { }
class SecondDto { }

@ćk Najpierw poćwicz czytanie ze zrozumieniem, zanim zaczniesz hejtować.

ĆK
dzięki za odpowiedź, prowokowałem, bo ciekawy byłem innego rozwiązania, przeanalizuję i dam odpowiedź do poniedziałku
Riddle
@ćk szczerze mówiąc, to nie obchodzi mnie Twoja opinia. zrób z tym co chcesz
Nowak Adam
@TomRiddle: Nie do końca rozumiem twój przykład, mogę uderzyć na priv ?
ĆK
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 4 lata
  • Postów:59
0

@TomRiddle: ok :) ocenę pozostawię sobie

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0
Nowak Adam napisał(a):

@TomRiddle: Nie do końca rozumiem twój przykład, mogę uderzyć na priv ?

Nie zostanie nic dla potomnych ;)

Żeby zrobić to co chcesz zrobić, najpierw musisz zdecydować czy info o mapowaniu usera na user dto, bardziej ma być bliżej usera, czy bardziej tej klasy abstrakcyjnej którą masz. Jeśli o tym zdecydujesz, to łatwo będzie wybrać czy interfejs czy parametr.

Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

@TomRiddle:
No dobra, najwyżej ośmieszę się na gronie publicznym, jeśli rozwiąże to mój problem z tym zadaniem, to warto xd

Bo problem jeszcze nawet nie występuje na etapie mapowania, co samej implementacji przed mapowaniem(wspomniałem, że z tym też mam problem)

Czyli np podaję:

Kopiuj
public class TempGetQueryUserDetailService<B,R extends TempGetQueryAbstractService<B, R>> {

ale z automatu mam wszędzie:

Method does not override method from its superclass

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0

@Nowak Adam: A mógłbyś gdzieś podać więcej kodu? Wrzucić na githuba albo coś? Bo tak z taką linijką, to ciężko coś powiedziec.

Zobacz pozostały 1 komentarz
Nowak Adam
@TomRiddle: I oczywiście pozmieniałem, tam gdzie mam klasę encji na wartości generyczne. Jeszcze muszę zobaczyć, jak wyciągnąć klasę z wartości generycznej, ale nad tam się nie zastanawiałem z racji, że cała reszta nie działa
Riddle
@Nowak Adam: Teraz nie mam czasu ale zerkne koło 23:00-24:00,. oki?
Nowak Adam
@TomRiddle: dla mnie git malina, a ja postaram się jeszcze pokombinować
Riddle
@Nowak Adam: No, jest dokładnie tak jak powiedziałem, albo interfejs w UserDetail, albo mapper przekazany jako parametr.Spodziewam się że chciałbyś zadeklarować sobie klasę GetQueryUserDetailService<UserDetail, UserDetailDto> i jej użyć? Bo jeśli tak to mam dla Ciebie zła wiadomość. Generyki są tracone podczas kompilacji, i nie ma jak ich odczytać w runtimie. Więc jakoś musisz przekazać implementacje mapowania modeli. I, again możesz to albo zrobić dopisując intetfejs np do UserDetail, albo wstrzykiwać GetQueryUserDetailService springu z parametrem, który Ci to zmap
Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

@TomRiddle:
Mam problem już nie na poziomie samego mapowania Encja->DTo, a wywołanie samego Query do bazy.

GetQueryUserDetailService<UserDetail, UserDetailDto> - Nie chodzi o samą deklerację takiej klasy z tymi klasami, co utworzenie takiej samej klasy, która będzie przyjmowałą dwie wartości generycznE(Encja, oraz DTo Encji)
Czyli np: GetQueryUserDetailService<T, B>

Więc niestety nawet nie mam jak przetestować, twojego sposobu implementacji mapowania, bo upadłem na etapie tworzenia Query do bazy

Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0
Nowak Adam napisał(a):

@TomRiddle:

Mam problem już nie na poziomie samego mapowania Encja->DTo, a wywołanie samego Query do bazy.

GetQueryUserDetailService<UserDetail, UserDetailDto> - Nie chodzi o samą deklerację takiej klasy z tymi klasami, co utworzenie takiej samej klasy, która będzie przyjmowałą dwie wartości generycznE(Encja, oraz DTo Encji)
Czyli np: GetQueryUserDetailService<T, B>

Więc niestety nawet nie mam jak przetestować, twojego sposobu implementacji mapowania, bo upadłem na etapie tworzenia Query do bazy

W kwestii generyków to jest jeden i ten sam problem. Może po prostu opisz jak sobie wyobrażasz użycie tej klasy GetQueryUserDetailService.

Nowak Adam
  • Rejestracja:ponad 4 lata
  • Ostatnio:prawie 4 lata
  • Postów:18
0

@TomRiddle:

Hmm w sensie, że po prostu temat jest nie do ugryzienia z generykami ? To może przedstawię cały obraz sytuacji.

Aktualnie klasa wygląda tak:

Kopiuj
public class GetQueryUserDetailService extends GetQueryAbstractService<UserDetail, UserDetail.UserDetailDto> {

Jest wywoływana w innym serwisie w ten sposób

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(String search);

Jak widzimy klasa : GetQueryUserDetailService ma dwa argumenty - Jest to encja oraz DtoEncji

Natomiast potrzebuję zrobić tak, żeby klasa GetQueryUserDetailService przyjmowała jako argument dwie klasy - Encja oraz DtoEncji

I wtedy wywoływanie by było mniej więcej w innym serwisie:

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(Encja, DtoEncja,String search);
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:około 15 godzin
  • Lokalizacja:Laska, z Polski
  • Postów:10076
0
Nowak Adam napisał(a):

Hmm w sensie, że po prostu temat jest nie do ugryzienia z generykami?

Mówię tylko, że z samych tylko generyków nie jesteś w stanie wykonać żadnej operacji w runtimeie.

Jest wywoływana w innym serwisie w ten sposób

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(String search);

Jak widzimy klasa : GetQueryUserDetailService ma dwa argumenty - Jest to encja oraz DtoEncji

Nie widzę jak ona ma dwa "argumenty". Możesz masz na myśli dwa typy generyczne?

Natomiast potrzebuję zrobić tak, żeby klasa GetQueryUserDetailService przyjmowała jako argument dwie klasy - Encja oraz DtoEncji

I wtedy wywoływanie by było mniej więcej w innym serwisie:

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(Encja, DtoEncja,String search);

No to nie, w ten sposób się tego nie da zrobić, bo nawet gdybyś wyciągnął refleksją tą klasę, to nie wiadomo by było jaką funkcję na niej wywołać (chyba że umówiłbyś się na jedną i tą samą nazwę, co w sumie jest tożsame z wydzieleniem interfejsu.

Nie da się zrobić tak:

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(Encja.class, DtoEncja.class,String search);

Ale, da się zrobić tak:

Kopiuj
private final GetQueryUserDetailService quer;
quer.execute(Encja.class, DtoEncja.class,String search, encja -> new DtoEncja(encja));
albo
quer.execute(Encja.class, DtoEncja.class,String search, DtoEncja::new);

Wtedy deklaracja powinna wyglądać tak

Kopiuj
void execute(T encja, D dto, String search, Function<T, D> mapper)
edytowany 3x, 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.