Programy obsługi poleceń i DDD

11

Mam aplikację ASP.NET MVC, która korzysta z usługi zapytań w celu uzyskania danych oraz usługi poleceń do wysyłania poleceń. Moje pytanie dotyczy części dowodzenia.

Jeśli nadejdzie żądanie, usługa komend używa dyspozytora poleceń, który przekieruje polecenie do wyznaczonego modułu obsługi poleceń. Ten moduł obsługi poleceń najpierw sprawdza poprawność polecenia, a jeśli wszystko jest dopuszczalne, wykonuje polecenie.

Konkretny przykład: AddCommentToArticleCommandHandler otrzymuje AddCommentToArticleCommand, który ma ArticleId, CommentText i EmailAddress.

Pierwszy; weryfikacja musi nastąpić, na przykład: - sprawdź, czy artykuł istnieje - sprawdź, czy artykuł nie jest zamknięty - sprawdź, czy tekst komentarza jest wypełniony i ma od 20 do 500 znaków - sprawdź, czy adres e-mail jest wypełniony i czy ma prawidłowy format.

Zastanawiam się, gdzie umieścić tę weryfikację?

1 / w samym module obsługi poleceń. Ale potem nie można go ponownie użyć w innych programach obsługi poleceń.

2 / w podmiocie domeny. Ale ponieważ jednostka domeny nie wie o repozytoriach lub usługach, nie może przeprowadzić wymaganej weryfikacji (nie może sprawdzić, czy artykuł istnieje). Ale z drugiej strony, jeśli jednostka nie zawiera logiki, staje się prostym kontenerem danych, który nie jest zgodny z zasadami DDD.

3 / moduł obsługi poleceń używa walidatorów, dzięki czemu sprawdzanie poprawności może być ponownie wykorzystane w innych modułach obsługi poleceń.

4 / Inne mechanizmy?

Szukam łańcucha odpowiedzialności za ten konkretny przykład i jakie obiekty (byty, repozytoria, ...) odgrywają w nim rolę.

Czy masz pomysły na to, jak to zaimplementować, poczynając od modułu obsługi poleceń aż po repozytoria?

L-Four
źródło
„Ale ponieważ jednostka domeny nie wie o repozytoriach lub usługach, nie może przeprowadzić wymaganej weryfikacji”? Dlaczego nie? Jaka zasada DDD tego wymaga?
S.Lott,
Wszędzie czytam, że jednostka nie powinna wiedzieć o repozytoriach ani niczym innym.
L-Four
Czy możesz podać wycenę, link lub przykład tego, co - konkretnie - przeczytałeś? Nie wiemy, jakie opisy DDD czytasz.
S.Lott,
Jimmy Bogard podzielił się niektórymi opiniami na ten temat ... lostechies.com/jimmybogard/2009/02/15/validation-in-a-ddd-world
Mayo

Odpowiedzi:

4

Myślę, że w tym przypadku musisz oddzielić dwa typy walidacji; walidacja domeny i walidacja aplikacji .

Sprawdzanie poprawności aplikacji polega na sprawdzeniu, czy właściwość polecenia „tekst” ma od 20 do 200 znaków; więc sprawdzasz to za pomocą GUI i sprawdzania poprawności modelu widoku, które również wykonuje się na serwerze po POST. To samo dotyczy wiadomości e-mail (przy okazji, mam nadzieję, że zdajesz sobie sprawę, że wiadomość taka jak `32.d +„ Hello World .42 ”@ mindomän.local” jest poprawna zgodnie z RFC).

Następnie masz kolejną weryfikację; sprawdź, czy artykuł istnieje - musisz zadać sobie pytanie, dlaczego artykuł nie powinien istnieć, jeśli rzeczywiście jest wysłane polecenie z GUI, które dotyczy dołączenia komentarza do niego. Czy twój GUI był w końcu spójny i masz zagregowany katalog główny, artykuł, który można fizycznie usunąć ze składnicy danych? W takim przypadku wystarczy przenieść polecenie do kolejki błędów, ponieważ program obsługi poleceń nie ładuje zagregowanego katalogu głównego.

W powyższym przypadku dysponujesz infrastrukturą, która obsługuje wiadomości o zatruciach - na przykład ponawiają próbę 1-5 razy, a następnie przenoszą ją do kolejki, w której można ręcznie sprawdzić zbiór wiadomości i ponownie wysłać odpowiednie. Dobrze jest monitorować.

Więc teraz omówiliśmy:

  • Sprawdzanie poprawności aplikacji

    • Z javascript w GUI
    • Z walidacją MVC na serwerze internetowym
  • Brak zagregowanych korzeni + kolejki zatruć

Co z poleceniami, które nie są zsynchronizowane z domeną? Być może masz logikę domeny mówiącą, że po 5 komentarzach do artykułu dozwolone są tylko komentarze poniżej 400 znaków, ale jeden facet spóźnił się z piątym komentarzem i musiał być szósty - GUI go nie złapał, ponieważ nie było to zgodne z domeną w momencie wysłania polecenia - w tym przypadku masz „błąd sprawdzania poprawności” jako element logiki domeny i zwracasz odpowiednie zdarzenie awarii.

Zdarzenie może mieć formę wiadomości wysłanej do brokera wiadomości lub niestandardowego programu rozsyłającego. Serwer WWW, jeśli aplikacja jest monolityczna, może synchronicznie nasłuchiwać zarówno zdarzenia pomyślnego, jak i wspomnianego zdarzenia awarii i wyświetlać odpowiedni widok / częściowy.

Często masz niestandardowe zdarzenie, które oznacza niepowodzenie dla wielu rodzajów poleceń, i to jest to zdarzenie, które subskrybujesz z perspektywy serwera WWW.

W systemie, nad którym pracujemy, wykonujemy żądanie-odpowiedź za pomocą poleceń / zdarzeń za pośrednictwem magistrali komunikatów + brokera MassTransit + RabbitMQ i mamy zdarzenie w tej konkretnej domenie (częściowo modelujące przepływ pracy) o nazwie InvalidStateTransitionError. Większość poleceń, które próbują poruszać się wzdłuż krawędzi na wykresie stanu, może spowodować to zdarzenie. W naszym przypadku modelujemy interfejs GUI zgodnie z ostatecznie spójnym paradygmatem, więc wysyłamy użytkownika na stronę „polecenia zaakceptowanego”, a następnie pozwalamy pasywnie aktualizować widoki serwera WWW poprzez subskrypcje zdarzeń. Należy wspomnieć, że zajmujemy się także pozyskiwaniem zdarzeń w zagregowanych korzeniach (i będziemy także robić sagi).

Widzisz więc, wiele z walidacji, o których mówisz, to w rzeczywistości walidacje typu aplikacji, a nie rzeczywista logika domeny. Nie ma problemu z posiadaniem prostego modelu domeny, jeśli twoja domena jest prosta, ale robisz DDD. Jednak w miarę modelowania domeny odkryjesz, że domena może nie być tak prosta, jak się początkowo okazało. W wielu przypadkach zagregowany katalog główny / jednostka może po prostu zaakceptować wywołanie metody spowodowane przez komendę i zmienić niektóre jej stany bez przeprowadzania żadnej weryfikacji - szczególnie jeśli ufasz komendom tak, jak robisz to, jeśli sprawdzasz je na serwerze WWW, który kontrolujesz.

Mogę polecić obejrzenie dwóch prezentacji na DDD z Norwegian Developer Conference 2011, a także prezentacji Grega na Öredev 2010 .

Na zdrowie, Henke

Henrik
źródło
Dzięki! Jedna rzecz na temat sprawdzania poprawności: w tej chwili sprawdzanie poprawności jest uruchamiane przez interfejs użytkownika (poprzez wysłanie do usługi żądania sprawdzania poprawności (polecenia)), który korzysta z walidacji () samej jednostki komentarza. Następnie, jeśli polecenie jest prawidłowe, klient wydaje polecenie Wykonaj, które ponownie wykona polecenie Validate (), aby upewnić się, a jeśli jest prawidłowe, polecenie zostanie wykonane. Tak więc główna weryfikacja jest wykonywana przez jednostkę Komentarz, ponieważ w każdym kontekście weryfikacja będzie taka sama (e-mail zawsze musi być prawidłowy, tekst komentarza nie jest zbyt długi itp.) Czy to dobre podejście?
L-Four
Walidacja, którą wydajesz się opisywać, nie wydaje mi się uzasadniać modelowania jej za pomocą 2-fazowego protokołu sprawdzania poprawności - oczywiście sprawdź parametry wywołania metody na obiekcie, tak jak byś testował w teście jednostkowym, ale poza tym; warstwa aplikacji / GUI może łatwo zweryfikować opisane reguły bez wysyłania poleceń do domeny. Imo Jeśli klient nie jest złośliwy, polecenie powinno wtedy działać. Jeśli klient jest złośliwy, polecenie nie powiedzie się, a model odczytu nigdy nie otrzyma odpowiedniego zdarzenia i można sprawdzić problematyczne polecenie w kolejce błędów.
Henrik,
W interfejsie użytkownika (ASP.NET MVC) używam atrybutów sprawdzania poprawności do przeprowadzenia wszystkich sprawdzeń poprawności. Więc jeśli ta weryfikacja się powiedzie, nie muszę wtedy ponownie sprawdzać poprawności w domenie, ale po prostu wykonać polecenie?
L-Four,
1
Tak, wykonujesz polecenie, ale upewnij się, że nie jest ono nieprawidłowe zarówno w warstwie aplikacji, jak i w domenie.
Henrik
0

EDYCJA: WaybackMachine link: http://devlicio.us/blogs/billy_mccafferty/archive/2009/02/17/a-response-to-validation-in-a-ddd-world.aspx

Nie ma odpowiedzi.

Istnieją dwa jasne scenariusze projektu, które przychodzą mi na myśl, gdy próbuję odpowiedzieć, gdzie powinna istnieć weryfikacja. Pierwszy polega na tym, że warstwa DTO służy do przesyłania informacji między warstwami widoku i warstwami domenowymi. Na przykład możesz mieć obiekt klienta w warstwie domeny i powiązany klient DTO w innej warstwie, do której mapujesz informacje o kliencie, aby następnie dać widok prezentacji informacji o kliencie użytkownikowi.

Drugi scenariusz to projekt, w którym podmioty w obrębie warstwy domeny są udostępniane bezpośrednio w celu przedstawienia danych użytkownikowi. Na przykład zamiast utrzymywania oddzielnej warstwy DTO i odwzorowywania obiektu domeny na DTO, które mają zostać przekazane do widoku, widok może otrzymać obiekt klienta bezpośrednio. Zamiast rozmawiać przez osobno utrzymywane DTO w celu pokazania nazwy klienta, widok po prostu poprosi sam obiekt klienta o informacje.

S.Lott
źródło