CQRS i viewmodele

N0
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Gdańsk
  • Postów:647
0

Czy w aplikacji MVC zgodnej z CQRS viewmodele i komendy (zapytania) powinny być reprezentowane przez różne klasy? Czy jeśli mam np. CreateXCommand, to powinienem też mieć CreateXViewModel? Przy takim podejściu komenda jedynie opakowuje model widoku, czyli trzeba tworzyć wiele "nadmiarowych" klas, ale jaka jest alternatywa? Dziedziczenie viewmodeli po ICommand (IQuery) albo przekazywanie komend (zapytań) do widoku raczej nie pachnie dobrze.

E9
  • Rejestracja:ponad 13 lat
  • Ostatnio:10 miesięcy
  • Postów:395
2

Do api mogą przychodzić spokojnie command i query, a kontroler może je wysyłać na szynę. Jeśli jednak command lub query potrzebują dodatkowych informacji niż to co przyszło z zewnątrz to powinny to być oddzielne klasy. O dziedziczeniu viewmodeli z ICommand zapomnij.

edytowany 1x, ostatnio: error91
N0
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Gdańsk
  • Postów:647
0

Po dłuższym namyśle (wiem, dwa miesiące :p) stwierdzam, że MVC i CQRS (u mnie zaimplementowane przy użyciu MediatR) raczej do siebie nie pasują. Czy stosowanie MediatR jest warte duplikowania każdego viewmodelu? @Aventus Ty się znasz dobrze na MediatR. Co o tym sądzisz?

neves
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 9 godzin
  • Lokalizacja:Kraków
  • Postów:1114
1

Jeśli nie robisz jakiegoś AOP w okół command/query, nie masz eventów, to nie potrzebujesz MediatR.
Do robienia CQRS, nie musisz mieć każdej komendy i query osobno, możesz jeśli to coś wniesie do systemu który tworzysz, a jak nic nie wnosi to tylko dodajesz nikomu niepotrzebnej złożoności przypadkowej.

title


edytowany 1x, ostatnio: neves
Zobacz pozostałe 2 komentarze
N0
Hmm, faktycznie ;) Ale co zrobić, jeśli te klasy staną się za długie?
Aventus
A nawet w myśl prezentacji Udi Dahan'a którą niedawno oglądałem, można mieć CQRS całkowicie bez zmieniania kodu :) wszystko zależy od skali i tego gdzie chcemy "widzieć" te CQRS. Ja jestem zwolennikiem rozdzielania klas na podstawie operacja, czyli oddzielna klasa command i handler na każdą akcję jaką chcemy wykonać w systemie. Ale fakt, można to robić inaczej.
Aventus
@nobody01: dla mnie używanie jednej klasy do np. wielu zapisów to próba nadania innej nazwy dla popularnego antywzorca w postaci managera. Taki "manager" od wszystkiego, w jednym miejscu. Osobiście odradzam.
neves
to samo co robisz gdy komendy urosną zbyt duże, czy jakikolwiek kod urośnie zbyt duży, czyli wydzielasz mniejsze kawałki i je nazywasz i zamykasz w postaci serwisów czy jakiś innych klocków których używasz do modelowania
neves
dodałem przykład jak wygląda serwis aplikacyjny w aplikacji którą obecnie piszę, serwis składa się z 3 komend i jednego zapytania i w sumie ma 84 linijki kodu
SZ
  • Rejestracja:prawie 11 lat
  • Ostatnio:około godziny
  • Postów:1473
2
nobody01 napisał(a):

Po dłuższym namyśle (wiem, dwa miesiące :p) stwierdzam, że MVC i CQRS (u mnie zaimplementowane przy użyciu MediatR) raczej do siebie nie pasują. Czy stosowanie MediatR jest warte duplikowania każdego viewmodelu? @Aventus Ty się znasz dobrze na MediatR. Co o tym sądzisz?

Ale co w tym złego, że masz klasy osobno do zapisu, osobno do edycji osobno do wyświetlania? Dla mnie dużą zaletą jest to, że każdą operację mogę mieć w osobnej klasie a wywołuje to z jednego miejsca. I jak sama nazwa wskazuje wydaję mi się, że głównym celem mediatR jest zaimplementowanie wzorca mediator.

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

.Czy stosowanie MediatR jest warte duplikowania każdego viewmodelu?

Troche blednie zadane pytanie. Podejrzewam ze w Twoim przypadku to nie wzorzec mediator wymusza "duplikowanie" view modelu, a fakt ze - calkiem slusznie- masz podzial na warstwy i warstwa domeny nie wie nic o widoku. Tak wiec naturalnie rezutatem zwracanym z handlera bedzie zwykle DTO bez danych metadancyh o widoku.Gdybys wszystko wrzucil do jednego worka to bys mogl zwracac sam model widoku, ale tego oczywiscie nie powinno sie raczej robic. Chyba ze piszesz naprawde prosty CRUD.

Druga sprawa to ze przy stosowaniu API i oddzielnego frontu zwracanym rezultatem bedzie wlasnie DTO, wiec zazwyczaj nawet nie trzeba nic duplikowac ani mapowac. W Twoim jednak przypadku pytasz o MVC- zastanowmy sie. Zwracasz jakies DTO jako wynik requestu/polecenia, oraz w warstwie UI mapujesz to na view model. Moim zdaniem nie ma w tym problemu, poniewaz Twoj view model moze miec dodatkowe informacje na temat chociazby formatowania wyswietlanych danych czy tez dodatkowe wlasciwosci zwracajace dane zbudowane z kilku innych juz gotowych wlasciwosci. Tak wiec czy jest sens posiadania dwoch klas tak zwiazanych (jedna tylko posrednio) z widokiem modelu? Tak, jesli chcesz zachowac odpowiedni podzial miedzy warstwami.

Jesli zas chodzi o komunikacje w druga strone, czyli wyslanie czegos z kontrolera do domeny to sprawa wyglada tak samo. Dodatkowo moim zdaniem komendy oraz zwracane obiekty powinny byc niemutowalne, a view model zazwyczaj posiada settery.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus
HA
ViewModel ma setery bo jest to zależność od frameworka. Jeśli bardzo chcesz to możesz sobie binder nadpisać :P
Aventus
Jak najbardziej, ja jedynie stwierdziłem fakt że właśnie zazwyczaj posiadają settery. Zresztą nie widzę w tym nic złego ponieważ zakres i cykl życia modelu widoku jest krótki.
HA
A co to ma do długości cyklu życia.?
N0
  • Rejestracja:prawie 7 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Gdańsk
  • Postów:647
0

@Aventus: Wracam z innego tematu, bo za duży offtopic się zrobił ;) Chodziło mi o to, że zwracanie z handlera DTO, a następnie mapowanie go na ViewModel, który zawiera te same dane co DTO + metadane dla widoku, jak dla mnie jest oznaką przeinżynierowania w sytuacji, gdy mamy tylko MVC jako jedyną warstwę prezentacji. Chociaż korzyści wynikające z podziału na warstwy i projekty (czytelność kodu) są większe, to jednak są obecne klasy (DTO), które istnieją tylko po to, aby ten podział mógł mieć miejsce. Chociaż pewnie to jest zło konieczne. ;)

Aventus
  • Rejestracja:prawie 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
1

Tak, jest to zlo konieczne (w pewnym sensie). Do tego dochodza elementy ktore juz kiedys wymienialem:

  • Niemutowalnosc DTO
  • Dodatkowe, specyficzne dla widoku elementy w view modelu (np. atrybuty walidacji i formatowania)

Rowniez tak jak wspomnialem w innym watku, to co pisalem brzmialo jakbys mial zle wszystko porozdzielane. Ale moze to oddzielny temat. Reasumujac- tak, taki podzial moze nie miec sensu przy prostych aplikacjach, nigdzie tez do stosowania tego w takich przypadkach nie zachecalem. Natomiast kiedy tylko dochodzi bardziej rozbudowana logika biznesowa to szybko ujawniaja sie zalety takiej architektury.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
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)