Wzorzec architektoniczny ports and adapters. Jak mapować model domenowy?

0

Hej. W ramach przećwiczenia zabrałem się za implementację prostego projektu wykorzystując wzorzec ports and adapters. Jednak mam problem jak poprawnie zrobić mapowanie z modelu domenowego na model do persystencji danych. W modelu domenowym mam klasę abstrakcyjną CalendarEvent i dwa pod typy FreeTimeCalendarEvent oraz TreatmentCalendarEvent w secondary ports wystawia interface z metodą CalendarEvent save(CalendarEvent event). W adapterze utworzyłem mapowanie 1:1 z modelem domenowym. Wygląda to tak CalendarEventDao, FreeTimeCalendarEventDao, TreatmentCalendarEventDao. Implementując interface z metodą save muszę zmapować CalendarEvent na CalendarEventDao w związku z czym gubię typ eventu (jestem jedynie wstanie zmapować atrybuty klasy abstrakcyjnej). Oczywiście mógłbym wykorzystać rzutowanie, jednak zawsze wydaje mi się to nieeleganckim wyjściem i "hakiem". Rozwiązanie jakie mi się nasuwa to utworzenie przeciążonej metody save dla obydwu typów. Jednak to by się wiązało z przeciążaniem każdej innej metody w tym interfejsie, co też nie wygląda na rozsądne rozwiązanie.
Nie jestem do końca pewien czy moje podejście jest poprawne. Będę wdzięczny za sugestie.

1

Nie bardzo rozumiem problem. Skoro potrzebujesz znać typ eventu do persystencji, to musisz go przekazać, więc np. mieć dwie metody save z konkretnym typem eventu.

Jednak to by się wiązało z przeciążaniem każdej innej metody w tym interfejsie

Można jakiś generyk tam mieć z <T extends CalendarEvent> ale to wszystko zależy od dalszej implementacji.

0

No właśnie niby nie potrzebuje znać typu do persystecji, ale nie mogę go zgubić przy mapowaniu. Przypadek jest taki ze mam repozytorium, które jako typ przyjmuje klasę abstrakcyjną.

public interface CalendarEventJpaRepository extends CrudRepository<CalendarEventDao, Long> {
}

Adapter do tego repozytorium

public class CalendarEventRepositoryAdapter implements CalendarEventRepository {

    private final CalendarEventJpaRepository calendarEventJpaRepository;

    @Override
    public CalendarEvent save(CalendarEvent calendarEvent) {
        //map calendarEvent to  calendarEventDao and save
        return calendarEventJpaRepository.save(calendarEvent)
    }

    @Override
    public void remove(CalendarEvent event) {

    }
}

W tym miejscu leży problem jak zrobić to mapowanie. Przeciążona metoda save też będzie jakaś dziwna bo pod spodem wywoła i tak tą samą metodę save z CalendarEventJpaRepository.

2

No w Javie nie ma na to lepszego sposobu niż przeciążanie metod lub generyk.

public class CalendarEventRepositoryAdapter implements CalendarEventRepository

I to nie jest do końce poprawne podejście. Powinno być np. PostgresCalendarEventRepository albo JpaCalendarEventRepository. Nazwa klasy implementującej adapter powinna być już szczegółowa. Dodatkowo najlepiej rozdzielać porty,np.
PersistCalendarEventPort z metoda persist i FindCalendarEventPorts z metodami np. findById, albo FindByRange(LocalDate from, LocalDate to); etc

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