CQRS nauka

UW
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 5 lat
  • Postów:2
0

Cześć,
Mam za zadanie napisać aplikacje webową w oparciu o wzorzec CQRS. Posługując się "teoretycznymi" przykładami na które natknąłem się na internecie ciężko przełożyć mi to na kod.
Znacie może jakieś wartościowe materiały które od A do Z tłumaczą ideę CQRS jako takiego z przykładami wykorzystania jako kod ? najlepiej w formie książki, wideo, ewentualnie treściwego artykułu.

hcubyc
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad 2 lata
0

Tu jest wszystko wytłumaczone: https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

W uporszczeniu chodzi o to, że do części 'command', która wykonuje akcje/komendy stosujesz dwie ścieżki kodu - pierwsza słuzy do pobierania danych (ale tylko potrzebnych do realizacji komend biznesowych) i zapisywania/usuwania/zmiany stanu i druga 'query', z którego wyciągasz tylko potrzebne dane. Przykład: rejestrujesz użytkownika - częśc biznesowa - komenda. Pobierasz dane o uzytkowniu i zapisujesz w częsci 'command'. Wyświetlasz listę użytkowników, szukasz postów po użytkownikach - część query. To wszystko nawet może hulać na jednej bazie danych pod spodem czy innym źródle danych, chodzi o to, że wszystkie biznesowe akcje maja być spójne i zawsze mieć najświeższe dane, natomiast częśc query może być 'ewentualnie spójna', ale za to ma się świetnie skalować lub umożliwiać skalowanie w przyszłości.


Limitations are limitless > ##### Ola Nordmann napisał(a)
> Moim językiem ojczystym jest C++ i proszę uszanować to, że piszę po polsku.
edytowany 3x, ostatnio: hcubyc
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
1

Tylko po co tu pchać od razu jakieś "repozytoria"? Można to wszystko przecież zaimplementować normalnie, bez nieudolnych implementacji wzorców z innej klasy abstrakcji.

hcubyc
Masz rację, ja operuję na tym wzorcu, więc łatwiej mi się pisało.
0

A jakie to sa te złe implementacje repozytoriów? I co w zamian?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
0

Złe to takie, w których byle DAO jest nazywane repozytorium. W zamian nazywanie rzeczy po imieniu.

0

A czym jest prawdziwe repozytorium?

miszasty93
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 3 lata
  • Postów:93
6

Chodzi o to, że obecnie (niestety) zatarła się różnica między DAO a Repository (mam odczucie, że w Javie dzięki Spring Data JPA w szczególności mamy z tym do czynienia). Oba wzorce działają na innych poziomach abstrakcji.

  • Repository jest tworem na wyższym poziomie abstrakcji i bliżej mu do DDD. DAO to DAO, ot taki wzorzec, z DDD nie ma nic wspólnego.
  • Repository powinno być powiązane z jakimś typem kolekcji i zwracać tylko je. DAO służy ogólnie to wyciągania danych - różnych danych. Jeśli chcesz pobrać wiek 10 najstarszych użytkowników - DAO zwróci Ci po prostu kolekcję 10 intów, Repository powinno Ci zwrócić 10 całych użytkowników. Jeśli będziesz chciał wykonać zaawansowanego SQLa i zwrócić coś dziwnego to skorzystasz z DAO.
  • Repository jest IMO ściśle powiązane ze tzw. Specyfikacjami jeśli chcesz wykonywać bardziej zaawansowane operacje wyszukujące. DAO czegoś takiego nie ma bo jest bardzo blisko SQLa.

Mam nadzieje, że nie popłynąłem za bardzo. Trochę uczepiłem się tego SQLa, ale najczęściej korzystamy pod spodem właśnie z niego ;)

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
3

@miszasty93: dobre podsumowanie, chociaż Specyfikacje tak naprawdę nie są konieczne, równie dobrze repozytorium może wystawiać konkretne metody odpowiadające przypadkom biznesowym. I szczerze mówiąc ja preferuję takie podejście, bo specyfikacji to dla mnie taki trochę wyciek abstrakcji.
I masz rację, że najczęściej używamy SQL, ale nic nie stoi na przeszkodzie, żeby źródłem danych dla repozytorium był plik albo usługa sieciowa. Właśnie o to chodzi z repozytoriami, że stanowią abstrakcje i zwracają obiekty, nieważne skąd.

0

A jeśli potrzebujemy tylko jednego użytkownika to już nie możemy użyć Repository, bo on zwraca kolekcję? Chyba że pobrać kolekcję z jednym elementem? Tylko czy to nie bez sensu?
Czyli taki ogólny podział to DAO zwraca proste dane, a Repository obiekty?
Tylko że jak ktoś chce 10 najstarszych użytkowników to mało prawdopodobne, że same ID mu się przydadzą, więc tak naprawdę DAO jest mało użyteczne. Chyba że np Repository do wyszukania korzysta z DAO i zwraca obiekty?

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
0

Repozytorium nie ma zwracać dowolnych obiektów tylko Aggregate Rooty. Czyli, aby w ogóle rozmawiać o repozytorium trzeba mieć aplikację tworzoną zgodnie z DDD. W przeciwnym razie mamy jakieś DAO, nieważne czy zwraca inty czy obiekty.

edytowany 1x, ostatnio: somekind
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0
somekind napisał(a):

równie dobrze repozytorium może wystawiać konkretne metody odpowiadające przypadkom biznesowym.

Co to za brednie...? Niby jakie?. W takim razie po co ci DM i w ogóle repo ?

Repository jest tworem na wyższym poziomie abstrakcji i bliżej mu do DDD. DAO to DAO, ot taki wzorzec, z DDD nie ma nic wspólnego.

Bez sensu a jak bym chciał używać DAO zamiast ORM pod Repo to mi zabronisz, bo to DDD. Jak to nie ma nic wspólnego z DDD ? Ma tytle wspólnego z DDD, że można go w nim używać jak każdy inny wzorzec, jeśli to ma sens.

@miszasty93

To co piszesz to jest takie trochę pitu pitu pierdulitu. Praktyczna definicja Repo jest bardzo prosta Twór zapewniający dostęp do obiektów z warstwy dziedziny interfejsem kolekcji a jedyne obiekty dziedziny, do których jest sens odnosić się przez repository to DM.

edytowany 1x, ostatnio: Enter Name
miszasty93
No tak, tylko nie każdy po przeczytaniu takiej definicji wie o co chodzi ;)
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

A wracając do tematu CQRS to zrób sobie StoreService czy tam CommandService i ReadService. No i już, masz swój upragniony CQRS. ;)

EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Repozytorium nie ma zwracać dowolnych obiektów tylko Aggregate Rooty. Czyli, aby w ogóle rozmawiać o repozytorium trzeba mieć aplikację tworzoną zgodnie z DDD. W przeciwnym razie mamy jakieś DAO, nieważne czy zwraca inty czy obiekty.

Repo ma zwracać DM, bo to jest jedyny obiekt dziedziny, który jest sens zwraca prez Repo bo niby co miał by zwracać TS albo TableModule?, a to czy to robisz zgodnie z DDD to już inny problem. Repository i DM, możesz równie, dobrze używać bez DDD (modelu dziedziny znangeo z DDD) ale czy jest sens moim zdaniem, nie. Poza tym to, że masz 4-warstwową architekturę z DM z DDD I dependency inversion z Repo to jeszcze nie oznacza, że pracujesz zgodnie z metodyką DDD.

edytowany 1x, ostatnio: Enter Name
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
0
Enter Name napisał(a):

Co to za brednie...? Ty to zawsze coś palniesz..

Bredzić tutaj może jedynie ten tytan intelektu, który wyciął pół mojego zdania z kontekstu. To, że nie wiesz czym jest specyfikacja nie znaczy, że możesz ignorować tę część.

To serwis operujący na repo i obiektach DM powinien wystawia konkretne metody odpowiadające przypadkom biznesowym a cały przypadek biznesowy zakreśla się operacjami na obiekcie Domeny, który zwraca repo.

Serwisy i encje wykonują logikę biznesową, a repozytoria dostarczają danych. Skoro to tak trudne do zrozumienia dla Ciebie, to lepiej zamiast tracić czas na forum poczytaj sobie książki. Np. u Evansa, w dziale o repozytoriach jest sekcja Querying a repository. Tam jest wyjaśnione, że w repozytorium mogą znajdować się metody wykonujące zdefiniowane zapytania zwracające dane na potrzeby konkretnych potrzeb kodu klienckiego.

EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Tam jest wyjaśnione, że w repozytorium mogą znajdować się metody wykonujące zdefiniowane zapytania zwracające dane na potrzeby konkretnych potrzeb kodu klienckiego.

Ja polecam poczytać o problemach związanych z używaniem repo w książce Fowlera.

Ty nie rozumiesz co tam pisze takim specyfikatorem równie dobrze może być IdentityFiled lub zakres daty od do. Specyfikatory typu Matching Cirteria czy wystawianie jakiś lambd to wyciek abstrakcji infrastruktury. Zwracanie jakiś obiektów czy wartoci do warstwy klienckie z repo to pisanie syfu. Repo może zwracać jedynie jakieś dodatkowe metadane związane z DM ale to i tak jest w zakresie przypadku użycia warstwy klienckiej a nie potrzeby płynące z kodu klienckiego to tak jak byś chciał obarczać repo generowanie paginacji BEZ SENSU!.

Poza tym polecam coś świeższego jak Vaughn Vernon a zwłaszcza przeanalizowanie kodu z repo tego Pana.

Bredzić tutaj może jedynie ten tytan intelektu

Sam jesteś tytanem intelektu i do tego prosiakiem :P

zapytania zwracające dane na potrzeby konkretnych potrzeb kodu klienckiego.

Pokaż mi jakiś przykład bo nie wieże, że naprawdę coś takiego piszesz.

edytowany 1x, ostatnio: Enter Name
john_klamka
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 5 lat
  • Postów:177
1
Enter Name napisał(a):
somekind napisał(a):

Repository jest tworem na wyższym poziomie abstrakcji i bliżej mu do DDD. DAO to DAO, ot taki wzorzec, z DDD nie ma nic wspólnego.

Bez sensu a jak bym chciał używać DAO zamiast ORM pod Repo to mi zabronisz, bo to DDD. Jak to nie ma nic wspólnego z DDD ? Ma tytle wspólnego z DDD, że można go w nim używać jak każdy inny wzorzec, jeśli to ma sens.

Repozytorium ma imitować kolekcję obiektów. To jak jest zaimplementowane nie ma znaczenia z punktu widzenia DDD - może być ORM, może być DAO, może być nawet system plików. Spójrz sobie na ten schemat autorstwa Evansa: img. Zauważ, że nie ma żadnej informacji na temat tego, jak repozytorium realizuje dostęp do encji.

EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0
john_klamka napisał(a):
Enter Name napisał(a):
somekind napisał(a):

Repository jest tworem na wyższym poziomie abstrakcji i bliżej mu do DDD. DAO to DAO, ot taki wzorzec, z DDD nie ma nic wspólnego.

Bez sensu a jak bym chciał używać DAO zamiast ORM pod Repo to mi zabronisz, bo to DDD. Jak to nie ma nic wspólnego z DDD ? Ma tytle wspólnego z DDD, że można go w nim używać jak każdy inny wzorzec, jeśli to ma sens.

Repozytorium ma imitować kolekcję obiektów. To jak jest zaimplementowane nie ma znaczenia z punktu widzenia DDD - może być ORM, może być DAO, może być nawet system plików. Spójrz sobie na ten schemat autorstwa Evansa: img. Zauważ, że nie ma żadnej informacji na temat tego, jak repozytorium realizuje dostęp do encji.

No tak ale nie rozumiem dlaczego wyskakujesz z tą ilustracją, która nawet z książki Evansa nie pochodzi o której była mowa i jest to jedynie "Pattern Language Overview" Z punktu widzenia DDD jeśli nie utrwalasz agregatu czy encji możesz pobierać encje lub wartwości za pomocą serwisu ale z tej ilustracji się już tego nie dowiesz..... Ja biję do tego, że DDD to Metodyka rozwoju oprogramowania a nie suchy zestaw wzorców.
Tak samo robienie prezentacji na temat CQRS w tym stylu "W CQRS komendy potrzebują command handlera, command handler potrzebuje mediatora" graniczy z paranoją ponieważ jest przedstawiany jako suchy zestaw wzorców nie adekwatnie do problemu, który ma rozwiązać.

edytowany 1x, ostatnio: Enter Name
YA
Metodologia - nauka o metodach, metodyka - zbiór metod ;) Poza tym słusznie, przestawienie struktury mówi nic o tym jak coś działa.
EN
Przejęzyczenie chodziło mi o Metodyke a dokładniej w kontekście podejście do rozwoju oprogramowania.
john_klamka
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 5 lat
  • Postów:177
0
Enter Name napisał(a):

No tak ale nie rozumiem dlaczego wyskakujesz z tą ilustracją, która nawet z książki Evansa nie pochodzi o której była mowa i jest to jedynie "Pattern Language Overview" Z punktu widzenia DDD jeśli nie utrwalasz agregatu czy encji możesz pobierać encje lub wartwości za pomocą serwisu ale z tej ilustracji się już tego nie dowiesz..... Ja biję do tego, że DDD to metodologia a nie suchy zestaw wzorców.
Tak samo robienie prezentacji na temat CQRS w tym stylu "W CQRS komendy potrzebują command handlera, command handler potrzebuje mediatora" graniczy z paranoją ponieważ jest przedstawiany jako suchy zestaw wzorców nie adekwatnie do problemu, który ma rozwiązać.

"Pattern Language Overview" to tytuł tej ilustracji, pochodzącej z książki Erica Evansa pt. "Domain-Driven Design Definitions and Pattern Summaries". Załączyłem ją tu, aby mojej wypowiedzi nadać kontekst, w którym ma ona sens.

Jeśli mówisz o pobieraniu encji lub wartości za pomocą serwisu, to chyba masz na myśli serwis aplikacji, a to zupełnie coś innego niż serwis domenowy i nijak nie można ich porównać.

DDD to również zestaw wzorców tzw. "taktycznych" - to są właśnie te nieszczęsne repozytoria, serwisy, agregaty i cała reszta. Wzorce te można jak najbardziej stosować bez "pełnego" DDD, większość z nich pozytywnie wpływa na czystość kodu.

Aventus
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
0
UncleWoo napisał(a):

(...)
Znacie może jakieś wartościowe materiały które od A do Z tłumaczą ideę CQRS jako takiego z przykładami wykorzystania jako kod ? najlepiej w formie książki, wideo, ewentualnie treściwego artykułu.

Tutaj bardzo ciekawa i dosyc obszerna seria na temat tworzenia przykladowego systemu w ramach ktorego zaimplementowano rowniez CQRS:
https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/microservice-ddd-cqrs-patterns/

A na potrzeby zaliczeniowe i tlumaczac lopatologicznie: napisz systemik skladajacy sie z 3 serwisow- jeden to aplikacja kliencka ktora bedzie wysylac polecenia (np. CreateCustomer). Kolejny serwis bedzie zajmowal sie obsluga polecen (zapisze klienta) i w wyniku przeprowadzych operacji tworzyl zdarzenia (np. CustomerCreated). Ostatni bedzie obslugiwal te zdarzenia (klient utworzony)- tutaj dane ze zdarzenia bedziesz zapisywal w formacie do odczytu.

Prostsza wersja powyzszego bedzie aplikacja bez podzialu na serwisy a jedynie logiczny podzial odpowiedzlanosci na projekty (czy odpowiedniki projektow z C#)- w tym przypadku mozna uzyc biblioteke zapewniajaca wzorzec mediator, np. MediatR dla .Net (https://github.com/jbogard/MediatR/wiki).


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

"Pattern Language Overview" to tytuł tej ilustracji, pochodzącej z książki Erica Evansa pt. "Domain-Driven Design Definitions and Pattern Summaries". Załączyłem ją tu, aby mojej wypowiedzi nadać kontekst, w którym ma ona sens.

Ja bym raczej powiedział, że to jest książeczka ;)

Jeśli mówisz o pobieraniu encji lub wartości za pomocą serwisu, to chyba masz na myśli serwis aplikacji, a to zupełnie coś innego niż serwis domenowy i nijak nie można ich porównać.

A to zależy, jakieś drobne wartości to aplikacyjny, jeśli potrzebujesz izolacji np na http to tak jak z repo interfejs w domenie a serwis w infrastrukturze.

DDD to również zestaw wzorców tzw. "taktycznych" - to są właśnie te nieszczęsne repozytoria, serwisy, agregaty i cała reszta. Wzorce te można jak najbardziej stosować bez "pełnego" DDD, większość z nich pozytywnie wpływa na czystość kodu.

Plus twoja intencja twórcza :)

somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:około 12 godzin
  • Lokalizacja:Wrocław
2
john_klamka napisał(a):

DDD to również zestaw wzorców tzw. "taktycznych" - to są właśnie te nieszczęsne repozytoria, serwisy, agregaty i cała reszta. Wzorce te można jak najbardziej stosować bez "pełnego" DDD, większość z nich pozytywnie wpływa na czystość kodu.

Aby móc nazwać klasę repozytorium musi ona zwracać ARy. Z ARami ciągną się encje i value objecty, itd., itp. To wszystko sprawia, że nie da się sensownie mówić o repozytoriach bez DDD.
Ale można mówić bezsensownie nazywając tak zwykłe crudowe DAO i mieć dzięki nim "niepełne DDD". I to chyba jest nieuleczalne.

EN
no, chyba nie jest, hahaha ;)
john_klamka
  • Rejestracja:prawie 9 lat
  • Ostatnio:prawie 5 lat
  • Postów:177
0

Oczywiście, że można mówić o repozytoriach nie w kontekście DDD, sam Evans proponuje stosowanie wzorców taktycznych, tam gdzie nie ma np. dostępu do ekspertów dziedziny i nie da się ustalić wszechobecnego języka.

edit:
A co do ARów, nigdzie Evans nie mówi, że repozytorium może zwracać tylko ARy, natomiast wyraźnie mówi, że repozytorium realizuje dostęp do encji.

edytowany 1x, ostatnio: john_klamka
EN
A niech sobie mówi... ;)
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Prostsza wersja powyzszego bedzie aplikacja bez podzialu na serwisy a jedynie logiczny podzial odpowiedzlanosci na projekty (czy odpowiedniki projektow z C#)- w tym przypadku mozna uzyc biblioteke zapewniajaca wzorzec mediator, np. MediatR dla .Net (https://github.com/jbogard/MediatR/wiki).

Możesz jakoś uzasadnić potrzebe używania mediatora dla comend w owym projekcie ? Jaką politykę ma nakładać i co ukrywać a przede wszystkim po co i dlaczego...?

jedynie logiczny podzial odpowiedzlanosci na projekty

A podział logiczny na odpowiedzialność pomiędzy obiektami bez podziału na projekty nie wystarczy ?

edytowany 1x, ostatnio: Enter Name
Aventus
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
2
[Enter Name napisał(a)]

Możesz jakoś uzasadnić potrzebe używania mediatora dla comend w owym projekcie ? Jaką politykę ma nakładać i co ukrywać a przede wszystkim po co i dlaczego...?

Rozumiem że pytasz tylko o komendy, nie eventy? Zakładając że za interakcje z klientem będzie odpowiadał jakiś kontroler (czy to MVC czy API) to jestem zwolennikiem wyraźnego podziału między kontrolerami a jakąkolwiek logika biznesową. Kontrolera powinno jedynie interesować wydanie polecenia (CreateClient, GetXDetails) i ewentualne zwrócenie wyniku do klienta. To co i jak wykonuje te operacje powinno być poza "wiedzą" kontrolera- wszelkie serwisy biznesowe również. Swoją drogą jest to praktyka promowana chociażby przez Scotta Allena.

A podział logiczny na odpowiedzialność pomiędzy obiektami bez podziału na projekty nie wystarczy ?

Może być, myślę jednak ze podział na projekty pozwala na wyrazniejsze rozdzielenie. No ale to już gusta i guściki...


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Rozumiem że pytasz tylko o komendy, nie eventy? Zakładając że za interakcje z klientem będzie odpowiadał jakiś kontroler (czy to MVC czy API) to jestem zwolennikiem wyraźnego podziału między kontrolerami a jakąkolwiek logika biznesową. Kontrolera powinno jedynie interesować wydanie polecenia (CreateClient, GetXDetails) i ewentualne zwrócenie wyniku do klienta. To co i jak wykonuje te operacje powinno być poza "wiedzą" kontrolera- wszelkie serwisy biznesowe również. Swoją drogą jest to praktyka promowana chociażby przez Scotta Allena.

Tak Buss dla eventów jest dla mnie jak najbardziej zrozumiała. W przypadku Query/Command. Nie widzę w tym najmniejszego sensu. Dlaczego jakiś kontroler ma nic nie wiedzieć o logice biznesowej, do której defakto się odnosi, jakie niby z tego benefity płyną?. Moim zdanie wystarczy izolacja na Domain Logic w postaci, Serwice Layer albo Application Layer z DDD. Przecież to kontroler ma wybierać z aplikacji to, co potrzebuje i przekazywać do View, a nie jakaś dodatkowa warstwa absrakcji, która w ogóle nie ma sensu w przypadku MVC.

Następne co jest bez sensu to pisanie do każdej komendy oddzielnej klasy na wzór programowania proceduralnego, bo akurat mediatorowi jest tak łatwiej się donieść po assembly do handlera.

A podział logiczny na odpowiedzialność pomiędzy obiektami bez podziału na projekty nie wystarczy ?

Może być, myślę jednak ze podział na projekty pozwala na wyrazniejsze rozdzielenie. No ale to już gusta i guściki...

Tak idąc twoim guścikiem to jak wygląda wtedy NameSpace do komendy ?

Kopiuj
CommandSide.ApplicationLogic.Commands.ProductCommand?
edytowany 1x, ostatnio: Enter Name
neves
  • Rejestracja:ponad 21 lat
  • Ostatnio:około godziny
  • Lokalizacja:Kraków
  • Postów:1114
1

Mediator użyty do rozprowadzania komend może się przydać do implementacji jakiś cross cutting concerns, jak np logowania jakie komendy są wywoływane. Ale jeśli nie mamy żadnych ccc to równie dobrze można się objeść bez mediatora i bezpośrednio wywoływać command handlery z poziomu kontrolerów, które jakby nie były są zwyczajnymi serwisami aplikacyjnymi tylko z inną nazwą ;)


Aventus
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
1
[Enter Name napisał(a)]

Tak Buss dla eventów jest dla mnie jak najbardziej zrozumiała. W przypadku Query/Command. Nie widzę w tym najmniejszego sensu. Dlaczego jakiś kontroler ma nic nie wiedzieć o logice biznesowej, do której defakto się odnosi, jakie niby z tego benefity płyną?. Moim zdanie wystarczy izolacja na Domain Logic w postaci, Serwice Layer albo Application Layer z DDD. Przecież to kontroler ma wybierać z aplikacji to, co potrzebuje i przekazywać do View, a nie jakaś dodatkowa warstwa absrakcji, która w ogóle nie ma sensu w przypadku MVC.

Nie, kontroler ma koordynowac modele i widoki, oraz pewne akcje. Benefity są bardzo proste - decoupling, odwrócenie i wstrzykiwanie zależności.

Następne co jest bez sensu to pisanie do każdej komendy oddzielnej klasy na wzór programowania proceduralnego, bo akurat mediatorowi jest tak łatwiej się donieść po assembly do handlera.

Nie ma w tym nic bezsensownego, kłania się single responsibility principle. W rezultacie metody kontrolera zostają odchudzone do 1-3 linii kodu.

Tak idąc twoim guścikiem to jak wygląda wtedy NameSpace do komendy ?

Kopiuj
CommandSide.ApplicationLogic.Commands.ProductCommand?

Nie wiem skąd taki dziwny pomysł. W ogóle nie rozumiem struktury tego namespace'a.

Ps: Daruj sobie uszczypliwosci, nie mam w zwyczaju prowadzić takich rozmów, szczególnie z anonimami w internecie. Jeśli nie możesz się powstrzymać i prowadzić normalnej rozmowy to soknczmy dyskusje. Moze kiedy zrozumiesz ze- tak jak sam napisales "twoje zdanie"- to tylko opinia, tak samo jak i moje zdanie, bedzie Ci latwiej.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Nie, kontroler ma koordynowac modele i widoki, oraz pewne akcje. Benefity są bardzo proste - decoupling, odwrócenie i wstrzykiwanie zależności.

Jakie wstrzykiwanie zależności czego, o czym ty w ogóle mówisz, jakie ty tam zależności wstrzykujesz mediator ? Odwrócenie zależności z warstwą prezentacji to najgłupszy pomysł, jaki może być. To jak byś chciał pisać warstwę prezentacji niezależną od logiki biznesowej zamiast logikę biznesową niezależną od prezentacji. Zdecyduj się albo w tą albo w tamtą.

Pisz, że po prostu nie wiesz, dlaczego to robisz, a nie strzelasz na oślep pojęciami, które nie rozumiesz.

Nie ma w tym nic bezsensownego, kłania się single responsibility principle. W rezultacie metody kontrolera zostają odchudzone do 1-3 linii kodu.

Co?. Acha, teraz rozumiem przedtem łamały SRP ? i musiałeś wprowadzić mediator, żeby już nie łamały. ;)

Nie wiem skąd taki dziwny pomysł. W ogóle nie rozumiem struktury tego namespace'a.

No to jak by wyglądał?

Aventus
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:UK
  • Postów:2235
2
Enter Name napisał(a):

Jakie wstrzykiwanie zależności czego, o czym ty w ogóle mówisz, jakie ty tam zależności wstrzykujesz mediator ?

Dokladnie tak, w dodatku- jest to jedyna zaleznosc wstrzykiwana do kontrolera i to jest piekne. Zadnych serwisow (no moze poza serwisem logowania)- te zostaja wstrzykniete do command handlerow. Jesli pytasz mnie "o czym ja w ogole mowie" to chyba nie wiesz co to Depedency Injection.

Odwrócenie zależności z warstwą prezentacji to najgłupszy pomysł, jaki może być. To jak byś chciał pisać warstwę prezentacji niezależną od logiki biznesowej zamiast logikę biznesową niezależną od prezentacji. Zdecyduj się albo w tą albo w tamtą.

Calkowicie wszystko pomieszales. Poza tym zarowno logika biznesowa powinna byc niezalezna od prezentacji jak i na odwrot. Takze decyduje- zarowno w ta jak i w tamta.

Pisz, że po prostu nie wiesz, dlaczego to robisz, a nie strzelasz na oślep pojęciami, które nie rozumiesz.

Tak, oczywiscie. Masz racje. (To ironia w razie jakbys w swoim gniewie tego nie zauwazyl)

Co?. Acha, teraz rozumiem przedtem łamały SRP ? i musiałeś wprowadzić mediator, żeby już nie łamały. ;)

Pisales o rozdzieleniu- oddzielna klasa dla kazdego polecenia. I w tym kontekscie sie odnioslem do SRP.

No to jak by wyglądał?

Dam standardowa odpowiedz w tej branzy- to zalezy. Mozna miec np. projekt posredni z samymi poleceniami (osobiscie jestem co do tego pomyslu sceptyczny), lub miec polecenia bezposrednio w projekcie wykonujacym logike, a wiec np. MyCompany.Domain.Commands. Swoja droga ApplicationLogic, ProductCommand itp. to sa wyjatkowo brzydkie nazwy, szczegolnie we wspominanym przez Ciebie kontekscie DDD.

Pójdź śladami Somekind, zadzwoń do Admina i powiedz, że jakiś anonim ci dokucza i do tego się wymądrza.

Nie, tak jak napisalem po prostu zakoncze te dyskusje. A jako ze robisz sie coraz bardziej agresywny to koncze ja wlasnie teraz. Pozdrawiam.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
edytowany 1x, ostatnio: Aventus
Zobacz pozostałe 14 komentarzy
flowCRANE
Bo przez takie dzieci „te forum” i polska ortografia kuleje. Idź się doinformuj, zamiast cwaniakować.
EN
furious programming. Jest zły, bo mu łopatkę do piasku zabrałem.
EN
To, takie typowe dla lamusów jak nie potrafią odpowiedzieć na post albo coś im nie pasuje do ich złotej teorii, to odwracają kota ogonem. Tłumacząc się tym, że pytający pytając, robi im krzywdę. Albo gdzieś tam napisał "te" zamiast "to".
EN
Co to za forum, jak tutaj nie można wyrażać swojej opinii, ani niczego się dowiedzieć. pfff....
EN
  • Rejestracja:prawie 7 lat
  • Ostatnio:prawie 7 lat
  • Postów:46
0

Calkowicie wszystko pomieszales. Poza tym zarowno logika biznesowa powinna byc niezalezna od prezentacji jak i na odwrot. Takze decyduje- zarowno w ta jak i w tamta.

W tym momencie twoja prezentacja jest zależna od Mediatora a mediator od serwisów czy handlerów, który tak czy siak jest też częścią logiki biznesowej. Mediator powinien nakładać jakąś politykę w stylu fasady, a nie być tylko listą handlerów. Jak potrzebujesz listę handlerów, to sobie zrób kolekcję z handlerami i sobie ją wstrzyknij tam, gdzie ci się podoba, ale po co ? A już wiem po to, żeby mieć jedną zależność do wstrzyknięcia. Przecież to jest takie zgodnie z SRP. Może zrób sobie ServiceLocatora co za różnica obydwa szukają serwisów po assembly.

Pisales o rozdzieleniu- oddzielna klasa dla kazdego polecenia. I w tym kontekscie sie odnioslem do SRP.

To zgodnie z SRP każda komenda ma mieć oddzielną klasę? No super....(bo tak jakiś selebryta powiedział na prezentacji). A może lepiej procedurę?

MyCompany.Domain.Commands

Trzymasz komendy w warstwie domenowej? A niby dlaczego tam ? Co one mają wspólnego z dziedziną?

Nie, tak jak napisalem po prostu zakoncze te dyskusje. A jako ze robisz sie coraz bardziej agresywny to koncze ja wlasnie teraz.

Już się nie gniewaj, kupie ci tort urodzinowy. Kiedy masz urodziny ?

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)