DDD z ORM, gdzie powinna iść logika biznesowa?

10

W przeszłości korzystałem z narzędzia MDA (architektura oparta na modelu), w którym modelowaliśmy za pomocą UML i generowało to między innymi jednostki biznesowe (nasz model domeny) i ORM (mapowanie itp.).

Wiele kodu biznesowego i usług działających w domenie było częścią modelu, a nasze repozytoria zwracały podmioty gospodarcze (więc nie byłoby możliwe przejście na inną ORM (nie to, że chcieliśmy)).

Jednak teraz zaczynam projekt i chcę myśleć w kategoriach DDD.

Jak dotąd wydaje mi się, że umieszczam logikę biznesową w moim modelu domeny i za pośrednictwem repozytoriów współpracuję z ORM (który kiedykolwiek wybrałem). Jeśli jednak chciałbym nadal korzystać z narzędzia MDA dla części ORM aplikacji, utworzony tutaj model byłby bardzo anemiczny (tj. Nie zawierałby żadnej logiki biznesowej). Podobnie, jeśli użyłem frameworku Entity (.net) lub NHibernate dla mojej ORM, byłby to również model anemiczny. Nie jestem pewien, gdzie postawisz logikę biznesową, gdybym tylko użył NHibernate.

Czy mam rację, myśląc w ten sposób, innymi słowy w DDD całą logikę biznesową w domenie i po prostu używam ORM do utrwalania za pośrednictwem repozytoriów?

JD01
źródło

Odpowiedzi:

12

więc nie byłoby możliwe przejście na inną ORM (nie to, że chcieliśmy)).

To wydaje się złe. Główną zaletą wzorca repozytorium jest ukrywanie logiki dostępu do danych i łatwość wymiany.

Jak dotąd wydaje mi się, że umieszczam logikę biznesową w moim modelu domeny i za pośrednictwem repozytoriów współpracuję z ORM (który kiedykolwiek wybrałem). Jeśli jednak chciałbym nadal korzystać z narzędzia MDA dla części ORM aplikacji, utworzony tutaj model byłby bardzo anemiczny (tj. Nie zawierałby żadnej logiki biznesowej). Podobnie, jeśli użyłem frameworku Entity (.net) lub NHibernate dla mojej ORM, byłby to również model anemiczny. Nie jestem pewien, gdzie postawisz logikę biznesową, gdybym tylko użył NHibernate.

Anemiczny model domeny jest uważany przez wielu za złą praktykę, na przykład Martin Fowler. Należy unikać takiego projektu, ponieważ taki model prowadzi raczej do procedur projektowania proceduralnego niż do dobrego projektowania obiektowego. Następnie masz klasy danych i klasy menedżera / przetwarzania, co oznacza, że ​​rozdzieliłeś stan i zachowanie. Ale przedmiotem naprawdę powinien być „stan i zachowanie”.

NHibernate wykonuje świetną robotę w uporczywej ignorancji. Możesz ukryć szczegóły mapowania w XML lub w FluentNHibernate i po prostu napisać zwykłe POCO. Stworzenie bogatego modelu domeny za pomocą NHibernate jest bardzo łatwe. Myślę, że możesz to zrobić za pomocą frameworku encji i narzędzia MDA. Tak długo, jak to narzędzie tworzy częściowe klasy, można dość łatwo rozszerzyć wygenerowany kod bez obawy, że nowa generacja może zniszczyć kod napisany przez użytkownika.

Krótko mówiąc, ta długa historia. Kiedy używasz NHibernate, nic, powtarzam nic , nie powstrzymuje cię przed przyjęciem bogatego modelu domeny. Polecam używać go z FluentNHibernate i mapowania ręcznie. Kod mapowania zajmuje tylko 5–10 minut. Przypuszczam, że to samo dotyczy frameworku encji i że jego narzędzia przynajmniej tworzą klasy cząstkowe, które można łatwo rozszerzyć.

Czy mam rację, myśląc w ten sposób, innymi słowy w DDD całą logikę biznesową w domenie i po prostu używam ORM do utrwalania za pośrednictwem repozytoriów?

W większości masz rację. Powinieneś mieć bogaty model domeny. Zwłaszcza, gdy sprawy stają się coraz bardziej złożone, łatwiej jest je utrzymać i rozszerzyć, jeśli odpowiednio je zaprojektujesz. Pamiętaj jednak, że DDD zna również (Warstwa Domeny i Warstwa Aplikacji) Usługi do implementacji logiki biznesowej oraz Fabryki do enkapsulacji logiki kreacyjnej.

Staram się również różnicować logikę biznesową na logikę domeny i logikę biznesową aplikacji. Logika domeny to sposób, w jaki domena współdziała i zachowuje się, podczas gdy logika aplikacji, która jest zupełnie inną warstwą, opisuje, w jaki sposób domena jest używana dla konkretnego przypadku użycia / aplikacji. Często muszę aktualizować model domeny, aby obsługiwał określone przypadki użycia i aby był bardziej wydajny.

Sokół
źródło
2
+1: Oddzielam także warstwę logiki domeny od warstwy logiki aplikacji. Umieszczam wszystkie ORM i bazy danych w warstwie logiki domeny. Warstwa logiki aplikacji nie wie nic o ORM, transakcjach i tym podobnych: widzi tylko klasy logiki biznesowej i wywołuje ich metody. Uważam, że to podejście jest bardzo skuteczne, ponieważ ma prostszą i czystszą warstwę logiki aplikacji.
Giorgio
@Falcon: Dzięki za informację. Kiedy wspomniałem o modelu anemicznym, miałem na myśli to, że jeśli utworzę domenę przy użyciu DDD, jedna wersja moich repozytoriów byłaby prawdopodobnie wersją mda, w której po prostu przenosiłbym moje jednostki do jednostek mda (tj. Model anemiczny), a następnie je utrwalałam w transakcjach itp. Czy byłoby to w porządku? Wątpię, czy użyję narzędzia MDA, ale po prostu próbuję zrozumieć, jak mógłbym, gdybym chciał. Czy to brzmi dobrze?
JD01,
@ JD01: Nie do końca cię rozumiem, ale wygląda na to, że chcesz przekształcić jednostki modelu domeny, abyś mógł je łatwo utrwalić. To prawie tak, jak używanie DTO i automapper (google it) może być przydatnym narzędziem do takiego zadania. Takie podejście niekoniecznie koliduje z najlepszymi praktykami DDD. W końcu repozytoria mają również ukrywać logikę dostępu do danych. Możesz po prostu przekształcić obiekty biznesowe za kulisami w MDA DTO, a następnie utrwalić je, a użytkownik interfejsu API nawet tego nie zauważy. Myślę, że to w porządku.
Falcon,
1
@ JD01: Proponuję rzucić okiem na poniższy link, aby zobaczyć, ilu ludzi robi to z javą Enterprise. Zasadniczo mają DAO, DTO i BO (obiekt biznesowy). Dla mnie to zbyt wiele warstw, ale projekt jest w porządku. java.sun.com/blueprints/corej2eepatterns/Patterns/…
Falcon
@ Falcon: Tak, myślałem zgodnie z wytycznymi DTO będącymi moimi obiektami MDA, a nie, że pójdę tą drogą. Właśnie chwytam się tego, co każda część graczy DDD d0. Jeszcze raz dziękuję.
JD01,
3

Jeśli jednak chciałbym nadal korzystać z narzędzia MDA dla części ORM aplikacji, utworzony tutaj model byłby bardzo anemiczny (tj. Nie zawierałby żadnej logiki biznesowej).

Nie wiem, z którego narzędzia MDA korzystasz, ale te, z którymi pracowałem, zawsze tworzą klasy cząstkowe, więc możesz je uzupełnić dowolną logiką biznesową.

Jednak wydaje mi się, że narzędzia MDA są nieco mniej odpowiednie w kontekście DDD niż ORM, ponieważ generowanie kodu często ma tendencję do tworzenia klas, w których występują szumy specyficzne dla narzędzi zamiast usprawnionych, wyraźnie wyrażonych jednostek domeny, których oczekujemy. W rzeczywistości często otrzymujesz połączenie danych domeny, logiki trwałości, logiki sprawdzania poprawności ograniczeń ... i nie wiem, czy istnieje sposób na rozdzielenie tych problemów za pomocą większości narzędzi MDA.

Oczywiście nie można dotknąć wygenerowanego kodu inaczej niż poprzez klasy częściowe, co oznacza, że ​​nie można wyeliminować potencjalnego zachowania anty-DDD, które byłoby zintegrowane. Jest to problematyczne w podejściu, w którym chcesz egzekwować ścisłe bariery między agregatami i perfekcyjnie dopasowywać relacje między swoimi bytami. Czas kompilacji w środowisku ciągłej integracji może również ucierpieć z powodu dodatkowego etapu generowania kodu.

Poza tym myślę, że Falcon prawie wszystko powiedział - absolutnie nic w narzędziach ORM lub MDA nie uniemożliwia posiadania bogatych jednostek domeny.

guillaume31
źródło
Cześć, używam ECO (podstawowych obiektów przedsiębiorstwa) ze zdolnego obiektu.com i jest dokładnie tak, jak to opisałeś.
JD01,
1

W moim zespole robię modelowanie mojego obiektu, domeny i dodawanie logiki biznesowej w tym samym czasie. Nie korzystam z Model Driven Development, który generowałby kod z modelu, ale wolę podejście adnotacyjne. Mam na myśli to, że na poziomie obiektu wewnątrz schematu klasowego dodaję stereotypy ORM. Spowoduje to dodanie adnotacji trwałości bezpośrednio w kodzie, które są zgodne z EJB3 / hibernacją. Tworzenie bazy danych odbywa się przez Hibernację, a na pewno nie przez szablony UML. Jest to o wiele lepsze, ponieważ jeśli kod się zmieni i dodane adnotacje nie są dokładnie tym, co specjalista od hibernacji, to może go zmienić, ale model jest nadal dobry. Mogę również zmienić swoje wymagania, a mój model domeny nadal działa.

Programiści mogą dodawać logikę biznesową do każdej metody i dodawać komentarz, mogę również modelować i dodawać ograniczenia. Na przykład sprzedaż powinna przekraczać 50 tys., Jeśli nie itd. Nie muszę go kodować, ale po prostu wpisuję w modelu, a ta informacja będzie widoczna dla zespołu programistów. Naprawdę fajny i elastyczny UML.

UML_GURU
źródło