Z tymi wszystkimi usługami, jak mogę nie być anemiczny?

90

Gdzie wyznaczamy granicę między delegowaniem a enkapsulacją logiki biznesowej? Wydaje mi się, że im więcej delegujemy, tym bardziej stajemy się anemiczni . Delegacja promuje jednak również ponowne użycie i zasadę SUCHEGO. Co zatem należy przekazać i co powinno pozostać w naszych modelach domen?

Weź jako przykład następujące obawy:

Autoryzacja . Czy obiekt domeny powinien być odpowiedzialny za utrzymanie swoich reguł kontroli dostępu (takich jak właściwość CanEdit), czy powinien być delegowany do innego komponentu / usługi odpowiedzialnej wyłącznie za zarządzanie dostępem, np. IAuthorizationService.CanEdit (obiekt)? A może powinna to być kombinacja tych dwóch? Być może obiekt domeny ma właściwość CanEdit, która deleguje do wewnętrznej IAuthorizationService, aby wykonać rzeczywistą pracę?

Validation . Ta sama dyskusja jak powyżej dotyczy walidacji. Kto przestrzega zasad i kto jest odpowiedzialny za ich ocenę? Z jednej strony stan obiektu powinien należeć do tego obiektu, a ważność jest stanem, ale nie chcemy przepisywać kodu używanego do oceny reguł dla każdego obiektu domeny. My mogli używać dziedziczenia w tym przypadku ...

Tworzenie obiektów . Klasa fabryczna a metody fabryczne kontra „nowe” wystąpienie. Jeśli użyjemy oddzielnej klasy fabryki, jesteśmy w stanie izolować i hermetyzować logikę tworzenia, ale kosztem otwarcia stanu naszego obiektu na fabrykę. Można to zarządzać, jeśli nasza warstwa domeny znajduje się w osobnym zestawie, odsłaniając wewnętrznego konstruktora używanego przez fabrykę, ale staje się to problemem, jeśli istnieje wiele wzorców tworzenia. A jeśli cała fabryka zajmuje się wezwaniem właściwego konstruktora, to po co mieć fabrykę?

Metody fabryczne w klasie eliminują problem z otwarciem stanu wewnętrznego obiektu, ale ponieważ są one statyczne, nie jesteśmy w stanie przełamać zależności poprzez wstrzyknięcie interfejsu fabrycznego, tak jak możemy to zrobić przy pomocy osobnej klasy fabrycznej.

Trwałość . Można argumentować, że jeśli nasz obiekt domeny zamierza ujawnić CanEdit podczas delegowania odpowiedzialności za wykonanie kontroli autoryzacji na inną stronę (IAuthorizationService), dlaczego nie zastosować metody Save na naszym obiekcie domeny, która robi to samo? Umożliwiłoby to nam ocenę stanu wewnętrznego obiektu w celu ustalenia, czy operację można wykonać bez przerywania enkapsulacji. Oczywiście wymaga to, abyśmy wstrzyknęli instancję repozytorium do naszego obiektu domeny, który trochę pachnie, więc czy zamiast tego wywołujemy zdarzenie domeny i pozwalamy programowi obsługiwać wykonanie operacji utrwalania?

Widzisz, gdzie idę z tym?

Rockford Lhotka ma świetną dyskusję na temat powodów, dla których zdecydował się pójść drogą Class-in-Charge dla swojego frameworka CSLA, a ja mam trochę historii z tym frameworkiem i mogę zobaczyć jego pomysł na obiekty biznesowe równoległe do obiektów domeny na wiele sposobów. Ale starając się bardziej przyłączyć do dobrych ideałów DDD, zastanawiam się, kiedy współpraca staje się zbyt duża.

Jeśli skończę z usługą IAuthorizationService, IValidator, IFactory i IRepository dla mojego zagregowanego katalogu głównego, co pozostanie? Czy posiadanie metody publikowania, która zmienia stan obiektu z wersji Roboczej na Opublikowaną, wystarcza, aby uznać klasę za obiekt domeny nieanemicznej?

Twoje myśli?

SonOfPirate
źródło
Świetne pytanie. Nie mam dla ciebie odpowiedzi, ponieważ prawie zawsze skończę całkowicie anemicznie z tego samego powodu - z używania / konsumpcji / udostępniania usług z / do wielu różnych kontekstów lub różnych aplikacji.
hromanko
Świetne pytanie, chciałbym zobaczyć unclebob, martinfowler, ericevans i in. Teraz muszę odejść i długo się zastanowić
Martijn Verburg
Cały czas ewoluuję w kierunku modelu anemicznego; więc walczę z tą samą rzeczą. Świetne pytanie!
L-Four
Takie było również moje doświadczenie z DDD. Robimy to tam, gdzie pracuję i zawsze kończymy na anemii. Wcześniej (i nadal faktycznie) używam Csli. Nasz architekt nie lubi, że jesteśmy anemiczni, ale nie był w stanie udzielić mi dobrej odpowiedzi na temat tego, co powinien zrobić obiekt, jeśli wszystkie rzeczy, które wskazałeś, nie mogą być wykonane w obrębie obiektu. W końcu próba bycia purystą DDD wydaje się tworzyć więcej pracy niż jest warta. Osobiście uważam, że Csla i DDD się dogadują (wydają się one identyczne w zasadzie), jeśli jesteś gotów porzucić dogmat DDD.
Andy,
Oto przykład niektórych technik stosowanych podczas modelowania domeny z perspektywy behawioralnej (nie koncentrującej się na danych): medium.com/@wrong.about/…
Zapadlo,

Odpowiedzi:

66

Większość zamieszania wydaje się dotyczyć funkcjonalności, która w ogóle nie powinna istnieć w modelu domeny:

  • Trwałość nigdy nie powinna być w modelu domeny. Nigdy przenigdy. Właśnie dlatego polegasz na typach abstrakcyjnych, takich jak IRepositorygdyby część modelu kiedykolwiek musiała zrobić coś takiego, jak odzyskanie innej części modelu i użycie wstrzykiwania zależności lub innej podobnej techniki w celu uporządkowania implementacji. Więc skreśl to z płyty.

  • Autoryzacja zasadniczo nie jest częścią modelu domeny, chyba że faktycznie jest częścią domeny, np. Jeśli piszesz oprogramowanie zabezpieczające. Mechanicy, którzy mogą wykonywać to, co w aplikacji, są zwykle obsługiwani na „krawędzi” warstwy biznesowej / domeny, części publiczne, z którymi interfejs użytkownika i elementy integracji mogą rozmawiać - kontroler w MVC, usługi lub sam system przesyłania wiadomości w SOA ... dostajesz obraz.

  • Fabryki (i zakładam, że masz tu na myśli abstrakcyjne fabryki) nie są wcale takie złe w modelu domenowym, ale prawie zawsze są niepotrzebne. Zwykle masz fabrykę tylko wtedy, gdy wewnętrzna mechanika tworzenia obiektów może się zmienić. Ale masz tylko jedną implementację modelu domeny, co oznacza, że ​​zawsze będzie tylko jeden rodzaj fabryki, która zawsze wywołuje te same konstruktory i inny kod inicjujący.

    Możesz mieć „wygodne” fabryki, jeśli chcesz - klasy, które zawierają typowe kombinacje parametrów konstruktora i tak dalej - ale szczerze mówiąc, ogólnie mówiąc, jeśli masz wiele fabryk siedzących w modelu domeny, po prostu marnujesz linie kodu.

Więc kiedy przejdziesz wszystkie te, pozostawia to tylko weryfikację. To jedyna trudna sprawa.

Walidacja jest częścią twojego modelu domeny, ale jest także częścią każdego innego komponentu aplikacji. Twój interfejs użytkownika i baza danych będą miały własne, podobne, ale różne reguły sprawdzania poprawności, oparte na podobnym, ale innym modelu koncepcyjnym. Nie jest tak naprawdę określone, czy obiekty muszą mieć Validatemetodę, ale nawet jeśli tak, zwykle delegują ją do klasy walidatora (nie interfejsu - sprawdzanie poprawności nie jest abstrakcyjne w modelu domeny, jest fundamentalne).

Należy pamiętać, że walidator nadal jest technicznie częścią modelu; nie musi być dołączony do zagregowanego katalogu głównego, ponieważ nie zawiera żadnych danych ani stanów. Modele domenowe są rzeczami konceptualnymi, zwykle fizycznie tłumaczącymi na zespół lub kolekcję zespołów. Nie stresuj się problemem „anemicznym”, jeśli kod delegacji znajduje się w bardzo bliskiej odległości od modelu obiektowego; to wciąż się liczy.

Wszystko to sprowadza się do tego, że jeśli zamierzasz robić DDD, musisz zrozumieć, czym jest domena . Jeśli nadal mówisz o uporczywości i autoryzacji, jesteś na niewłaściwym tropie. Domena reprezentuje stan działania systemu - fizyczne i koncepcyjne obiekty i atrybuty. Wszystko, co nie jest bezpośrednio związane z samymi obiektami i relacjami, nie należy do modelu domeny, kropka.

Zasadniczo, rozważając, czy coś należy do modelu domeny, zadaj sobie następujące pytanie:

„Czy ta funkcjonalność może się kiedykolwiek zmienić z przyczyn czysto technicznych?” Innymi słowy, czy nie wynika to z jakiejkolwiek zauważalnej zmiany w świecie biznesu lub domeny?

Jeśli odpowiedź brzmi „tak”, to nie należy do modelu domeny. To nie jest część domeny.

Istnieje bardzo duża szansa, że ​​pewnego dnia zmienisz infrastrukturę uporczywości i autoryzacji. Dlatego nie są częścią domeny, są częścią aplikacji. Dotyczy to również algorytmów, takich jak sortowanie i wyszukiwanie; nie powinieneś wchodzić i implementować kodu binarnego wyszukiwania w swoim modelu domeny, ponieważ twoja domena zajmuje się jedynie abstrakcyjną koncepcją wyszukiwania, a nie jego działaniem.

Jeśli po usunięciu wszystkich rzeczy, które nie mają znaczenia, okaże się, że model domeny jest naprawdę anemiczny , to powinno to służyć jako całkiem dobra wskazówka, że ​​DDD jest po prostu złym paradygmatem dla twojego projektu.

Niektóre domeny naprawdę anemiczne. Aplikacje zakładek społecznościowych nie mają tak naprawdę „domeny”, o której można mówić; wszystkie twoje obiekty są w zasadzie tylko danymi bez żadnej funkcjonalności. Z drugiej strony system Sales and CRM ma dość ciężką domenę; kiedy ładujesz Ratejednostkę, istnieje uzasadnione oczekiwanie, że możesz faktycznie robić rzeczy z tą stawką, na przykład zastosować ją do ilości zamówienia i sprawić, by obliczyła rabaty ilościowe i kody promocyjne i wszystkie te fajne rzeczy.

Obiektów domeny, które po prostu przechowywania danych zwykle nie znaczy, że masz anemiczny model domeny, ale to nie musi oznaczać, że masz stworzył zły projekt - może to po prostu oznaczać, że sama domena jest anemiczne i które powinny być za pomocą inna metodologia.

Aaronaught
źródło
2
Ponadto, @SonOfPirate, nie jest całkiem prawdopodobne, że będziesz chciał kiedyś zmienić cały model bezpieczeństwa; bezpieczeństwo oparte na rolach jest często nieaktualne na korzyść bezpieczeństwa opartego na roszczeniach lub prawach, a może nawet chcesz bezpieczeństwa na poziomie pola. Wyobraź sobie próbę przerobienia całego modelu domeny, jeśli tak się stanie.
Aaronaught 28.04.11
1
@ SonOfPirate: Wygląda na to, że nadal trochę utknąłeś w starym modelu „warstwy biznesowej”, w której „warstwa środkowa” była w zasadzie cienką okleiną na warstwie danych, wdrażając różne reguły biznesowe, a także reguły bezpieczeństwa . To nie jest warstwa domeny. Domena jest tym , od czego wszystko zależy, reprezentuje rzeczywiste obiekty i relacje, którymi system ma zarządzać.
Aaronaught
1
@ LaurentBourgault-Roy: Przepraszam, nie wierzę ci. Każda firma może tak powiedzieć o każdej aplikacji; w końcu zmiana bazy danych jest trudna. To nie czyni go częścią twojej domeny, a logika biznesowa połączona z warstwą trwałości oznacza po prostu słabą abstrakcję. Model domeny koncentruje się na zachowaniu, a dokładnie tym nie jest upór . To nie jest temat, na który ludzie mogą wymyślić własne definicje; jest to dość wyraźnie zapisane w DDD. Często nie potrzebujesz modelu domeny dla CRUD lub aplikacji raportujących, ale nie powinieneś również twierdzić, że masz taki model, gdy go nie masz.
Aaronaught
1
Autoryzacja absolutnie należy do warstwy domeny. Kto decyduje, jakie uprawnienia istnieją? Biznes robi. Kto decyduje, kto może co robić? Biznes robi. Kilka tygodni temu mieliśmy prośbę o zmianę funkcji, aby zmienić autoryzację potrzebną do edycji konkretnego obiektu w naszym systemie. Jeśli szablon był oparty na szablonie głównym, potrzebne były wyższe uprawnienia do edycji (zastępowania wartości z wzorca) szablonu, niż normalnie byś potrzebował. Gdzie jest ta logika, jeśli nie w domenie?
Andy,
1
Innym rodzajem autoryzacji może być limit konta klienta. Zwykli pracownicy obsługi klienta mogą podnieść go do pewnego momentu, ale być może wyższe limity wymagają zatwierdzenia przez kierownictwo. To jest logika autoryzacji.
Andy,
6

Upoważnienie. Czy obiekt domeny powinien być odpowiedzialny za utrzymanie swoich reguł kontroli dostępu

Nie. Autoryzacja to problem sam w sobie. Polecenia, które nie byłyby ważne z powodu braku uprawnień, powinny zostać odrzucone przed domeną tak wcześnie, jak to możliwe - co oznacza, że ​​często będziemy nawet chcieć sprawdzić autoryzację potencjalnego polecenia w celu zbudowania interfejsu użytkownika (aby nie nawet pokaż użytkownikowi opcję edycji).

Udostępnianie strategii autoryzacji między warstwami (w interfejsie użytkownika i dalej w usłudze lub module obsługi poleceń) jest łatwiejsze, gdy autoryzacja jest złożona oddzielnie od modelu domeny.

Jedną z trudnych części, które można napotkać, jest autoryzacja kontekstowa, w której polecenie może, ale nie musi, być dozwolone nie tylko na podstawie ról użytkownika, ale także danych / reguł biznesowych.

Uprawomocnienie. Ta sama dyskusja jak powyżej dotyczy walidacji.

Powiedziałbym też nie, nie w tej dziedzinie (głównie). Sprawdzanie poprawności odbywa się w różnych kontekstach, a reguły sprawdzania poprawności często różnią się w zależności od kontekstu. Rzadko kiedy istnieje proste, absolutne poczucie ważności lub nieważności, gdy rozważa się dane zawarte w agregacji.

Podobnie jak w przypadku autoryzacji, wykorzystujemy logikę sprawdzania poprawności na różnych warstwach - w interfejsie użytkownika, w usłudze lub module obsługi poleceń itp. Ponownie łatwiej jest zastosować DRY z funkcją sprawdzania poprawności, jeśli jest to osobny komponent. Z praktycznego punktu widzenia sprawdzanie poprawności (szczególnie przy użyciu frameworków) wymaga ujawnienia danych, które w innym przypadku powinny zostać obudowane, i często wymaga dołączenia niestandardowych atrybutów do pól i właściwości. Wolę, aby były na innych klasach niż moje modele domen.

Wolę powielać niektóre właściwości w kilku podobnych klasach niż próbować wymusić wymagania dotyczące struktury sprawdzania poprawności w moich jednostkach. To nieuchronnie kończy bałagan klas jednostek.

Tworzenie obiektów. Klasa fabryczna a metody fabryczne kontra „nowe” wystąpienie.

Używam jednej warstwy pośredniej. W moich najnowszych projektach jest to polecenie + moduł obsługi do tworzenia czegoś, tj CreateNewAccountCommand. Alternatywą może być zawsze użycie fabryki (chociaż może to być niezręczne, jeśli reszta operacji encji jest narażona na działanie klasy usług innej niż klasa fabryki).

Generalnie jednak staram się być bardziej elastyczny, wybierając opcje projektowania obiektów. newjest łatwe i znane, ale nie zawsze wystarczające. Wydaje mi się, że ważne jest zastosowanie tutaj osądu i umożliwienie różnym częściom systemu korzystania z różnych strategii.

Trwałość. ... dlaczego nie zastosować metody Save na naszym obiekcie domeny

To rzadko dobry pomysł; Myślę, że jest wiele wspólnych doświadczeń, które to potwierdzają.

Jeśli skończę z usługą IAuthorizationService, IValidator, IFactory i IRepository dla mojego zagregowanego katalogu głównego, co pozostanie? Czy posiadanie metody publikowania, która zmienia stan obiektu z wersji roboczej na opublikowaną, wystarcza, aby uznać klasę za obiekt domeny nieanemicznej?

Być może model domeny nie jest właściwym wyborem dla tej części twojej aplikacji.

Quentin-Starin
źródło
2
„Jedną z trudnych części, które można napotkać, jest autoryzacja kontekstowa, w której polecenie może, ale nie musi, być dozwolone nie tylko na podstawie ról użytkowników, ale także danych / reguł biznesowych”. - A jak do tego podchodzisz? Więcej razy, przynajmniej dla mnie, nasze zasady autoryzacji są połączeniem roli i aktualnego stanu.
SonOfPirate
@ SonOfPirate: procedury obsługi zdarzeń, które nasłuchują zdarzeń domeny i aktualizują tabele, które są bardzo specyficzne dla potrzeb zapytań sprawdzających autoryzację. Logika, która patrzy na stan i określa, czy dana rola lub osoba jest autoryzowana, czy też nie żyje w module obsługi zdarzeń (więc tabele są prawie zawsze prostym tak / nie, dzięki czemu sprawdzanie uwierzytelnienia jest prostym wyszukiwaniem). Ponadto, gdy tylko jakakolwiek logika zostanie użyta w więcej niż jednym miejscu, zostanie ona refaktoryzowana z modułu obsługi do usługi wspólnej.
quentin-starin
1
Ogólnie rzecz biorąc, w ciągu ostatnich kilku lat coraz bardziej oddalałem się od próby skonsolidowania wszystkiego w domenie lub obiekcie biznesowym. Z mojego doświadczenia wynika, że ​​zwiększenie szczegółowości i zmniejszenie powiązań to długoterminowe zwycięstwo. Chociaż z jednej perspektywy metoda ta umieszcza logikę biznesową poza domeną (do pewnego stopnia), obsługuje również zwinne modyfikacje później. Chodzi o zachowanie równowagi.
quentin-starin
4
Odwołując się do samej odpowiedzi tutaj: Uważam, że wzorzec stanu jest bardzo przydatny w przypadku sprawdzania poprawności zależnych zarówno od uprawnień, jak i reguł biznesowych. Utwórz stan abstrakcyjny, który zostanie wstrzyknięty do modelu domeny i ujawni metody, które przyjmują obiekt domeny jako parametr i sprawdzają działania specyficzne dla domeny. W ten sposób, jeśli zmieniają się twoje reguły uprawnień (jak to prawie zawsze robią), nigdy nie musisz bawić się z modelem, aby go dostosować, ponieważ implementacje stanu znajdują się w twoim komponencie bezpieczeństwa.
Aaronaught 27.04.2011
1
Pozostając na temat autoryzacji, pozwól mi rzucić namacalny przykład na stół, aby zobaczyć, jak sobie poradzicie. Mam operację publikowania na moim obiekcie domeny, która wymaga, aby użytkownik był w roli wydawcy ORAZ że obiekt jest w określonym stanie. Chcę ukryć lub wyłączyć przycisk „Publikuj” w interfejsie użytkownika. Jak byś to zrobił?
SonOfPirate
4

OK, proszę. Opróżnię to, mówiąc:

  • Przedwczesna optymalizacja (w tym projektowanie) często może powodować problemy.

  • IANMF (nie jestem Martin Fowler);)

  • Brudną małą tajemnicą jest to, że w przypadku małych projektów (nawet prawdopodobnie średnich), ważna będzie spójność twojego podejścia.

Upoważnienie

Dla mnie Uwierzytelnianie i autoryzacja są zawsze kwestią przekrojową. W moim szczęśliwym małym świecie Java jest to delegowane do Spring Security lub frameworka Apache Shiro.

Sprawdzanie poprawności Dla mnie sprawdzanie poprawności jest częścią obiektu, ponieważ uważam, że jest to określenie, czym jest obiekt.

np. Obiekt samochodowy ma 4 koła (OK, są pewne dziwne wyjątki, ale na razie zignorujmy dziwny samochód 3-kołowy). Samochód po prostu nie jest ważny, chyba że ma 4 (w moim świecie), więc walidacja jest częścią definicji samochodu. To nie znaczy, że nie możesz mieć klas sprawdzania poprawności pomocnika.

W moim szczęśliwym świecie Java używam struktur sprawdzania poprawności Bean i używam prostych adnotacji na większości moich pól Bean. Łatwo jest wtedy zweryfikować obiekt bez względu na to, w jakiej warstwie jesteś.

Tworzenie obiektów

Ostrożnie patrzę na klasy fabryczne. Zbyt często widuję xyxFactoryFactoryklasę;)

Zwykle tworzę newobiekt w razie potrzeby, dopóki nie natknę się na przypadek, w którym uzasadnione jest wstrzykiwanie zależności (a ponieważ staram się stosować podejście TDD, pojawia się to częściej niż nie).

W moim szczęśliwym świecie Java jest to coraz więcej Guice, ale Wiosna jest tu nadal Królem.

Trwałość

Tak więc ta debata toczy się w kółko i na rondach, a ja zawsze o tym myślę.

Niektórzy twierdzą, że jeśli spojrzysz na obiekt w „czysty” sposób, wytrwałość nie jest podstawową właściwością, to jedynie kwestia zewnętrzna.

Inni uważają, że twoje obiekty domeny domyślnie implementują interfejs „trwały” (tak, wiem, że się tutaj rozciągam). Dlatego dobrze jest mieć różne save, deleteitp metod na nich. Jest to postrzegane jako podejście pragmatyczne i wiele technologii ORM (JPA w moim szczęśliwym świecie Java) radzi sobie z obiektami w ten sposób.

Z przekrojowego zagadnienia bezpieczeństwa upewniam się, że uprawnienia do edycji / usuwania / dodawania / cokolwiek są poprawnie ustawione w usłudze, która wywołuje metodę save / update / delete na obiekcie. Jeśli naprawdę jestem paranoikiem, mogę nawet ustawić uprawnienia do samego obiektu domeny.

HTH!

Martijn Verburg
źródło
2

Jimmy Nilsson porusza ten temat w swojej książce na temat DDD. Zaczął od modelu anemicznego, poszedł do modeli nieanemicznych w późniejszym projekcie i ostatecznie zdecydował się na modele anemiczne. Rozumował, że modele anemiczne mogą być ponownie wykorzystane w wielu usługach o różnej logice biznesowej.

Kompromisem jest brak zdolności odkrywania. Metody, którymi możesz posługiwać się w modelach anemicznych, są rozpowszechnione w zestawie usług zlokalizowanych gdzie indziej.

Todd Smith
źródło
Brzmi jak szczególny wymóg - ponowne wykorzystanie struktury danych („danych” stresu) - prowadzi do tego, że wspólna część została zredukowana do zwykłych DTO.
Victor Sergienko
Modele anemiczne umożliwiają lepsze ponowne wykorzystanie? Brzmi bardziej jak DTO, a ja osobiście nie obchodzi mnie ponowne wykorzystywanie definicji właściwości. Wolałbym ponownie wykorzystywać zachowania.
Andy,
@Andy - zgodziłbym się jednak, jeśli twoje zachowania są w ramach usług domenowych i działają one na obiektach anemicznych (w porządku DTO, jeśli chcesz), to czy to nie zwiększa ponownego wykorzystania tych zachowań? Po prostu gra adwokata diabła.
jpierson
@ jpierson Przekonałem się jednak, że zachowania są zazwyczaj specyficzne dla konkretnego przypadku użycia. Jeśli nastąpi ponowne użycie, należałoby to do innej klasy, ale konsument nie użyłby tych klas, użyłby tych specyficznych dla przypadku użycia. Więc każde ponowne użycie jest „za kulisami”, że tak powiem. Ponadto próba ponownego użycia modeli zwykle utrudnia korzystanie z modeli przez konsumenta, więc ostatecznie tworzysz modele przeglądania / edycji w warstwie interfejsu użytkownika. Często zdarza się, że naruszasz DRY, aby zapewnić użytkownikom bogatsze wrażenia (na przykład DataAnnotations edycji modeli).
Andy,
1
Wolę moduły domenowe zbudowane dla przypadku użycia, ponownie użyte tam, gdzie ma to sens (to znaczy, ponowne użycie może być wykonane bez znacznej lub w ogóle zmiany zachowania). Zamiast anemicznego modelu domeny, klasy usługi i modelu edycji, masz jeden inteligentny, edytowalny model domeny. Znalazłem, że jest o wiele łatwiejszy w użyciu i utrzymaniu.
Andy,
2

To pytanie zostało zadane dawno temu, ale jest oznaczone tagiem Domain Driven Design. Myślę, że samo pytanie zawiera fundamentalne niezrozumienie całej praktyki, a odpowiedzi, w tym odpowiedź zaakceptowana, utrwalają fundamentalne nieporozumienie.

W architekturze DDD nie ma „modelu domeny”.

Weźmy za przykład Autoryzację. Pozwól, że poproszę o zastanowienie się nad pytaniem: wyobraź sobie, że dwóch różnych użytkowników uwierzytelnia się w twoim systemie. Jeden użytkownik ma uprawnienia do zmiany określonego Podmiotu, a drugi nie. Dlaczego nie?

Nienawidzę prostych i wymyślonych przykładów, ponieważ często mylą bardziej niż oświecają. Ale udawajmy, że mamy dwie różne domeny. Pierwszy to platforma CMS dla agencji marketingowej. Ta agencja ma wielu klientów, którzy mają treści online, którymi muszą zarządzać autorzy tekstów i graficy. Treść obejmuje posty na blogu oraz strony docelowe dla różnych klientów.

Drugą domeną jest zarządzanie zapasami w firmie obuwniczej. System zarządza zapasami od momentu ich dostarczenia od producenta we Francji, do centrów dystrybucyjnych w kontynentalnych Stanach Zjednoczonych, do sklepów detalicznych na lokalnych rynkach, a wreszcie do klienta, który kupuje obuwie w sklepie.

Jeśli uważasz, że zasady autoryzacji są takie same dla obu firm, to tak, byłby to dobry kandydat na usługę spoza domeny. Wątpię jednak, aby zasady autoryzacji były takie same. Nawet koncepcje użytkowników byłyby inne. Z pewnością język byłby inny. Agencja marketingowa prawdopodobnie pełni role autorów postów i właścicieli aktywów, podczas gdy firma obuwnicza prawdopodobnie pełni funkcje takie jak urzędnik wysyłkowy lub kierownik magazynu lub kierownik sklepu.

Pojęcia te prawdopodobnie wiążą się z wszelkiego rodzaju regułami uprawnień, które należy modelować w domenie. Ale to nie znaczy, że wszystkie są częścią tego samego modelu, nawet w tej samej aplikacji. Ponieważ pamiętaj, że istnieją różne powiązane konteksty.

Być może więc można uznać, że nieanemiczny model domeny w kontekście autoryzacji różni się od kontekstu kierowania wysyłek obuwia do sklepów z niskim stanem magazynowym lub kierowania odwiedzających witrynę na odpowiednią stronę docelową w zależności od klikniętej reklamy.

Jeśli znasz anemiczne modele domen, być może po prostu musisz poświęcić więcej czasu na mapowanie kontekstu, zanim zaczniesz pisać kod.

RibaldEddie
źródło