CQRS/ES - Pytanie

Marcin Lazar
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:3
1

Cześć,

Właśnie projektuję sobie testową aplikację z wykorzystaniem architektury CQRS/ES. Napotkałem jednak problemy na które nie umiem znaleźć odpowiedzi(może źle wpisuję w google). Ale do rzeczy, przedstawię to na prostym przykładzie bloga.
Jest sobie blog, autorzy dodają sobie artykuły etc. Jest też administrator który czuwa nad ich treściami, i może banować autorów. Po zbanowaniu autora wszystkie jego artykuły mają być niedostępne. No właśnie, i tutaj mam problem, bo o ile łatwo zmienić agregat autora, poprzez zmienienie jego stanu na zbanowanego(atrybut true/false) nie do końca rozumiem jak mam oznaczyć wszystkie jego artykuły jako niedostępne(niedostępne, czyli usuwam je z bazy danych zawierającą projekcje - read modele). Miałem 2 pomysły:

  1. W command handlerze emituję kilka eventów które banują autora(1 event), oraz artykuły(n eventów)
  2. Tworzę sobie process manager który po wyemitowaniu eventu do zbanowania autora zmieni stan artykułów
    W tych dwóch rozwiązaniach jest tylko jeden problem. Skąd mam zabrać identyfikatory wszystkich agregatów dla artykułu. Czy mogę sobie je wyciągnąć poprzez zapytanie bazy danych z read modelami o wszystkie id artykułów dla danego autora?
Aventus
  • Rejestracja:prawie 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
1

Jesli wystarczy Ci samo zbanowanie autora (w sensie wyslanie w "swiat" eventu o jego zbanowaniu) bez odpowiedniego eventu dla kazdego artykulu, to w denormaliserze gdzie tworzysz read model skonsumuj ten event i usun odpowiednio wszystkie artykuly tego autora. Ewentualnie dla kazdego eventu o usunietym artykule, usun ten artykul z read modelu.

Skąd mam zabrać identyfikatory wszystkich agregatów dla artykułu.

Nie wiem jak wyglada Twoj read model, ale czy artykuly nie powinny miec ID autora? W takim przypadku wystarczylo by usuniecie/zmiana stanu artykulu na podstawie ID autora.

Tworzę sobie process manager który po wyemitowaniu eventu do zbanowania autora zmieni stan artykułów

Chyba mylisz czym jest process manager. Process manager na pewno nie powinien zmieniac zadnego stanu artykulow! Logika biznesowa nie jest odpowiedzialnoscia process managerow. Process Manager jest jedynie od koordynacji dzialan agregatow. Zachecam do lektury

You should not use a process manager to implement any business logic in your domain. Business logic belongs in the aggregate types.

EDIT: Żeby bardziej to zobrazować, process manager powinien konsumowac eventy i emitować polecenia, czyli event -> command. W Twoim przypadku byłoby to coś w stylu: AuthorBanned -> RemoveArticlesForAuthor


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 5x, ostatnio: Aventus
Marcin Lazar
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:3
0

@Aventus: Dzięki za odpowiedź. Jednak trochę podałem zły przykład. Chciałbym żeby zbanowane artykuły nie zostały usunięte z bazy danych projekcji, ale zmieniły swój atrybut na coś w rodzaju "zbanowany". i teraz chciałbym żeby agregat tego artykułu miał też ustawiony taki atrybut na "zbanowany". Nie wiem ale o ile się nie mylę nie powinno się czerpać stanu z bazy projekcji, dlatego myślę że mógłbym zapisywać wszystkie id artykułów w agregacie autora(jako tablica identyfikatorów)?

Chyba mylisz czym jest process manager

Tutaj dobrze rozumiem czym jest process manager :)

fakt, napisałem

...eventu do zbanowania autora zmieni stan artykułów

Chodziło mi że on sam nie zmieni stanu tych artykułów, tylko wyda odpowiednie komendy do zmiany stanu :)

edytowany 1x, ostatnio: Marcin Lazar
Aventus
  • Rejestracja:prawie 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
1

@Aventus: Dzięki za odpowiedź. Jednak trochę podałem zły przykład. Chciałbym żeby zbanowane artykuły nie zostały usunięte z bazy danych projekcji, ale zmieniły swój atrybut na coś w rodzaju "zbanowany". i teraz chciałbym żeby agregat tego artykułu miał też ustawiony taki atrybut na "zbanowany".

Jesli chodzi nie o usuwanie, a ustawianie odpowiedniego "stanu" (flagi) artykulow to zaproponowane przeze mnie podejscie sie nie zmienia. Nadal emitujesz eventy, i na ich podstawie ustawiasz odpowiednio flage w read modelu.

Nie wiem ale o ile się nie mylę nie powinno się czerpać stanu z bazy projekcji, dlatego myślę że mógłbym zapisywać wszystkie id artykułów w agregacie autora(jako tablica identyfikatorów)?

Jesli dobrze rozumiem Twoj model i wymagania transakcyjnosci w obrebie kontekstu (ban autora skutkuje "banem" artykulow), to Autor powinien byc aggregate root trzymajacy wszystkie swoje artykuly. Wtedy, wywolujac metode banujaca Autora, Autor iteruje po swoich artykulach i rowniez je banuje. Nie za bardzo rozumiem do konca o co chodzi z tym stanem z projekcji- stan agregatow ladujesz poprzez rehydrate za pomoca eventow. Mozna rowniez zastosowac wzorzec memento.

Chodziło mi że on sam nie zmieni stanu tych artykułów, tylko wyda odpowiednie komendy do zmiany stanu :)

Ok, opacznie to odebralem.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus
Marcin Lazar
  • Rejestracja:około 6 lat
  • Ostatnio:około 6 lat
  • Postów:3
1

Ok, dobra już zrozumiałem :) Wielkie dzięki @Aventus

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)