Chcę wdrożyć moją pierwszą aplikację przy użyciu wzorca CQRS wraz z Event Sourcing. Zastanawiam się, jak prawidłowo obsługiwać tworzenie zagregowanych korzeni. Powiedzmy, że ktoś wysyła polecenie CreateItem. Jak sobie z tym poradzić? Gdzie należy przechowywać zdarzenie ItemCreated? Jako pierwsze wydarzenie nowego przedmiotu? Czy powinienem mieć jakiś element ItemList, który agreguje wszystkie elementy, a lista zdarzeń zawiera tylko zdarzenia ItemCreated?
Udi Dahan sugeruje, aby nie tworzyć zagregowanych korzeni i zawsze używać zamiast tego jakiejś metody pobierania. Ale jak mogę pobrać coś nowego i na pewno nie ma przypisanego żadnego identyfikatora. Rozumiem tę ideę i rozsądnie jest myśleć, że nowy obiekt to obiekt, którego stan składa się z odpowiedzi na zero zdarzeń. Ale jak mam go używać? Czy powinienem mieć w moim repozytorium odrębną metodę, taką jak getNewItem()
lub uczynić moją get(id)
metodę akceptującą Optional<ItemId>
?
Edycja: Po pewnym czasie kopania znalazłem naprawdę ciekawą implementację wyżej wymienionych wzorców za pomocą aktorów. Autor zamiast tworzyć agregat pobiera go z pewnego rodzaju repozytorium z nowo utworzonym UUID. Wadą tego podejścia jest to, że pozwala on na przejściowy stan niespójności. Zastanawiam się także, jak mogę wdrożyć delete
metodę z takim podejściem. Po prostu dodać usunięte wydarzenie do listy zdarzeń agregatu?
Odpowiedzi:
Z tego, co rozumiem, w postie Udi jest to, że żaden przedmiot nie pojawia się z powietrza. Zawsze jest (prawie) zawsze coś, a dokładniej, pewne działanie domeny, które spowodowało utworzenie elementu. Podobnie jak w przypadku Udi, że użytkownik faktycznie rodzi się z odwiedzającego rejestrującego się na stronie. W tym momencie i w tym ograniczonym kontekście Odwiedzający jest zagregowanym rootem, który jest pobierany przez jego adres IP. Ten gość następnie tworzy nowy „element”, w tym momencie użytkownika, poprzez operację domeny o nazwie Zarejestruj . To samo dotyczy kroku wcześniejszego, który jest innym ograniczonym kontekstem: strona odsyłająca to AR, który jest pobierany przez adres URL i który ma operację domeny o nazwie BroughtVisitorWithIp , w której urodził się użytkownik.
Udi również bardzo ładnie pisze o usuwaniu: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ . Główną ideą jest to, że nigdy niczego nie usuwasz. Za nami zawsze jest operacja domeny, którą chcemy uchwycić. Jak zamówienie anulowane, a nie usuwane. Przeczytaj, to bardzo dobry post.
Głównym punktem na obu kontach, wykonując DDD, a zwłaszcza Sourcing zdarzeń, jest to, że nigdy nie powinieneś wykonywać prostych operacji CRUD. Jeśli znajdziesz się w sytuacji, w której naprawdę musisz po prostu wstawić, zaktualizować lub usunąć niektóre dane, a naprawdę nie ma za tym operacji domeny, być może DDD i Event Sourcing nie są odpowiednie dla tego ograniczonego kontekstu . Możesz dowolnie łączyć te dwa elementy tak długo, jak długo jeden kontekst ogranicza się do jednej zasady. W ten sposób kontekst ograniczony w stylu CRUD może utworzyć wiersz w bazie danych, który stanie się bytem i agregatem głównym w innym ograniczonym kontekście, w którym można teraz pobrać AR i nie trzeba go tworzyć.
źródło