Model domeny anemicznej: wady / zalety


Odpowiedzi:


39

Profesjonaliści:

  • Możesz twierdzić, że jest to model domeny i chwalić się znajomym programisty i umieścić go w swoim CV.
  • Generowanie z tabel bazy danych jest łatwe.
  • Zaskakująco dobrze odwzorowuje się na obiektach transferu danych.

Wady:

  • Twoja logika domeny istnieje gdzie indziej, prawdopodobnie w klasie pełnej metod klasowych (statycznych). Albo twój kod GUI. Lub w wielu miejscach, wszystkie z sprzeczną logiką.
  • Jest to anty-wzorzec, więc inni programiści zapytają, czy rozumiesz koncepcje projektowania obiektowego.

7
+1 Dla niektórych bardzo ważna jest kwestia generowania kodu z tabel bazy danych. Jeśli jesteś w trybie szybkiego prototypowania, automatyczne generowanie kodu jest niezwykle pomocne. Nie udajemy, że jest to właściwy projekt OO, a układanie rzeczy w niechlujny sposób powoduje „dług techniczny”. Niemniej jednak w wielu projektach czas wprowadzenia produktu na rynek ma wyższy priorytet.
Bill Karwin

62
Nie. To, czy model anemiczny jest anty-wzorcem, jest kwestią opinii. Fowler (którego prace szanuję i zazwyczaj śledzę) mówi, że tak. Nie zgadzam się (nie to, że moje słowo ma jakąkolwiek wagę), a wielu w okopach OO również się z tym nie zgadza. Modelowanie Pure OO nie jest powszechnie stosowane w każdym przypadku, o czym cała branża wie z doświadczenia. Co więcej, model anemiczny może nadal spełniać wytyczne dotyczące modelowania OO. Zatem widzenie konkretnych przypadków, w których się aplikuje, nie stawia pod znakiem zapytania zrozumienia projektu obiektu obiektowego.
luis.espinal

12
To, czy jakikolwiek wzór jest anty-wzorcem, jest kwestią opinii. Solidny model domeny to dobry projekt OO, a anemiczny model domeny to zły projekt OO. Dlatego w kontekście OO jest to anty-wzorzec. Nie oznacza to, że nie jest używany lub jest niewłaściwy we wszystkich przypadkach, ale z własnego doświadczenia uważam, że jest gorszy niż uzależnienie od singletona.
Terry Wilcox

7
Czuję, że istnieje trend w kierunku programowania funkcjonalnego, a model domeny ma zwykle wiele skutków ubocznych. Mam wrażenie, że anemiczny model domeny powraca, ponieważ pozwala na bardziej funkcjonalny styl programowania, w którym logika biznesowa oczekuje i zwraca przetworzone dane. Twoja warstwa usług nadzoruje przepływ tego wszystkiego, wiedząc, które dane są wymagane do przetworzenia za pomocą jakiej metody logiki biznesowej.
Didier A.

2
@TerryWilcox No cóż, nie jestem ekspertem w dziedzinie funkcjonalności, ale programowanie funkcjonalne też ma struktury danych. Model domeny anemicznej wykorzystuje obiekt tak samo jak kontenery danych, bardziej przypominają one struktury. Chodzi mi o to, że dzięki ADM możesz w pewnym sensie przejść w kierunku bardziej funkcjonalnego sposobu, w którym masz niezmienne dane, które z czasem są przekształcane w coraz nowsze stany. Widzę, że robi się to na przykład w Scali, próbując wykorzystać trochę OOP i zastosować do tego trochę PR. Trochę tak, jak wyjaśniają to tutaj: slideshare.net/debasishg/qconny-12
Didier

131

Skoro „Anemic Domain Model” jest anty-wzorcem, dlaczego jest tak wiele systemów, które to implementują?

Myślę, że jest kilka powodów

1. Złożoność systemu

W prostym systemie (czyli prawie wszystkie przykłady i przykładowy kod, które można znaleźć w Internecie), jeśli chcę zaimplementować:

Dodawanie produktu do zamówienia

Umieściłem tę funkcję w Zakonie

public void Order.AddOrderLine(Product product)
{
    OrderLines.Add(new OrderLine(product));
}

Ładny i super obiektowy.

Teraz powiedzmy, że muszę się upewnić, że muszę sprawdzić, czy produkt istnieje w magazynie i zgłosić wyjątek, jeśli tak nie jest.

Naprawdę nie mogę już złożyć zamówienia na zamówienie, ponieważ nie chcę, aby moje zamówienie było zależne od zapasów, więc teraz musi przejść do usługi

public void OrderService.AddOrderLine(Order order, Product product)
{
    if (!InventoryService.Has(product)
       throw new AddProductException

    order.AddOrderLine(product);
}

Mógłbym również przekazać IInventoryService do Order.AddOrderLine, co jest inną opcją, ale nadal uzależnia zamówienie od InventoryService.

W Order.AddOrderLine nadal jest pewna funkcjonalność, ale zwykle jest ona ograniczona do zakresu zamówienia, podczas gdy z mojego doświadczenia wynika o wiele więcej logiki biznesowej poza zakresem zamówienia.

Kiedy system jest czymś więcej niż tylko podstawowym CRUDem, większość swojej logiki skończy się w OrderService, a bardzo mało w Order.

2. Widok programisty na OOP

W Internecie toczy się wiele gorących dyskusji na temat tego, która logika powinna dotyczyć podmiotów.

Coś jak

Zamów, oszczędzaj

Czy Zakon powinien wiedzieć, jak się ratować, czy nie? Powiedzmy, że mamy do tego repozytoria.

Czy teraz zamówienie może dodawać linie zamówienia? Jeśli spróbuję to zrozumieć używając prostego angielskiego, to też nie ma sensu. Użytkownik dodaje produkt do zamówienia, więc powinniśmy zrobić User.AddOrderLineToOrder ()? To wydaje się przesada.

A co z OrderService.AddOrderLine (). Teraz to ma sens!

Moje rozumienie OOP jest takie, że w celu hermetyzacji umieszczasz funkcje w klasach, w których funkcja będzie musiała uzyskać dostęp do stanu wewnętrznego klasy. Jeśli chcę uzyskać dostęp do kolekcji Order.OrderLines, umieszczam Order.AddOrderLine () w polu Order. W ten sposób stan wewnętrzny klasy nie zostanie ujawniony.

3. Kontenery IoC

Systemy korzystające z kontenerów IoC są zwykle w pełni anemiczne.

Dzieje się tak, ponieważ możesz testować swoje usługi / repozytoria, które mają interfejsy, ale nie możesz testować obiektów domeny (łatwo), chyba że umieścisz interfejsy na wszystkich z nich.

Ponieważ "IoC" jest obecnie chwalone jako rozwiązanie wszystkich twoich problemów programistycznych, wiele osób ślepo je śledzi i w ten sposób uzyskuje Anemic Domain Modele.

4. OOP jest trudne, proceduralne łatwe

Mam trochę " Klątwy Wiedzy ", ale odkryłem, że dla nowszych programistów posiadanie DTO i usług jest o wiele łatwiejsze niż Rich Domain.

Być może dzieje się tak dlatego, że w przypadku Rich Domain trudniej jest określić, na których klasach należy umieścić logikę. Kiedy tworzyć nowe zajęcia? Których wzorców użyć? itp..

W przypadku usług bezstanowych wystarczy wcisnąć go w usługę o najbliższej nazwie.


Myślę, że to zależałoby od tego, jak skomplikowane byłoby to. 1. Jeśli to proste jak w 1-2 zależnościach - zostawiłbym to na klasie Order. 2. W przypadku umiarkowanej złożoności - stworzyłbym klasę OrderLines i użyłbym Order.OrderLines do obsługi komunikacji Order <-> OrderLines, a także powiązanych zależności. 3. Ale w przypadku dużej złożoności - użyłbym usługi Application Service OrderService, aby umożliwić większość zależności zewnętrznych, zachowując jednocześnie logikę o zakresie modułu Order w porządku.
Eric P,

13
Świetne podsumowanie - wszystkie te powody sprawiają, że nie jest to anty-wzór. Niewolnicze oddanie OO jest antywzorem. Teraz dodaj współbieżność bez projekcji i zobacz, jak wiążesz się w węzły dzięki OO w stylu Fowlera. Przyjrzyj się firmom stosującym współbieżność na dużą skalę (np. Google) i zobacz, ile robią OO.
DanH

Ładnie powiedziane. Używając Grails, nie jestem pewien, czy 3 ° prowadzi do anemii. Jeśli chodzi o 1 °, faktycznie kończysz przenoszenie logiki w warstwie usług w każdej nietrywialnej aplikacji. Ale nadal mam podejście skoncentrowane na domenie, używając Grails. Co sprawia, że ​​nie jest tak dobrze, ponieważ Twoja domena jest preferowanym miejscem dla logiki, ale w razie potrzeby przenosisz bity o jedną warstwę w górę.
youri

4
Nie widzę korelacji między IoC a anemią. Wydaje się, że to zupełnie niezwiązany problem. To, czy Twoje usługi / repozytoria, czy obiekty domeny implementują interfejsy, nie ma nic wspólnego z ich testowaniem. Zamiast tego testujesz usługi / repozytoria / obiekty domeny i oddzielasz je od ich zależności, które same implementują interfejsy. I czy robisz to dobrze, czy nie, nie ma żadnego związku z IoC, który widzę.

2
Rzecz w DDD, z którą walczę w Grok, to twój pierwszy punkt: „Kiedy system będzie czymś więcej niż tylko podstawowym CRUDem, większość logiki będzie w OrderService, a bardzo mało w Order”. Ma to dla mnie sens, ale czy celem DDD nie jest używanie w systemach, które są bardziej złożone?
Dan Ling

20

Po tym od bardzo dawna w mojej głowie pojawiła się myśl. Jestem przekonany, że termin „OOP” nabrał znaczenia, które nie jest do niego przeznaczone. Anagram oznacza „programowanie obiektowe”, jak wszyscy dobrze wiemy. Skupiamy się oczywiście na słowie „zorientowany”. To nie jest „OMP”, co oznacza „programowanie z mandatem obiektowym”. Zarówno ADM, jak i RDM są przykładami OOP. Wykorzystują obiekty, właściwości, interfejsy metod i tak dalej. Istnieje jednak różnica między ADM i RDM w tym, jak wybieramy hermetyzację. To są dwie różne rzeczy. Stwierdzenie, że ADM jest zły OOP, nie jest dokładnym stwierdzeniem. Może zamiast tego potrzebujemy innych terminów dla różnych poziomów hermetyzacji. Poza tym nigdy nie lubiłem terminu anty-wzór. Zwykle jest przypisywany czemuś przez członków przeciwnej grupy. Zarówno ADM, jak i RDM są prawidłowym wzorcem, mają po prostu różne cele i mają na celu rozwiązanie różnych potrzeb biznesowych. Ci z nas, którzy praktykują DDD, powinni przynajmniej to docenić i nie spaść na poziom innych, atakując tych, którzy zdecydują się wdrożyć ADM. Tylko moje myśli.


16

„Jest to anty-wzorzec, więc inni programiści będą pytać, czy rozumiesz koncepcje projektowania zorientowanego obiektowo”.

„Anemiczny model domeny jest anty-wzorcem. Anemiczne wzorce nie mają zalet”.

To, czy anemiczny model domeny jest anty-wzorcem, jest kwestią opinii. Martin Fowler twierdzi, że tak, wielu programistów, którzy znają OO na wylot, twierdzi, że tak nie jest. Podawanie opinii jako faktu rzadko jest pomocne.

A nawet gdyby był powszechnie akceptowany jako anty-wzór, są szanse, że nadal miałby pewne (choć stosunkowo niewielkie) korzyści.


2
... które są? Nie próbuję oszukiwać Ciebie ani nikogo, ale jestem naprawdę ciekawa profesjonalistów. Wady były wymieniane tysiące razy, ale wciąż szukam trwałych zalet ADM (poza frazesami polemicznymi).
struppi

6
... wygląda na to, że ktoś próbuje odgrywać diabelską adorację, robiąc z tego małe show. the chances are it would still have some (though relatively little) upside.Więc proszę, wymień niektóre! Przynajmniej jeden, zamiast stawiać hipotezę!
Sanki

2
Łatwiej jest wiedzieć, gdzie należy logika dla wszystkiego, co nie jest związane z jedną klasą (jakikolwiek prawdziwy biznes). Jak powiedziano w innych miejscach, „bogaty model domeny” kończy się logiką w wielu miejscach (warstwa usług, wiele klas zaangażowanych w grafy obiektów,…). Ponadto RDM nie pozwala na łatwy wgląd w pełną logikę biznesową, nie ułatwia unikania cykli itp. Głupie struktury danych bez logiki mają swoje miejsce w aplikacji obiektowej.
ymajoros

1
Uważam, że ten artykuł daje dobry argument, aby powiedzieć, że ADM nie jest anty-wzorcem blog.inf.ed.ac.uk/sapm/2014/02/04/ ...
syclee

1
Antypatterny zawsze stwarzają problemy i pomyślnie dostarczyliśmy kilka dość dużych aplikacji (2 lub 3 lata rozwoju 10 programistów pracujących> 300KLOC) z wysokiej jakości rozwiązaniami wykorzystującymi wzorzec i bez poczucia, że ​​coś jest z nim nie tak, więc nie może być tak źle, jeśli tak jest pozwala na stworzenie dobrego kodu podczas korzystania z niego.
Ignacio Soler Garcia

13

Wydaje mi się, że głównym zarzutem Fowlera jest to, że ADM nie są OO w następującym sensie. Jeśli projektuje się system „od zera” wokół pasywnych struktur danych, którymi manipulują inne fragmenty kodu, to z pewnością pachnie to bardziej projektowaniem proceduralnym niż obiektowym.

Sugeruję, że istnieją co najmniej dwie siły, które mogą wytworzyć taki projekt:

  1. Projektanci / programiści, którzy nadal myślą, że są proceduralnie wymagane do pracy w środowisku zorientowanym obiektowo (lub zakładają, że mogą ...) stworzyć nowy system, oraz

  2. Programiści pracujący nad nadaniem „twarzy” usługi w starszym systemie zaprojektowanym w sposób inny niż OO (niezależnie od języka).

Gdyby na przykład budować zestaw usług w celu udostępnienia funkcjonalności istniejącej aplikacji mainframe COBOL, można by zdefiniować usługi i interfejsy w oparciu o model koncepcyjny, który nie odzwierciedla wewnętrznych struktur danych COBOL. Jeśli jednak usługa mapuje nowy model do starszych danych, aby użyć istniejącej, ale ukrytej implementacji, nowy model może być bardzo „anemiczny” w sensie artykułu Fowlera - np. Zestaw definicji w stylu TransferObject i relacje bez prawdziwego zachowania.

Ten rodzaj kompromisu może być bardzo powszechny w przypadku granic, przy których idealistycznie czyste systemy obiektowe muszą wchodzić w interakcję z istniejącym środowiskiem innym niż obiekt obiektowy.


8

Model domeny anemicznej (ADM) może być dobrym wyborem, jeśli Twój zespół nie jest w stanie lub nie chce zbudować bogatego modelu domeny (RDM) i utrzymywać go w czasie. Zwycięstwo z RDM wymaga szczególnej uwagi na dominujące abstrakcje używane w systemie. Wyobraź sobie, że w dowolnej grupie deweloperów nie więcej niż połowa i być może tylko jedna dziesiąta jej członków jest kompetentna w zakresie abstrakcji. O ile ta kadra (być może tylko jeden deweloper) nie jest w stanie utrzymać wpływu na działania całej grupy, RDM ulegnie entropii.

A entropia RDM boli w określony sposób. Jego twórcy wyciągną trudne lekcje. Na początku będą mogli sprostać oczekiwaniom swoich interesariuszy, ponieważ nie będą mieli historii, której mogliby sprostać. Ale gdy ich system stanie się bardziej skomplikowany (nie złożony) , stanie się kruchy; programiści będą próbowali ponownie wykorzystać kod, ale mają tendencję do wywoływania nowych błędów lub cofania się w rozwoju (i tym samym przekraczają swoje szacunki).

W przeciwieństwie do tego programiści ADM będą stawiać sobie niższe oczekiwania, ponieważ nie będą oczekiwać ponownego wykorzystania tak dużej ilości kodu dla nowych funkcji. Z biegiem czasu będą mieć system z wieloma niespójnościami, ale prawdopodobnie nie zepsuje się nieoczekiwanie. Ich czas wprowadzenia na rynek będzie dłuższy niż w przypadku udanego RDM, ale ich interesariusze raczej nie dostrzegą takiej możliwości.


5

„Programiści pracujący nad nadaniem usługowej„ twarzy ”starszemu systemowi zaprojektowanemu w sposób inny niż OO (niezależnie od języka).”

Jeśli myślisz o wielu aplikacjach LOB, te starsze systemy często nie będą używać tego samego modelu domeny, co Ty. Anemic Domain Model rozwiązuje ten problem za pomocą logiki biznesowej w klasach usług. Możesz umieścić cały ten kod interfejsu wewnątrz swojego modelu (w tradycyjnym sensie OO) - ale zazwyczaj kończy się to utratą modułowości.


1
Bingo. To jest miejsce, w którym wiele osób zdaje się tęsknić za łodzią. ADM mają cel. Ich niewłaściwe użycie jest anty-wzorcem, ale oni sami nim nie są.
luis.espinal

4

Kiedy po raz pierwszy natknąłem się na artykuł Anemic Domain Model, pomyślałem: „O cholera, to właśnie robię. Wytrwałem i zastosowałem się do odniesień do książki Erica Evana, uważanej za dobry przykład, i pobrałem źródło. Okazuje się, że „niestosowanie anemicznego modelu domeny” nie oznacza „nieużywania klas usług, nieużywania mediatorów, nieużywania strategii” ani nawet „nakładania logiki na manipulowaną klasę”.

Przykłady DDD mają klasy usług, XyzUpdaters, singletony i IoC.

Jestem zdezorientowany tym, czym dokładnie jest model domeny anemicznej. Oczekuję, że „poznam to, kiedy to zobaczę”. Na razie jestem zadowolony z pozytywnego przykładu dobrego projektu.


1
Później kupiłem książkę Erica Evana i bardzo ją polecam. Zapewnia solidne przykłady przeciwieństw modeli dziedzin anemicznych.
jamie

4

Pracując z „dojrzałym” systemem z ADM i czuję, że mogę udzielić przynajmniej kilku anegdotycznych informacji zwrotnych na to pytanie.

1) Brak hermetyzacji

W systemie live z ADM istnieje możliwość zapisu np. 'Obj.x = 100; obj.save '', nawet jeśli narusza to logikę biznesową. Prowadzi to do szeregu błędów, które nie wystąpiłyby, gdyby niezmienniki były modelowane na obiekcie. Uważam, że to powaga i wszechobecność tych błędów jest najpoważniejszym negatywnym skutkiem dla ADM.

Uważam, że ważne jest, aby podkreślić, że w tym miejscu rozwiązanie funkcjonalne i rozwiązania proceduralne ADM znacznie się różnią, a wszelkie podobieństwa, które inni mogli wyciągnąć na powierzchnię podobieństw między ADM a rozwiązaniem funkcjonalnym, są przypadkowe.

2) Nadęcie kodu

Szacuję, że ilość kodu produkowanego w ADM jest 5-10 razy większa niż w przypadku rozwiązania OOP / RDM. Przyczyną tego jest być może 50% powtórzeń kodu, 30% to kod płyty głównej, a 20% to rozwiązywanie lub rozwiązywanie problemów wynikających z braku RDM.

3) Słabe zrozumienie problemów dziedzinowych

ADM i słabe zrozumienie problemów domeny idą w parze. Pojawiają się naiwne rozwiązania, słabo uwzględniane są wymagania ze względu na trudność w ich wsparciu przy pomocy istniejącego DM, a ADM staje się istotną barierą dla innowacji biznesowych, biorąc pod uwagę dłuższy czas rozwoju i brak elastyczności.

4) Trudność w utrzymaniu

Wymagany jest pewien poziom rygoru, aby zapewnić, że koncepcja domeny zostanie zmieniona we wszystkich miejscach, w których jest wyrażona, biorąc pod uwagę, że koncepcja nie może być tylko powtórną implementacją typu kopiuj i wklej. Często prowadzi to do tego, że te same błędy są badane i naprawiane przy wielu okazjach.

5) Zwiększona trudność przy wejściu na pokład

Myślę, że jedną z zalet RDM jest spójność koncepcji, które pozwalają na szybsze zrozumienie dziedziny. W przypadku ADM koncepcje mogą być fragmentaryczne i niejasne, przez co nowi deweloperzy mogą trudniej je zdobyć.

Kusiło mnie również, aby uwzględnić koszty wsparcia operacyjnego dla ADM, które są wyższe niż dla RDM, ale będzie to zależało od wielu czynników.

Jak zauważyli inni, spójrz na DDD (Greg Evans, Vince Vaughn i Scott Millett), aby poznać zalety RDM.


1
Czy Greg Evans jest tajemniczym dzieckiem Grega Younga i Erica Evansa? Nie wiedziałem też, że Vince Vaughn pisze książki DDD, ale może Vaughn Vernon też zaczął grać :)
knittl

Ojej, wygląda na to, że moja pamięć, kiedy pisałem powyższe, była nieco pomieszana. Dziękuję za zwrócenie uwagi :)
Mr Morphe

2

Jest to ten sam profesjonalista, co w przypadku większości anty-wzorców: pozwala na zajęcie wielu osób przez długi czas. Ponieważ menedżerowie zwykle zarabiają więcej, gdy zarządzają większą liczbą ludzi, istnieje silna zachęta, aby nie robić postępów.


7
W takim razie pozwolę sobie to przeformułować. ^^^ Czysto anegdotyczne dowody używane do wnioskowania o ogólnie brzmiącej propozycji.
luis.espinal

Kiedy znajdziemy wystarczająco dużo anegdotycznych dowodów, być może uda nam się wyprowadzić wzór. Ten wzorzec jest dobrze znany i odpowiednio opisany w literaturze dotyczącej zarządzania zmianą.
Stephan Eggermont

4
„Ten wzorzec jest dobrze znany i odpowiednio opisany w literaturze dotyczącej zarządzania zmianą”. - Proszę o cytaty. Co więcej, korelacja nie oznacza związku przyczynowego . To znaczy, tylko dlatego, że widzisz ludzi kręcących się kołami w biurokracji z powodu lokalnych anty-wzorców (w szczególności wzorców oprogramowania i modeli dziedzin anemicznych ), nie oznacza to, że późniejsze istnieje po to, aby usprawiedliwić to pierwsze, które jest co właśnie odtrąbiłeś. Hasła retoryczne są kiepską karykaturą w wyjaśnianiu złożonych zagadnień. Zatem znowu, korelacja nie oznacza związku przyczynowego.
luis.espinal

4
Może zechcesz przeczytać Quality Software Management Geralda M. Weinberga, zwłaszcza tom 4. I twierdzę tylko, że jest to możliwa przyczyna dalszego istnienia, a nie jego wystąpienia. Zasada Petera zapewnia odpowiednią alternatywę.
Stephan Eggermont

Dziękuję, przeczytam, gdy będę miał okazję (+1 za podanie cytatu). Czy ta książka przedstawia to jako dobrze znany anty-wzór? Poza tym, czy twierdzi / wykazuje nie tylko korelację, ale także związek przyczynowy ? Teraz twierdzisz, że jest to „możliwe” wyjaśnienie . Twój oryginalny tekst przedstawia to jako pewnik, z większą retoryką niż szczegółami (dlatego nazwałem to „czystą spekulacją”). Czy to był twój zamiar wtedy , albo po prostu wypadek redakcyjny, który wie, i mogę wywnioskować tylko od tego, co jest obecne w tekście w czasie lektury.
luis.espinal

2

Zgodnie z odpowiedzią Erica P, a także z tym, co napisali inni powyżej, wydaje się, że główną wadą ADM jest utrata OOD, w szczególności utrzymywanie logiki i danych koncepcji domeny razem, tak że szczegóły implementacji są ukryte podczas API może być bogate.

Eric zwraca uwagę, że często istnieją informacje spoza klasy domeny, które są niezbędne dla logiki działania na tej klasie, na przykład sprawdzanie zapasów przed dodaniem pozycji do zamówienia. Zastanawiam się jednak, czy odpowiedzią jest warstwa usług, która przechowuje tę nadrzędną logikę, czy też lepiej jest obsługiwana jako część projektu obiektu. Ktoś musi wiedzieć o obiekcie Inventory, obiekcie Product i obiekcie Order. Być może jest to po prostu obiekt OrderSystem, który ma element Inventory, listę zamówień i tak dalej. To nie będzie wyglądać inaczej niż usługa, ale myślę, że jest koncepcyjnie bardziej spójna.

Lub spójrz na to w ten sposób: Możesz mieć użytkownika z wewnętrznym saldem kredytowym i za każdym razem, gdy wywoływany jest User.addItemToOrder (item), pobiera on cenę przedmiotu i sprawdza kredyt przed jego dodaniem itd. To wydaje się rozsądne OO. projekt. Nie jestem pewien, co dokładnie stracono, zastępując to Service.addItemToUserOrder (użytkownik, przedmiot), ale nie jestem też pewien, co zyskałem. Wydaje mi się, że stratą byłaby dodatkowa warstwa kodu, a także bardziej skomplikowany styl pisania i wymuszona ignorancja leżącego u podstaw Modelu Domeny.


1

Należy zauważyć, że wraz ze wzrostem złożoności i ziarnistości zmienności systemów, hermetyzacja i konsolidacja punktów interfejsu zapewniana przez dobrze zaprojektowany model obiektowy przekazywania komunikatów sprawia, że ​​zmiana i utrzymanie krytycznego kodu bez powszechnej refaktoryzacji jest znacznie bezpieczniejsza.

Warstwy usług stworzone przez ADM, choć z pewnością łatwiejsze do wdrożenia (ponieważ wymagają stosunkowo niewielkiego myślenia i mają wiele zdecentralizowanych punktów interfejsu), prawdopodobnie spowodują problemy w przyszłości, gdy nadejdzie czas na modyfikację działającego i rozwijającego się systemu.

Dodam też, że nie wszystkie przypadki w ogóle wymagają modelu domeny (nie mówiąc już o modelu ADM). Czasami lepiej jest użyć bardziej proceduralnego / funkcjonalnego stylu zadania, który jest oparty na danych i nie zależy od logiki / reguł biznesowych całej aplikacji.

Jeśli próbujesz zdecydować o zaletach i wadach całej aplikacji, myślę, że ważne jest, aby najpierw zaprojektować, jak każda z nich może wyglądać dla danej aplikacji, ZANIM zaczniesz pisać pojedynczą linię kodu. Po CRC lub oprawieniu aplikacji w ramy w obu stylach, cofnij się o krok i zdecyduj, który z nich jest bardziej sensowny i lepiej pasuje do aplikacji.

Zastanów się również z wyprzedzeniem, który z nich będzie łatwiejszy w utrzymaniu ...


1

Daje lepszą przewidywalność. Menedżerowie tacy jak to, zwłaszcza jeśli projekt jest płatny czas i materiały. Każda zmiana oznacza dużo pracy, więc trudna praca może być ukryta za wieloma powtarzalnymi pracami. W dobrze zaprojektowanym systemie DRY przewidywalność jest bardzo zła, ponieważ ciągle robisz nowe rzeczy.


1

Kiedy po raz pierwszy przeczytałem książkę Erica Evansa o projektowaniu opartym na domenach, nie rozumiałem, że nie jest to tylko zbiór taktycznych wzorców projektowania dobrych klas modeli domen.

Po tym, jak dowiedziałem się więcej na ten temat i wykorzystałem również strategiczne wzorce, w końcu zacząłem rozumieć, że na początku chodzi o głębokie zrozumienie problemów biznesowych , które próbujesz rozwiązać.

Dopiero potem można zdecydować, które części systemu będą nadawać się do stosowania wzorców taktycznych, takich jak agregaty, encje , repozytoria itp. Wraz z tzw. Bogatymi modelami domenowymi (w przeciwieństwie do anemicznych ). Jednak aby skorzystać z tych wzorców, logika biznesowa musi być wystarczająco złożona dla tej części systemu.

A więc przy wdrażaniu rozwiązania danego problemu należy najpierw ustalić, czy do tego konkretnego problemu lepiej podejść, stosując podejście oparte na CRUD, czy też inwestując w bogaty model dziedzinowy wraz ze wspomnianymi wzorcami taktycznymi.

Jeśli CRUD ma więcej sensu, np. Jeśli nie ma złożonej logiki biznesowej, a większość logiki dotyczy transformacji, przesyłania i utrwalania danych implementujących model domeny, może to być niepotrzebna przesada. Nie oznacza to, że nie będzie dużo pracy, ale po prostu to nie reguły biznesowe powodują najwięcej wysiłku wdrożeniowego. Ale w tym przypadku nie ma czegoś takiego jak anemiczny model domeny , po prostu dlatego, że w ogóle nie ma modelu domeny . Będziesz raczej widzieć takie rzeczy jak DTO (Data Transfer Objects) lub DAO(Data Access Objects) i klasy usług, które będą operować na danych. Odpowiednie operacje są w dużym stopniu związane z przekształcaniem danych z jednej reprezentacji do drugiej i przenoszeniem danych z bardzo małą lub prawie żadną logiką biznesową.

Jeśli ustaliłeś, że istnieje wiele złożonej logiki biznesowej, która również będzie się zmieniać w czasie, to inwestowanie w model domeny jest - z mojego doświadczenia - dobrym pomysłem. Powodem jest to, że łatwiej jest przedstawić perspektywę biznesową za pomocą kodu i ułatwić zrozumienie odpowiednich operacji, które odzwierciedlają domenę biznesową i jej reguły. Nie oznacza to, że w każdym przypadku użycia muszą istnieć klasy modelu domeny. Na przykład, jeśli nie ma stanu do zmutowania i utrwalenia, mogą istnieć tylko usługi domenowe, które zawierają logikę domeny, są zaimplementowane bardziej jak czyste funkcje.

Ale jeśli istnieje również stan, który ma być zmutowany i trwały, który ma również cel i znaczenie w domenie biznesowej, stan i zachowanie, które zmienia ten stan, powinny być zawarte . Dzięki temu nikt nie może tak łatwo obejść reguł biznesowych, co prowadzi do nieprawidłowych stanów i poważnych niepowodzeń. Źródłem takich problemów są często tzw. Anemiczne modele dziedzinowe . Dzieje się tak często, gdy widzisz kod, w którym różne komponenty działają na tej samej "anemicznej" klasie modelu domeny, sprawdzając jakąś część swojego stanu i zmieniając jakąś część swojego stanu bez dbania o ogólne niezmienniki tej jednostki biznesowej lub ich znajomości. Nie jest konieczne nazywanie tego anty-wzorcem, ale ważne jest, aby to zrozumiećtracisz wiele korzyści z bogatego modeli domen w podejście oparte na DDD wraz z wymienionymi problemami. Podczas korzystania z modelu domeny, w którym zachowanie i jego dane są umieszczone w tej samej klasie, może być również wiele różnych operacji wywołujących „klientów” tej klasy, ale nie muszą się przejmować, że niezmienniki biznesowe jednostki biznesowej są przestrzegane klasa modelu domeny zawsze zajmie się tym i może również informować „klienta” o nieprawidłowych operacjach lub nawet rzucać wyjątki jako sieć bezpieczeństwa.

Więc dolnej linii , myślę, że ważne jest, aby nie mylić danych strukturze jak klas (takie jak DTOs lub DAOs) z niedokrwistością klas modelu domeny . W starannie i celowo wybranym podejściu opartym na CRUD nie ma korzyści z próby użycia modelu domeny, ponieważ istnieje zbyt mniej złożona logika biznesowa.

Przez anemiczny modelu domeny chciałbym odwołać się do kodu, z którego widzę, że tam jest dużo złożonych logicznych reguł biznesowych i gospodarczych, które są rozproszone w różnych składników, które powinny raczej być zbliżona do tych danych logika się zmienia.

Jest też inna lekcja, której nauczyłem się po drodze: jeśli spróbujesz użyć tego samego języka biznesowego (zwanego również językiem wszechobecnym ) w swoim kodzie, którego używają stekowcy w swoim codziennym życiu zawodowym, zdobędziesz już wiele korzyści związanych domeny biznesowej i poprawie czytelności kodu, które pomogą Ci tak bardzo bez względu na to, czy używasz podejścia opartego na CRUD, czy opartym na modelu domeny.


0

Aby rozszerzyć odpowiedź Michaela, pomyślałbym, że jest (dość) jasne, gdzie ten kod powinien się znaleźć: do dedykowanego mediatora, który obsługuje interakcję między Zakonem a Inwentarzem.

Z mojego punktu widzenia kluczową kwestią w tej domenie jest to, że MUSI ona utrzymywać proste zachowanie testowe isInThisState()metod itp. Z mojego doświadczenia wynika, że są one również rozproszone po łzach usług (sic :)) w większości firm i albo kopiowane, albo bez końca przepisywane. Wszystko to łamie standardowe zasady spójności.

Moim zdaniem podejście powinno polegać na dążeniu do DM, który zawiera tyle zachowań biznesowych, ile jest to praktyczne, a resztę należy umieścić w jasno wyznaczonych obszarach (tj. Nie w usługach)


W przypadku Mediatora różnica między nim a programowaniem proceduralnym i tak jest niewielka; po prostu grupujesz funkcje, które nie należą do żadnego z obiektów. Fakt, że grupujesz je w innym obiekcie, nie robi dużej różnicy.
Rob Grant

0

Mój zespół osobiście preferuje ADM. mamy zestaw obiektów biznesowych, które reprezentują określone części naszej domeny. Korzystamy z usług, aby zapisać te obiekty do bazy danych. Nasze obiekty biznesowe mają metody, jednak te metody manipulują tylko ich stanem wewnętrznym.

Korzyści dla nas wynikające z używania ADM zamiast RDM można zobaczyć w sposobie utrwalania obiektów w db. Programiści pracujący na naszych starszych systemach kodu mogą używać naszych obiektów biznesowych (z nowego systemu) i nadal używać ich bieżącej warstwy dostępu do danych, aby utrwalić te obiekty w bazie danych. Korzystanie z RDM zmusiłoby programistów naszego dotychczasowego systemu do wprowadzenia obiektów repozytorium do naszego modelu biznesowego ... co byłoby niezgodne z ich obecną warstwą dostępu do danych.


-15

Anemiczne modelu domeny jest anty-wzór. Anty-wzory nie mają zalet.


10
Nie zgadzam się. Większość Antipatterns ma narożne skrzynki, w których są one lepszym rozwiązaniem niż inne alternatywy.
Bill Karwin

19
Anty-wzory mają zalety. Dlatego ludzie ich używają, mimo że zazwyczaj są to złe pomysły.
Kristopher Johnson,

6
Papugowanie, że coś jest anty-wzorcem jako faktem, kiedy jest to tylko opinia (nawet jeśli jest to coś w rodzaju Fowlera), to nie jest poprawna forma odpowiedzi.
luis.espinal

@luis: Właśnie to miałem napisać, zanim zobaczyłem twój komentarz. Ponadto istnieją narzędzia, które służą celowi. Jeśli Fowler nie chce nazywać tego OO, to w porządku. Ale to nie oznacza automatycznie złego rozwiązania / architektury / itp.
JensG,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.