18

Martin Fowler uważa Anemic Domain Model za antystyk.Rich Domain Model i ORM

Trasowanie modelu trwałości jako modelu domeny również wydaje się zbyt poważne z powodu Object Relational Impedence Missmatch. W przypadku uporczywości i normalizacji, mamy tendencję do rozkładania klas na bardzo małe drobne kawałki, metody nakładania na te klasy są głupie. Poza tym uporczywość rzadko się zmienia, ale logika biznesowa zmienia się trochę.

Potrzebujemy zatem modelu DomainModel, który opiera się na modelu trwałości (zamiast być jednym i tym samym). Ten model domeny będzie zawierał właściwości i metodę logiki biznesowej.

Ale teraz te Modele Domen są nadal za usługą, a aby odsłonić je światu zewnętrznemu, musimy przekonwertować je na DTO.

Dokonujemy tego mapowania manny tutaj.

  1. Trwałość do domeny modelu
  2. Aby przekształcić model domeny w DTOs aby przejść między usługami

To nie koniec, ponieważ DTO konieczne może być odwzorowany w ViewModel.

Wszystko to i problem powielania logiki walidacji nadal nie znika, ponieważ klient chce walidacji w czasie rzeczywistym. ViewModel nie wie nic o walidacji, więc w SPA na przykład, jesteś zmuszony ponownie napisać logikę walidacji po stronie klienta (zazwyczaj w javascript).

Również usługi są z natury bezpaństwowe (wiadomość lub zorientowane na RPC), więc robimy wszystkie te mapowania, między trwałości, do OO, a następnie z powrotem do proceduralne, do jakiej korzyści? Jak uzasadniałbyś koszty w praktyce pod względem większości budżetów IT?

Dowiedziałem się, że posiadanie pełnego DDD, z Root Aggregate, Domain Models itp. Byłoby "fajne", ale jak można usprawiedliwić koszt i wydajność produkcji?

antywzorzec projektowy (lub antywzorzec projektowy) to wzór stosowany w społecznej lub gospodarczej operacje lub inżynierii oprogramowania, które mogą być powszechnie stosowane, ale jest nieskuteczne i/lub odwrotne w praktyce

A jeśli tak , czy DDD i Rich Domain Model nie pasowałyby do powyższej definicji wzoru antywłamaniowego niż "Lean" Modelu Domeny. Przepraszam, gardzę załadowanym słowem "Anemiczny".

Utrzymując model domeny, "Lean", zezwala się na to, aby można go było udostępniać bez naruszania "abstrakcyjnej zasady zależności", "nie powtarzaj się" oraz czasochłonnego, żmudnego i podatnego na błędy procesu mapowania jednego z danych przewoźnika do innego, i cokolwiek związanego z testem jednostkowym, który ma na to wpływ (chyba że myślisz o mapowaniu bez testów jednostkowych i masz nadzieję na najlepsze).

Odpowiedz

7

Wygląda na to, że miesza się wiele koncepcji, obwiniając podejście do modelu bogatej domeny za rzeczy, za które nie jest bezpośrednio odpowiedzialny.

  • bogaty model domeny jest prostopadła do warstwowej architekturze, zwłaszcza posiadające bogaty model domeny nie dyktować liczbę warstw masz, co dane struktury powinny być wymieniane pomiędzy tymi warstwami i jak powinny być one odwzorowane.

  • Model domeny Rich jest ortogonalny do walidacji i nie mówi nic o potrzebie sprawdzania po stronie klienta oprócz sprawdzania poprawności back-end.

Innymi słowy, dzięki czemu model domeny z niedokrwistością wszelkiej logice biznesowej w sektorze usług nie musi zaoszczędzić od pisania dużo boilerplate DTO kod mapowania, ani nie usunie potrzebę stronie klienta „podwójnym sprawdzanie "(co jest przy okazji powszechnie przyjętą najlepszą praktyką).

Nie oznacza to, że twój punkt widzenia na temat kosztów i wagi w pełni rozwiniętej architektury wielowarstwowej jest nieważny. Możesz zainteresować się tym postem przez Marka Seemanna, omawiając podobne problemy: http://blog.ploeh.dk/2012/02/09/IsLayeringWorthTheMapping.aspx

+0

Myślę, że artykuł, który łączysz, podsumowuje dylemat. Tyle tylko, że nie wierzę w wysyłanie Modelu Domeny przez sieć, co wydaje się być zadaniem DTO. Nie ma sensu zachowanie się na DTO i wystawianie go na działanie klienta. Tak więc dla mnie architektura jest "wykonalna" z kolejną warstwą abstrakcji i mapowania oprócz 3 wspomnianych. A to jest dużo mapowania! Nie oznacza to, że jest inny sposób na wprowadzenie zagadnień związanych z UI do domeny w celu ponownego użycia. Myślę, że istnieje "szczęśliwe" medium pomiędzy dwoma ekstremami pololowymi. – Alwyn

+0

"Przesuwaj mniej danych, a rzeczy mogą stać się prostsze" - Jego własny wniosek na końcu artykułu, który brzmi dla mnie jak Lean Model. – Alwyn

+0

"Nie ma sensu zachowanie się w DTO i pokazywanie tego klientowi" - teraz rozumiem związek, jaki robisz między bogatym/anemicznym modelem domeny a warstwami. Czy sugerujesz, że obiekty domeny powinny być pozbawione tak dużej logiki biznesowej, jak to tylko możliwe, aby wysyłać je bezpośrednio do warstwy interfejsu użytkownika bez potrzeby używania DTO? Czy jest to coś innego, co określasz jako "Lean Model"? – guillaume31

2

Po pierwsze, nie sądzę, że można naprawdę łatwo uciec od powielania logiki walidacji na kliencie i na serwerze. Nie ogranicza się to jednak do DDD. Istnieją pewne mechanizmy łagodzące ból, ale zawsze będzie potrzebny wysiłek.

Druga część jest cała ta firma mapping :)

Co robisz jest skutecznie wykonywać za pomocą czyta. Być może myślisz, że musisz przeczytać swój byt, aby go edytować. Jest to prawdą, jeśli wykonujesz operacje oparte na encji (obiekt prawdopodobnie więcej tutaj w kategoriach DB - cały rekord) zamiast operacji opartych na zadaniach na obiekcie encji. Głupi przykład może polegać na tym, że klient dzwoni do centrum telefonicznego pod numer, zmieniając adres. Operator wywołuje rekord klienta i edytuje adres. Jest to oparte na jednostkach i prowadzi do typowych problemów w.r.t. współbieżność, ponieważ 2 akcje mogą być wykonywane na tym samym rekordzie (jednak mało prawdopodobne). Jest to bardzo tradycyjne podejście do projektowania UX: "Edytuj rekord".

Należy to porównać z przyciskiem na ekranie, który mówi: "zmienić adres". Zmieniasz tylko adres na płycie i chociaż wydaje się, że to jest to samo, to jest zupełnie inaczej. Szanse na 2 operacje, które zmieniają ten sam adres, są raczej mniejsze niż zmiana tego samego rekordu. W razie potrzeby można przeprowadzić sprawdzanie współbieżności w tej części.

Teraz, jeśli ktoś nie odczytuje domeny, co by się przeczytało. Skąd pochodzą dane. W tym miejscu pojawia się CQRS (Segregacja odpowiedzialności za polecenia/zapytania). W przeszłości został on zdezorientowany/połączony z funkcją Event Sourcing, ale nie jest to wymagane. Możesz stworzyć prostą stronę zapytań do aplikacji, która skupi się na zwrocie potrzebnych danych. W języku C# użyłem DataRow, jeśli jest to pojedyncza instancja, DataTable dla wielu wystąpień i niestandardowe DTO dla czegoś bardziej złożonego. Może istnieć sposób, w jaki można uciec nawet anonimowym typom (jeszcze tego nie zbadano).

Dlatego:

Domain Model = operacje/Obliczenia/zapisu Query Services = odczyt

Istnieje sytuacja, gdzie można uciec po prostu ładowanie podmiotu/kruszywo takie jak w aplikacji internetowej, ponieważ jest świadomy (lub może być świadomy) twojego modelu domeny, ale inteligentny klient byłby nieco anty-wzorem.

Uzasadnienie jest dość trudne, ale sprowadza się do konserwacji. Jeśli Twoje podejście nie zmniejsza Twojego obciążenia konserwacyjnego, istnieje ryzyko, że coś nie zostanie prawidłowo zastosowane i wymaga refaktoryzacji.

DDD to nie tylko techniczna implementacja, ale to idzie daleko, pchając w kierunku właściwego modelowania OO. Sądzę, że inne pomysły są dodawane do oprogramowania, więc oprogramowanie wydaje się być celem. Wszyscy chcemy zobaczyć, gdzie guma spotyka się z drogą.

Podobnie jak większość rzeczy DDD można zrobić źle :)

4

tl; dr Model domeny nie jest dobrze zdefiniowana, to prawdopodobnie zaprojektowany z db centric podejścia w umyśle.

Głównym celem DDD jest modelowanie w kodach koncepcji i procesów biznesowych. Naprawdę wątpię, że twoje koncepcje i procesy biznesowe to tylko worki nieruchomości. Ale jeśli tak naprawdę to tak, model domeny może być taki sam jak model trwałości, więc nie musisz wykonywać żadnego mapowania.

Model trwałości modeluje przechowywanie stanu obiektu . Jeśli nie jesteś w domenie baz danych, model domeny i trwałości nie może mieć tego samego celu.Jednym z największych błędów, które widzę w DDD, jest myślenie o modelu domenowym, tak jak to jest nadal napędzane danymi. W DDD nie masz konkretnej bazy danych. Masz repozytoria. Nie ma relacji jeden-do-wielu, wielu-do-wielu itd. Brak tabel i wierszy. Istnieją tylko obiekty, które starają się reprezentować domenę tak dokładnie, jak to możliwe.

Po prostu, Domain dba o modelowanie zachowań biznesowych, podczas gdy Persistence dba o przechowywanie stanu obiektu. Widzę tutaj dwa różne obowiązki.

Informacje o walidacji obejmują 2 typy: sprawdzanie poprawności danych wejściowych w formacie, a następnie sprawdzanie poprawności innych reguł biznesowych zgodnie z tym, co zmieniło się w stanie obiektu.

O duplikacji, myślę, że odnosisz się do formatu wejściowego, ale jak @EbenRoux powiedział, że istnieje mechanizm, który może pomóc w tym. W asp.net mvc większość tych reguł sprawdzania poprawności zawiera również wersję js.

Pozwól, że zdradzę ci mały sekret z usługami. Podczas gdy ich interfejs można zdefiniować w domenie, ich implementacja może zostać umieszczona w warstwie trwałości, umożliwiając im bezpośrednią pracę z pamięcią masową. A ponieważ reszta aplikacji korzysta z usługi w ich abstrakcyjnej formie (interfejs), tylko pojemnik DI będzie znać brudny sekret.

DDD nie mówi o byciu cool, chodzi o projektowanie aplikacji zgodnie z domeną. Założę się, że niewielu tworzy aplikację wyłącznie w celu bycia interfejsem dla bazy danych. Większość ma na celu dostarczenie usługi za pomocą swojego oprogramowania, aby stworzyć wirtualny produkt, który rozwiązuje problem. To ma sens, aby zaprojektować aplikację, która ma być rozwiązaniem problemu, który chcesz rozwiązać, a nie przez narzędzia techniczne, których właśnie używasz.

Jak to brzmi, chcesz dom murowany, ale konstruktor mówi: "Przepraszam, ale moja piła działa tylko z drewnem". Cóż, nie używaj piły, użyj innego narzędzia, które pomoże ci wyciąć cegłę. Narzędzia muszą być dostosowane do problemu, a nie odwrotnie.

+0

Domena w DDD jest zatem stanowa lub bezpaństwowa? Czy domena powinna ujawnić swoje właściwości? Gdyby nie to, co byłoby typem i typem zwrotu metod Domeny ?, DTO? Jeśli eksponuje swoje właściwości, jak to jest lepsze niż Anemiczny Model? – Alwyn

+0

Domena to przede wszystkim zachowanie.Oczywiście obiekt domeny może mieć właściwości, ale nie ma tylko właściwości. A te właściwości to nie tylko prymitywy. Jak zapisać IFormattedContent bezpośrednio w kolumnie? Zaczynam myśleć, że twoja obecna domena to tylko zbiór kodu proceduralnego opartego na danych, który po prostu używa terminów DDD. – MikeSW

+0

@Alwyn część domeny jest stanowa - to właśnie celem Jednostek jest posiadanie stanu, a także tożsamości, abyśmy mogli śledzić zmiany w tym stanie. Obiekty wartości z drugiej strony nie są stanowe (stan zamrożony, jeśli chcesz). Usługi domenowe powinny być wyraźnie bezpaństwowcami. – guillaume31