Kombinuję trochę z DDD (na razie bardziej teoretycznie niż praktycznie) i zastanawiam się nad problemem agregatów w skład których wchodzi kolekcja z dużą liczbą encji.
Weźmy standardowy przykład konto + operacje na nim. Z jednej strony ma to sens aby stworzyć agregat Account bo wraz z operacjami tworzy on całość - nie da się niektórych operacji wykonać przy pewnym stanie konta etc. Z drugiej strony pytanie jak wtedy rozwiązać problem, ogromnej ilości operacji przypisanych do danego konta. Agregaty z tego co widzę nie powinny mieć dostępu do repozytorium, więc w teorii wszystkie operacje powinny być wczytane w trakcie wczytywania agregatu, ale z oczywistych względów nie jest to zbyt efektywne.
Rodzi się więc pytanie w jaki sposób ogrywać takie przypadki.
Widzę tutaj kilka opcji:
a) Przy operacjach wymagających przeglądania listy operacji wymagać wstrzyknięcia repozytorium lub jakiegoś serwisu domenowego - np sygnatura do dodania operacji
public function addOperation(OperationInterface $operation, OperationLoaderPort $repository): void
b) Rezygnacja z agregatu i np. synchornizacja stanu przez Domain Services / Domain Events - np. addOperation() publikuje zdarzenie OperationAddedEvent i na tej podstawie Account się przelicza
c) Chat gpt podpowiada aby w ogóle wstrzyknąć repozytorium operacji przez publiczną metodę typu setOperationRepository()
Moim zdaniem jedynie opcja a jest w miarę sensowna. Z jednej strony unikamy ładowania operacji przy każdej interakcji z agregatem, a z drugiej wszystkie operacja możemy wykonać dość efektywnie - np. jeśli potrzebujemy przeliczenia stanu konta to nie musimy pobierać operacji, jeśli potrzebujemy wyświetlić operacje to możemy dodać stronicowanie itp.
Opcja b jest raczej bez sensu bo wtedy zmieniamy naszą domenę ze względu na ograniczenia techniczne.
Opcja c mi się nie podoba bo wtedy klient kodu musi wiedzieć, że przed użyciem niektórych funkcji musi setować repozytorium, a przy innych nie musi.
Pytanie czy na ten problem są jakieś bardziej eleganckie rozwiązania?