Co do dzielenia tego na osobne jary czy rozwiązywania potencjalnych problemów ze skalowalnością, nie chciałbym iść tą drogą. Koniec końców to projekt hobbystyczny, w którym chcę się skupić na samej architekturze.
Co do samego podziału odpowiedzialności, nie bardzo wiem jak to rozwiązać.
Weźmy taki przykład, w którym nie muszę korzystać z Springowych eventów
class PostCreator {
private final PostRepository postRepository;
private final NotificationFacade notificationFacade;
PostCreator(PostRepository postRepository, NotificationFacade notificationFacade) {
this.postRepository = postRepository;
this.notificationFacade = notificationFacade;
}
PostDto createPost(CreatePostCommand command) {
final var savedPost = postRepository.save(toEntity(command));
final var postDto = savedPost.toDto();
this.notificationFacade.publishNotification(new PostCreatedNotification());
return postDto;
}
}
public class PostCreatedNotification implements Notification {
@Override
public Channel getChannel() {
return Channel.WEB_SOCKET;
}
}
No i NotificationFacade
po prostu deleguje takie wywołanie do
class NotificationPublisher {
private final WebSocketPublisher webSocketPublisher;
private final EmailPublisher emailPublisher;
public NotificationPublisher(WebSocketPublisher webSocketPublisher, EmailPublisher emailPublisher) {
this.webSocketPublisher = webSocketPublisher;
this.emailPublisher = emailPublisher;
}
public void publishEvent(Notification notification) {
CompletableFuture.runAsync(() -> this.processAndPublish(notification));
}
private void processAndPublish(Notification notification) {
//do some processing?
switch (notification.getChannel()) {
case WEB_SOCKET -> webSocketPublisher.publish(notification);
case EMAIL -> emailPublisher.publish(notification);
}
}
}
Gdzie WebSocketPublisher
oraz EmailPublisher
to interfejsy, zaimplementowane gdzieś w infrastrukturze. No i na tym przykładzie, musze zdecydować do kogo trafi to powiadomienie, czyli powiedzmy muszę iść do domeny User
, znaleźć użytkownika który stworzył posta i jako odbiorców ustawić coś w stylu user.getFollowers()
. Gdzie to zrobić? Dodam, że tych reguł może być więcej. Sam PostCreator
powinien odpowiadać również za stworzenie kompletnej notifykacji, czyli powinien iść po dane użytkownika itp? Wtedy po stronie serwisu odpowiedzialnego za notyfikację, zostaje część techniczna, czyli np. skierowanie tego na odpowiedni topic. Pytanie czy nadal ma sens robienie z tego domeny i pisanie tych interfejsów, jak wszystko co się wewnątrz tego dzieje jest związane z frameworkiem, czy takie notyfikacje to już nie jest stricte część infrastruktury.
Więc nie masz architektury heksagonalnej. Szczególnie jeżeli mówimy o cieknących frameworkach jak Hibernate. Design jest sterowany potrzebami frameworka a nie np poprawności domeny (przykładowo mutowalne encje z masą setterów vs value objects)
Nawet w wysłanym przeze mnie repo jest użycie @Document
wewnątrz domeny, wiele jest też prezentacji mówiących by jednak iść na kompromis i gdy nie trzeba, to po prostu użyć tych adnotacji wewnątrz domeny, zamiast robić mapowania typu dto -> encja biznesowa -> encja bazodanowa, gdzie przy prostym projekcie nie ma różnic między tymi warstwami, albo są one znikome.