Co sądzicie na temat tego artykułu? https://itenium.be/blog/design/CQRS-Ramble/
class CreateUserRequest {
string Name;
DateTime BirthDate;
Address Address;
}
class UpdateUserRequest : CreateUserRequest {
int Id;
}
class FullUserViewModel : UpdateUserRequest {
// perhaps this one is a stretch 😅
DateTime CreatedOn;
string CreatedBy;
}
Doskonały przykład. Oczywiście tego jak nie dziedziczyć.
Moim zdaniem nie warto czytać tekstów kogoś, kto nie ogarnia, że DRY dotyczy logiki, a nie struktur.
Nie mam w zwyczaju czytać "artykuły" zapychające treść memami. Ehh, chyba się starzeję...
EDIT: Podejrzewałem jaka będzie puenta, rzuciłem okiem na ostatni paragraf i... bingo. "Nie używaj CQRS do aplikacji CRUDowych". Czyli reasumując- używaj CQRS tam gdzie to ma sens, jak każde inne narzędzie. Wielkie odkrycie, medal się należy. Nie mówiąc już o tym że jest coś takiego jak CQRS w procesie przy zastosowaniu wzorca mediator i to sprawdzi się nawet w prostych aplikacjach. Auto zapewne jak wiele innych osób mówi CQRS i myśli o tylko jednym sposobie jego zastosowania.
CQRS to nie jest panaceum; w ogóle zadnego panaceum w informatyce nie ma. Jeśli ktoś traktuje CQRS, DDD albo jakiekolwiek inne podejście na zasadzie jak mam młotek to wszystko wygląda jak gwoździe
to wiadomo ze będzie z tego problem. Śmiejemy się tu często z podejscia encja na twarz i pchasz
ale jeśli ktoś robi generic cruda gdzie tabele bazodanowe, obiekty domenowe i DTO mapują się 11 to pewnie nie potrzeba nic więcej (ale może lepiej w ogóle nie pisać kodu tylko zapiać spring-data-rest?).
Rzecz w tym, że mimo wszystko wiele aplikacji, szczególnie nie tutoriali z jutuba, tylko takich za które ludzie płacą, to nie są generyczne crudy.
@obscurity: paragrafy An Explosion of Classes
i An Explosion of Duplication
są oparte na założeniu, że programowanie polega na tworzeniu zbędnych warstw oraz bezsensownych klas metodą kopiuj i wklej. Działanie w ten sposób jest złe niezależnie do tego, czy robimy CRUDa i czy używamy do tego CQRS, czy nie. Nie widziałem sensu w czytaniu dalej, więc wstawki kodu potraktowałem być może niesłusznie jako popis umiejętności autora.
W ogólnym przypadku można mieć jeden generyczny handler do każdego typu requestu, generycznie je mapować i zapisywać do bazy. Nie potrzeba żadnych serwisów, "repozytoriów" ani całego tego badziewia, które ten koleś sugeruje.
W pewnym sensie mamy An Explosion of Classes
, jednak wydzielone przypadki użycia do odrębnych klas/typów wnoszą czytelność, SRP itp. A przynajmniej zbliżają do tego i do modularności.
Bo czy kierując się w drugą stronę nie uzyskamy jeszcze większej patologii? Ostatnio zauważyłem, że niektórzy bronią się przed takim podejściem. Są niechętni do refaktoryzacji i rozbijania klas serwisów mających po kilka tysięcy linii, nawet jeśli to mało skomplikowane przypadki. Tak czy owak, gdy mamy IoC to wstrzykujemy zależności. Ile z nich wstrzykniemy do handlera realizującego przypadek użycia, a ile do jakiegoś uber serwisu?