DDD - czy anemiczny model domeny jest antypatrakiem? Czy powinniśmy używać bogatych modeli domen? [Zamknięte]

11

Anemiczny model domeny był dawno krytykowany przez Evansa i Fowlera , ponieważ najwyraźniej jest sprzeczny z obiektowymi zasadami itp. Społeczność DDD jest wyraźnie zgodna z tymi stwierdzeniami.

Jednak w ostatnich latach pojawiły się głosy zaprzeczające twierdzeniu, że to wcale nie jest antypattern i że jest to przykład przestrzegania zasad SOLID.

Od tylu lat pracuję przy użyciu Spring Framework. Każdy projekt w każdej firmie zawsze miał warstwę usług zawierającą logikę biznesową, wykorzystującą repozytoria działające na modelach anemicznych (podmioty JPA). Co więcej, większość próbek, nawet oficjalnych od wiosennych facetów, pokazuje ten sposób pracy.

Moje pytania: czy anemiczny model domeny nadal jest uważany za antypattern? Czy wszyscy źle robiliśmy (w odniesieniu do DDD)? Czy nie uważasz, że posiadanie modeli Rich Domain narusza zasady SOLID?

współzależny
źródło
2
czy anemiczny model domeny jest nadal uważany za antypattern? ”. Przez niektórych tak. Inni, w tym ja, postrzegają to jako preferowany sposób pisania kodu przez większość czasu, ale jeśli RDM Ci odpowiada, użyj go. Głosujcie więc, aby zamknąć to jako oparte wyłącznie na opiniach.
David Arno
1
To byłoby fantastyczne pytanie na forum dyskusji / debaty; ale obecnie nie ma wiarygodnej odpowiedzi. Wolimy pytania, na które można odpowiedzieć, a nie tylko omówić.
VoiceOfUnreason

Odpowiedzi:

9

ADM jest dobrym wzorcem dla rozwiązania usług rozproszonych, takich jak mikrousługi. Pasuje do wielu współczesnych biznesowych przypadków internetowych.

Zastanów się, czy mamy obiekt Domeny zamówienia. Dzięki podejściu OOP dodalibyśmy Order.Purchase () Order.Cancel () itp. Działałoby to dobrze w aplikacji komputerowej, w której przechowujemy zamówienia w pamięci i robimy wiele rzeczy w tym samym wystąpieniu.

Ale jeśli mamy system rozproszony, z programami, które tylko do jednej rzeczy, tj. Uzyskują dostęp do listy zamówień i kupują je kolejno, lub uzyskują listę zamówień i anulują je kolejno, to posiadanie obu metod na tym samym obiekcie nie powoduje sens. Musielibyśmy mieć dwie Domeny lub Ograniczone Konteksty:

PurchaseSystemOrder.Purchase()

i

CancelSystemOrder.Cancel();

Jedyne, co te obiekty mogłyby dzielić, to struktura danych właściwości.

Gdy dodajesz coraz więcej mikrousług, powstaje dziesiątki rodzajów zamówień. To już nie ma sens mówić o na zamówienie jako obiektu domeny, choć jej tym samym porządku pojęciowego, który jest przetwarzany przez wszystkich tych systemów.

O wiele bardziej sensowne jest posiadanie modelu anemicznego, Order, który zawiera tylko dane i odpowiednio zmienia nazwę usług:

PurchaseService.Purchase(Order order)

Teraz możemy porozmawiać o Zamówieniu i możemy dodać dowolne nowe usługi, które wymyślimy, aby przetworzyć, bez wpływu na inne obecnie wdrażane usługi.

Fowler i Co wywodzą się z systemu monolitycznego, w ich świecie podejście ADM oznaczałoby pojedynczą aplikację z wszystkimi tymi oddzielnymi usługami utworzonymi w pamięci, a OrderDTO było przekazywane i mutowane. Byłoby to znacznie gorsze niż nałożenie metod na bogaty model Zakonu.

Ale w systemie rozproszonym istnieje wiele programów, z których każdy wymaga tylko jednej metody Zamówienia i uruchamia ją na wielu zamówieniach, ładując każdy z nich, uruchamiając metodę, a następnie odrzucając ją. Wymaga tylko jednej usługi i strumienia obiektów danych.

Pełne wypełnienie bogatego modelu, obawianie się o wymagania i zależności wszystkich Metod tylko wywołania jednego, a następnie niemal natychmiastowego odrzucenia obiektu jest bezcelowe.

Ponadto zmiana jednej z metod wymagałaby aktualizacji wszystkich komponentów rozproszonych, ponieważ wszystkie one zależą od modelu zaawansowanego pod względem logiki.

W mojej bazie danych nie ma miejsca na rzeczy, których nie potrzebują

Ewan
źródło
4
Odrzuciłem głos, ponieważ uważam, że DDD szczególnie dobrze nadaje się do mikrousług właśnie ze względu na ograniczoną koncepcję kontekstu. Myślę, że problem z twoją odpowiedzią polega na tym, że koncepcja i klasa zamówienia byłyby takie same dla każdej mikrousługi, ale myślę, że nie jest to ani konieczne, ani dokładne.
RibaldEddie
Nie zgadzam się, ADM może być DDD, jeśli zadzwonisz do usługi CashRegister w usłudze PurchaseService i włączysz ją do swojego języka domeny
Ewan
czy możesz rozwinąć? Zawsze myślałem, że YMMV, gdy ADM i DDD były w bazie kodowej SOLID J2EE lub .NET C # MVC EF.
RibaldEddie
Mam na myśli to, że ograniczony kontekst Zamówienie, PurchaseSystemOrder.Purchase () będzie prawie identycznym kodem jak CashRegister.Purchase (zamówienie zamówienia), to tylko zmiana nazwy w języku domeny. Bogaty model domeny oznacza posiadanie zarówno metod zakupu, jak i anulowania w tej samej klasie.
Ewan
1
@RibaldEddie, Zgodnie z grubością książki „javaScript, dobre części”, oferuję ten obraz jako ( niezupełnie poważny) argument przeciwko używaniu DDD do implementacji mikrousług;)
David Arno
3

SOLID i DDD są względem siebie ortogonalne, co oznacza, że ​​naprawdę idą w różnych kierunkach. Nie powinieneś mówić, że jeden jest przyzwyczajony do wykluczenia drugiego, ponieważ mogą i powinny istnieć razem w tej samej bazie kodu.

Anemiczne modele domen stają się anty-wzorcem dopiero wtedy, gdy domena problemowa ma wiele zachowań i masz setki metod usług z dużą ilością wklejonej logiki lub zależności, w których metody warstwy usługi muszą wywoływać inne metody warstwy usługi, aby cokolwiek zrobić.

DDD jest doskonałym paradygmatem dla mikrousług ze względu na koncepcję ograniczonego kontekstu .

Strzeż się pokusy, aby zobaczyć kod infrastruktury jako część domeny. Kod infrastruktury to wszystko, czego sam nie napisałeś, lub cokolwiek, co jest połączone z frameworkiem lub biblioteką, która współdziała z systemem innej firmy. Połączenia z bazami danych, mailery SMTP, biblioteki ORM, czasy działania serwera aplikacji, wszystko to jest infrastrukturą i nie powinieneś uwzględniać jej w swojej domenie, jeśli możesz tego uniknąć.

Zasady SOLID to zestaw ogólnych koncepcji OOP, których można użyć do ulepszenia kodu OOP. Korzystając z nich, możesz napisać dobrą bazę kodów DDD.

RibaldEddie
źródło
Odnośnie oddzielenia kodu infrastruktury od domeny. Do tej pory uważałem Podmioty JPA za moją domenę, mając następujące warstwy aplikacji: kontroler -> usługa -> repozytorium -> domena (Podmioty JPA). Jakie byłyby właściwe (lub jeden z właściwych) sposobów modelowania go według twojego punktu widzenia? Coś w stylu: kontroler -> model bogaty -> x? Jak i gdzie miałbym poradzić sobie z transakcyjnością? A co z mapowaniem JPA? Czy nie musielibyśmy powielać naszego bogatego modelu oddzielonymi jednostkami JPA?
współzależny
Podmiot JPA jest zwykłym starym obiektem Java. Mapowanie jest częścią infrastruktury, ale sama klasa nie musi tak być. Jeśli zdecydujesz się traktować go jako część infrastruktury, powinieneś rozważyć go jako obiekt transferu danych, który jest używany w Fabryce lub Repozytorium do utworzenia Podmiotu Domeny.
RibaldEddie
1

Bogata domena jest dobra, jeśli jest dobrze wykonana. Koszmar, kiedy nie. Domena anemiczna jest zawsze zła. Ale to znajomy wygodny rodzaj zła.

Jeśli domena anemiczna jest wszystkim, czego chcesz, wybrałeś niewłaściwy język, wybierając język ogólnego przeznaczenia. Języki czwartej generacji specjalizują się w konkretnym zastosowaniu. Jeśli anemia jest wystarczająco dobra, użycie ich ułatwiłoby ci życie.

Wiele platform wkrada się do przestrzeni językowej, dopóki nie będzie można reklamować pracy jako pracy java. To praca Java / Spring. To, co robią, oprócz uzależnienia cię od nich, polega na przekształceniu języka ogólnego w drańską formę języka 4. generacji.

Czy to najlepsza praktyka czy anty-wzór? Cóż, szefowi zależy tylko na tym, czy możesz zatrudnić ludzi do pracy na bazie kodu. Więc jeśli musimy udawać, że zatrudniamy ludzi, używamy języka ogólnego.

Jeśli nie masz nic przeciwko, to dobrze. Z pewnością nie jesteś jedyny.

Ale nie mów mi, że tak właśnie musi być. Nie mów mi, że robi dla mnie coś więcej niż jest. Wiem jak bez tego żyć. Wiem, jak to wypchnąć, więc zależy od tego tylko kilka rzeczy. Jeśli prosisz mnie, żebym się poddał i pozwolił przejąć wszystko tylko dlatego, że walka jest trudna, to tak, myślę, że to źle.

W mojej bazie kodu nie ma miejsca na rzeczy, których nie potrzebuje.

Jeśli chodzi o SOLID i inne zasady projektowania, mogę w dużej mierze przestrzegać tych, nawet w dziedzinie anemii. Nieprzestrzeganie ich powoduje inny rodzaj problemu.

candied_orange
źródło
Doceniam twoją odpowiedź i absolutnie zgadzam się, że niektóre frameworki, takie jak Spring lub JPA-Hibernate, podbiły krajobraz Java. Jednak jest również niezaprzeczalne, że dostarczyli wiele dobrych praktyk i uproszczeń, których Java (JEE) w ogóle nie rozwiązała lub zrobiła źle. Jestem bardzo entuzjastycznie nastawiony do DDD i chciałbym zrozumieć wszystkie zasady, które mówią. doświadczenie, jakie są najlepsze platformy / języki / frameworki do pracy z aplikacjami czysto DDD (z modelami Rich Domain)? Czy znasz dobrą próbkę Github? Jak mówisz, chcę robić rzeczy dobrze, a nie przestrzegać złych praktyk.
współzależny
Nie robimy tutaj rekomendacji zasobów. Uważam jednak, że odpowiednia warstwa infrastruktury, która zajmuje się frameworkami, oznacza, że ​​możesz używać dowolnego rodzaju. Po prostu traktuj je jak bibliotekę. Trzymaj wiedzę o nich poza domeną. Nie polegaj też na magii. Oprzyj się pokusie używania rzeczy, których sam nie potrafisz zrobić. Bo pewnego dnia może być konieczne.
candied_orange
Wracając do pierwotnego punktu. Co z zasadami SOLID? Modele z bogatą domeną przyjmują wiele obowiązków, trwałość (JPA), logikę biznesową (konieczność radzenia sobie z transakcyjnością) itp. Modele anemiczne natomiast dbają tylko o to, by trwałość miała rozdzielone usługi zajmujące się logiką biznesową. Brzmi również łatwiej testować. Co w tym takiego złego jest?
współzależny
Najważniejsze, abyś zaczął wybierać projekty w oparciu o potrzeby systemowe, a nie potrzeby semantyczne. Jest subtelny, łatwy do zignorowania, koszt nie jest oczywisty i trudny do uzasadnienia. Krótko mówiąc, to tak, jakby argumentować, że linie energetyczne powinny być pochowane, a nie w ankietach. Gdy ludzie przyzwyczają się do alternatywnej metody, nie będzie się to prawdopodobnie zmieniać. Nawet gdy huragany nokautują moc.
candied_orange
1
Chciałem dać ci przewagę nad twoim twierdzeniem, że „bogata domena jest dobra, gdy jest dobrze zrobiona. Koszmar, gdy nie jest”. Może po prostu nigdy nie widziałem, żeby robiło to dobrze, ale wtedy nonsensownie twierdzisz, że „Domena anemiczna jest zawsze zła”. Uprzejme bzdury czynią twoją odpowiedź bezwartościową. -1
David Arno